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
79
[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
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
3
240
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.4k
Large-scale JavaScript Application Architecture
addyosmani
510
110k
Measuring & Analyzing Core Web Vitals
bluesmoon
5
210
We Have a Design System, Now What?
morganepeng
51
7.3k
The Cost Of JavaScript in 2023
addyosmani
46
7.2k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Building Better People: How to give real-time feedback that sticks.
wjessup
366
19k
Adopting Sorbet at Scale
ufuk
74
9.2k
jQuery: Nuts, Bolts and Bling
dougneiner
62
7.6k
Git: the NoSQL Database
bkeepers
PRO
427
64k
RailsConf 2023
tenderlove
29
970
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