Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
[Flutter] 端末を傾けてWidgetを動かす
Search
beeeyan
June 07, 2024
1
89
[Flutter] 端末を傾けてWidgetを動かす
2024/6/7 FlutterKaigi mini in Osaka の発表資料
beeeyan
June 07, 2024
Tweet
Share
More Decks by beeeyan
See All by beeeyan
div要素の中に、Flutterを埋め込んでみよう
beeeyan
0
260
Featured
See All Featured
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
12
960
Designing Experiences People Love
moore
140
23k
Keith and Marios Guide to Fast Websites
keithpitt
411
22k
The Pragmatic Product Professional
lauravandoore
32
6.4k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
120k
A designer walks into a library…
pauljervisheath
205
24k
GitHub's CSS Performance
jonrohan
1030
460k
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Fashionably flexible responsive web design (full day workshop)
malarkey
406
66k
Code Review Best Practice
trishagee
67
18k
GraphQLの誤解/rethinking-graphql
sonatard
68
10k
Transcript
[Flutter] 端末を傾けて Widgetを動かす beeeyan(ベーやん)
デモ Github https://github.com/beeeyan/gyro_app
「傾けられていること」を検知する方法 「sensors_plus」を使う。 https://pub.dev/packages/sensors_plus
sensors_plusで検知できるもの 全てx,y,zの値をもつ accelerometerEvent ・重力(加速度)を含んだデータ userAccelerometerEvent ・重力(加速度)を含まないデータ gyroscopeEvent ・回転速度(rad/s)で提供される ( https://kawa.dev/posts/flutter-3d-gyro/
) magnetometerEvent ・磁力計
例) 右側面を地面に向けたとき
基本 @override void initState() { super.initState(); _streamSubscriptions .add( accelerometerEventStream ().listen(
(AccelerometerEvent event) {} ), ); StatefulWidget initStateの中でlistenする
Widgetの場所の指定 child: Stack( children: [ Positioned( left: widgetX, top: widgetY,
Stack・Positionedを利用 ※ leftとtopが両方とも 0であれば左上の位置となる
定数を乗算 accelerometerEventStream().listen( (AccelerometerEvent event) { setState(() { accelX = event.x;
accelY = event.y; if (!isPhysics) { // 新しい位置を計算 widgetX -= accelX * 20; widgetY += accelY * 20; // 画面外に出ないようにする if (widgetX < 0) { widgetX = 0; } 〜枠をはみ出ないようにするための制御〜 } });
等加速度運動 // 物理演算で計算するためにTimerで値を更新する。 // SensorInterval.normalIntervalの値で処理できたかも。 // デフォルトstatic const normalInterval =
Duration(milliseconds: 200); _timer = Timer.periodic(Duration(milliseconds: timerMilliseconds), (Timer timer) { if (isPhysics) { final seconds = timerMilliseconds / 1000; // 速度の更新 velX -= accelX * seconds; velY += accelY * seconds; widgetX += velX * seconds + 1 / 2 * preAccelX * pow(seconds, 2); widgetY += velY * seconds + 1 / 2 * preAccelY * pow(seconds, 2); preAccelX = accelX; preAccelY = accelY;
等加速度運動 速度更新の式 : 距離 : Timerを利用したのは「t (s)」を知りたかったから ( GPT-4o案) →
sensorの更新間隔だけで処理できたかも
反発係数 壁にぶつかった時、反発係数をかけて速度を反転させる。 if (widgetX < 0) { widgetX = 0;
velX *= bounceFactor; preAccelX = 0; } if (widgetY < 0) { widgetY = 0; velY *= bounceFactor; preAccelY = 0; } bounceFactor自体がマイナス
回転 加速度から位相角を取得 final rotationAngle = atan2(accelY, accelX); Transform.rotateで回転状態を反映 child: Transform.rotate(
angle: isRotate ? rotationAngle : 0, child: Container( height: boxSize, width: boxSize, decoration: BoxDecoration(
別の検証 : Flutter Flame 「flame_forge2d」 https://pub.dev/packages/flame_forge2d https://flame.tnantoka.com/examples/physics/ https://www.egao-inc.co.jp/tech/flutter_2d/
加速度センサーの反映 @override Future<void> onLoad() async { super.onLoad(); final viewWidth =
size.x; final viewHeight = size.y - kBottomNavigationBarHeight - kToolbarHeight; ball = Ball(pos: Vector2(size.x / 2, size.y / 2)); add(ball!); accelerometerEventStream().listen((AccelerometerEvent event) { accelX = event.x; accelY = event.y; }); _timer = Timer.periodic(const Duration(milliseconds: 16), (Timer timer) { if (ball != null) { ball!.body.applyForce(Vector2(-accelX * 1000, accelY * 1000)); } }); onLoadの中で呼び出せる 物体に「applyForce」で影響を 与えることができる
まとめ ・実実装するとなると、それなりに大変かも。 (自然な動き、、とは?) ・要件が許せばflameから検討するのが良い可能性がある。 (学習コストはそれなりにありそうだが、みなさんが考えるやりたいことに近いかも) 〜 感想 : モバイルの可能性を追求しているという点では楽しかった
参考 https://pub.dev/packages/sensors_plus https://note.com/hatchoutschool/n/n03667b574f77 Flame) https://flame.tnantoka.com/examples/lifecycle/ https://pub.dev/packages/flame_forge2d https://flame.tnantoka.com/examples/physics/ https://www.egao-inc.co.jp/tech/flutter_2d/ https://pub.dev/documentation/flame_forge2d/latest/flame_forge2d/Body/app lyForce.html
and GPT-4o