以下是我们今天要构建的示例:

我们将使用Flutter的官方传感器插件来获取设备的倾斜/旋转。
只需将以下内容作为你的依赖项,然后在项目文件夹中运行“pub get”就能完成简单的安装了。
1sensors: ^0.4.2+6
1class PerspectiveZoomDemo extends StatefulWidget {
2 PerspectiveZoomDemo({
3 Key key,
4 }) : super(key: key);
5
6 @override
7 _PerspectiveZoomDemoState createState() => _PerspectiveZoomDemoState();
8}
9
10class _PerspectiveZoomDemoState extends State<PerspectiveZoomDemo> {
11 AccelerometerEvent acceleration;
12 StreamSubscription<AccelerometerEvent> _streamSubscription;
13
14 int planetMotionSensitivity = 4;
15 int bgMotionSensitivity = 2;
16
17 @override
18 void initState() {
19 _streamSubscription = accelerometerEvents.listen((AccelerometerEvent event) {
20 setState(() {
21 acceleration = event;
22 });
23 });
24 super.initState();
25 }
26
27 @override
28 void dispose() {
29 _streamSubscription.cancel();
30 super.dispose();
31 }
32
33 @override
34 Widget build(BuildContext context) {
35 return Scaffold(
36 backgroundColor: Colors.black,
37 body: Center(
38 child: Stack(
39 children: <Widget>[
40 Positioned(
41 top: acceleration.y * bgMotionSensitivity,
42 bottom: acceleration.y * -bgMotionSensitivity,
43 right: acceleration.x * -bgMotionSensitivity,
44 left: acceleration.x * bgMotionSensitivity,
45 child: Align(
46 child: Image.asset(
47 "assets/images/bg.jpg",
48 height: 1920,
49 fit: BoxFit.fitHeight,
50 ),
51 ),
52 ),
53 Positioned(
54 top: acceleration.y * planetMotionSensitivity,
55 bottom: acceleration.y * -planetMotionSensitivity,
56 right: acceleration.x * -planetMotionSensitivity,
57 left: acceleration.x * planetMotionSensitivity,
58 child: Align(
59 child: Image.asset(
60 "assets/images/earth_2.png",
61 width: 250,
62 ),
63 ),
64 ),
65 ],
66 ),
67 ),
68 );
69 }
70}
我们已经订阅了设备的accelerometer events,并且正在乘数bgMotionSensitivity和planetMotionSensitivity的基础上更改背景和行星图像的位置。
答:这是因为视差效果的工作原理,即离你较远的对象要比离你近的对象移动得慢。
行星和背景对设备运动的响应及时,但是…
这里的问题是加速度计的事件太快了,并且值变化得也很快,因此每当值突然变化时,我们的动画就会停顿。
1AnimatedPositioned(
2 duration: Duration(milliseconds: 250),
3 top: acceleration.y * bgMotionSensitivity,
4 bottom: acceleration.y * -bgMotionSensitivity,
5 right: acceleration.x * -bgMotionSensitivity,
6 left: acceleration.x * bgMotionSensitivity,
7 child: Align(
8 child: Image.asset(
9 "assets/images/bg.jpg",
10 height: 1920,
11 fit: BoxFit.fitHeight,
12 ),
13 ),
14 ),
15 AnimatedPositioned(
16 duration: Duration(milliseconds: 250),
17 top: acceleration.y * planetMotionSensitivity,
18 bottom: acceleration.y * -planetMotionSensitivity,
19 right: acceleration.x * -planetMotionSensitivity,
20 left: acceleration.x * planetMotionSensitivity,
21 child: Align(
22 child: Image.asset(
23 "assets/images/earth_2.png",
24 width: 250,
25 ),
26 ),
27 ),
我们已用AnimatedPositioned替换了Positioning,并设置了一些延迟(以毫秒为单位)以创建平滑的过渡效果。
这可以用作登录或介绍屏幕的良好背景。

