Flutter for Web
Flutter for Web
Flutter for Web
- Android/iOSに加えてFlutterの対応プラットフォームにWebが入っている
- Dartで書かれたソースコードをJavaScriptへと変換し動作させる
- 2020年4月時点では beta channel で使用可能(本番利用は非推奨)
使い方
仕組み
- DartからJavaScriptへの変換処理はDart自体で提供されている仕組みを利用
- DOM・Canvas・CSSを使い各ブラウザで動作する描画処理をFlutter側で提供している
Dart Web
- webdevを使いDartからJavaScriptへの変換処理を行う
- 内部では、dartdevc と daert2js の2つのコンパイラが使われている
- dartdevc
- the Dart dev compiler
- 開発用、差分ビルド等が使える
- dart2js
- Dart-to-JavaScript compiler
- 本番用
- HTMLから変換されたJavaScriptを呼び出すことで処理を実行する
DartでWebアプリケーション作成
$ dart --version Dart VM version: 2.7.2 (Mon Mar 23 22:11:27 2020 +0100) on "macos_x64" // DartからJavaScriptへの変換処理を行うためのツール $ pub global activate webdev // プロジェクト作成 $ mkdir dartwebapp $ cd dartwebapp $ vi pubspec.yaml name: dartwebapp description: Dart web application environment: sdk: '>=2.7.0 <3.0.0' dev_dependencies: # dependencies for webdev build_runner: ^1.8.1 build_test: ^0.10.12+1 build_web_compilers: ^2.9.0 $ vi web/index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>dartwebapp</title> <!-- JavaScriptに変換されたmain.dartを読み込む --> <script defer src="main.dart.js"></script> </head> <body> <div id="hello"></div> </body> </html> $ vi web/main.dart import 'dart:html'; void main() { querySelector('#hello').text = 'Hello World!!'; } // Webアプリケーション起動(開発用) $ pub global run webdev serve ... [INFO] Serving `web` on http://127.0.0.1:8080 ... // ビルド(本番用) $ pub global run webdev build --release
Flutterでの描画処理
- HTML・CSS・Canvasを組み合わせて描画を行っている
DomCanvasとBitmapCanvasの使われ方
import 'package:flutter/material.dart'; void main() => runApp(MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar( leading: FlutterLogo(), ), body: Center( child: Text('Hello World'), ), ), ); } }
<flt-scene flt-layer-state="updated" style="position: absolute;"> <flt-transform flt-layer-state="updated" style="position: absolute; transform-origin: 0px 0px 0px;"> <flt-offset flt-layer-state="retained" style="position: absolute; transform-origin: 0px 0px 0px; transform: translate(0px, 0px);"> <flt-offset flt-layer-state="retained" style="position: absolute; transform-origin: 0px 0px 0px; transform: translate(0px, 0px);"> <flt-clip flt-layer-state="retained" clip-type="physical-shape" style="position: absolute; overflow: hidden; background-color: rgb(250, 250, 250); box-shadow: none; left: 0px; top: 0px; width: 552px; height: 815px; border-radius: 0px;"> <flt-clip-interior style="position: absolute; left: 0px; top: 0px;"> <flt-picture flt-layer-state="retained" style="position: absolute; transform: translate(0px, 0px);"> <!-- HTML&CSSのみで描画できる場合 → HTML&CSSを使う (DomCanvas) --> <flt-dom-canvas style="position: absolute; top: 0px; right: 0px; bottom: 0px; left: 0px;"> <!-- Scaffold.body --> <p style="font-size: 14px; font-weight: normal; font-family: Roboto, Arial, sans-serif; color: rgba(0, 0, 0, 0.867); position: absolute; white-space: pre-wrap; overflow-wrap: break-word; overflow: hidden; height: 16px; width: 72px; transform-origin: 0px 0px 0px; transform: matrix(1, 0, 0, 1, 240, 427.5);">Hello World</p> </flt-dom-canvas> </flt-picture> <flt-clip flt-layer-state="retained" clip-type="physical-shape" style="position: absolute; overflow: hidden; background-color: rgb(33, 150, 243); box-shadow: rgba(0, 0, 0, 0.4) 1.33333px 2.66667px 5.52px 0px; left: 0px; top: 0px; width: 552px; height: 56px; border-radius: 0px;"> <flt-clip-interior style="position: absolute; left: 0px; top: 0px;"> <flt-picture flt-layer-state="retained" style="position: absolute; transform: translate(0px, 0px);"> <!-- HTML&CSSのみで描画できない場合 → Canvasを使う (BitmapCanvas) --> <flt-canvas style="position: absolute; transform: translate(6px, 1px);"> <!-- Scaffold.appBar --> <canvas width="44" height="54" style="position: absolute; width: 44px; height: 54px; z-index: -1;"></canvas> </flt-canvas> </flt-picture> </flt-clip-interior> </flt-clip> <flt-picture flt-layer-state="retained" style="position: absolute; transform: translate(0px, 0px);"></flt-picture> </flt-clip-interior> </flt-clip> </flt-offset> </flt-offset> </flt-transform> </flt-scene>
Nativeコードを呼び出す(JavaScriptを呼び出す)
- Android/iOSとは異なりFlutter for WebではDartからJavaScriptに変換して実行されるため、DartからJavaScriptに変換するための型を定義することで任意のJavaScriptの処理を呼び出すことができる
package:js
を使用し変換のための型を定義する