Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
[Flutter] 端末を傾けてWidgetを動かす
Search
beeeyan
June 07, 2024
190
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
[Flutter] 端末を傾けてWidgetを動かす
2024/6/7 FlutterKaigi mini in Osaka の発表資料
beeeyan
June 07, 2024
More Decks by beeeyan
See All by beeeyan
div要素の中に、Flutterを埋め込んでみよう
beeeyan
0
350
Featured
See All Featured
Joys of Absence: A Defence of Solitary Play
codingconduct
1
550
Intergalactic Javascript Robots from Outer Space
tanoku
273
28k
sira's awesome portfolio website redesign presentation
elsirapls
0
470
Scaling GitHub
holman
464
140k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.9k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
254
22k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
2
490
The Cost Of JavaScript in 2023
addyosmani
55
10k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
540
How STYLIGHT went responsive
nonsquared
100
6.3k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
940
How to Ace a Technical Interview
jacobian
280
24k
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