携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天
前言
使用虎撲APP時,注意到個人頁面上的勳章展示區,勳章會隨手機的轉動而移動掉落。很喜歡這個效果,也很好奇是怎麼實現的,便想在flutter上嘗試重現出來,當作練習項目。
思路
在這邊大致列幾個關鍵點
- 基本運動
- 邊界碰撞
- 相互碰撞
- 球體自轉
基本運動
使用sensors_plus
我這裡選用加速度感測的監聽,ValueNotifier來觸發刷新取代setstate。
import 'package:sensors_plus/sensors_plus.dart';
ValueNotifier<List<double>> phoneXY = ValueNotifier([0, 0]);
StreamSubscription sensor = accelerometerEvents.listen((AccelerometerEvent event) {
phoneXY.value = [event.x, event.y];
});
由於sensors_plus在安卓端適用SensorManager默認 SENSOR_DELAY_NORMAL靈敏度不高,可以手動修改套件的本地緩存,或是把sensors_plus colne下來改成私有專案(以下是兩種引用私有庫方式)。
sensors_plus:
git:
url: https://github.com/xxx/sensors_plus.git
sensors_plus:
path: xxx/sensors_plus
定義小球
class Ball {
//位置
Offset position;
//顏色
Color color;
//半徑
double radius;
//速度
double speedX = 0;
double speedY = 0;
Ball({
//給定默認色
this.color = Colors.lightGreen,
required this.position,
required this.radius,
});
}
繪製小球
先用List放入兩個小球(徽章)
List<Ball> balls = [];
balls.add(
Ball(
radius: 10,
position: const Offset(100, 100),
color: Colors.pink,
),
);
balls.add(
Ball(
radius: 20,
position: const Offset(100, 100),
),
);
我的第一個想法是用canvas繪製,而ValueListenable可以只刷新畫布而不重構widget。
我將每次刷新都當作一個瞬間,大致把模擬移動簡化成下述公式,這樣就有了小球歲加速度計墜落移動的效果。因為每次執行paint都是一個瞬間,就可以把d時間 dt當作1來忽略。
CustomPaint(
size: size,
painter: BallPainter(balls: balls, phoneXY: phoneXY),
),
class BallPainter extends CustomPainter {
final List<Ball> balls;
final ValueListenable<List<double>> phoneXY;
BallPainter({
required this.balls,
required this.phoneXY,
}) : super(repaint: phoneXY);
final Paint _paint = Paint()..isAntiAlias = true;
@override
void paint(Canvas canvas, Size size) {
for (var ball in balls) {
//更新速度
ball.speedX -= phoneXY.value[0] / 20;
ball.speedY += phoneXY.value[1] / 20;
//更新位移
double dx = ball.speedX;
double dy = ball.speedY;
//?位置
ball.position += Offset(dx, dy);
_paint.color = ball.color;
canvas.drawCircle(ball.position, ball.radius, _paint);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
//要能夠刷新
return true;
}
}
後話
基本的運動到這邊就結束了,這些還是比較基礎的內容分享,如果文中有任何錯誤歡迎大佬們指正。
後面幾個關鍵點我還尚未解決,慢慢處理慢慢上傳,有任何想法也歡迎分享,互相參考互相學習。
參考文章
- 拿去吧你!Flutter 仿自如 App 裸眼 3D 效果| 8月更文挑战 @Nayuta
- Flutter 雪花飘落的效果-深夜创作 @早起的年轻人
© 版权声明
文章版权归作者所有,未经允许请勿转载,侵权请联系 admin@trc20.tw 删除。
THE END