介紹
前天看了《自如客APP裸眼3D效果的實現》的效果,覺得這個互動很棒也很好玩,遂用Flutter實現了一個。
巧婦難為無米之炊,因沒有設計稿,所以相較於自如的可以說很醜。 (●'◡'●)
複製程式碼
實現
如《自如客APP裸眼3D效果的實現》 中介紹的,整體構成為3層:
底層、中層、上層
複製程式碼
在轉動手機時,中層
保持不動,底層
和上層
做相反運動。 我們先整合外掛sensors
:
sensors: ^2.0.3
https://pub.flutter-io.cn/packages/sensors/install
複製程式碼
之後通過StreamSubscription
監聽外掛的AccelerometerEvent
事件,其攜帶3個值,分別是:x, y, z
。
這裡介紹一下此處三個值的意思,它們分別代表三個軸的重力感應,如下:
三個軸得取值範圍是一樣的: [-10 , 10]
,方向朝天為正,反之為負。
之後,我們藉助stack
和 position
就可以實現這個互動效果了。
值得注意
這裡需要注意的是,sensor
傳遞的值是通過event channel
,而且值變更的時間視窗較大,粗暴地在收到event後,重新整理頁面效果並不好。
因此,介於感測器值的範圍,和時間視窗的問題,這裡建議將x
和y
的值做略微擴大,並通過AnimatedPositioned
進行位移動畫。也就是說,用動畫時間合理的填充空窗期
,並銜接前後值的變化。類似如下:
因為沒有設計圖,具體位置只能摸索,所以值的設定看起來有點瑣碎,見諒。
複製程式碼
///值僅作參考,具體要根據設計稿和頁面環境靈活配置
///監聽
_streamSubscription =
accelerometerEvents.listen((AccelerometerEvent event) async {
setState(() {
x = event.x * 2.5;
y = event.y * 1.8;
});
});
///主要佈局
Stack(
alignment: Alignment.center,
children: [
AnimatedPositioned(
top: y - 40,
right: x - 10,
duration: Duration(milliseconds: duration),
child: _bottom()),
Positioned(
child: _middle()),
AnimatedPositioned(
bottom: y - 10 ,
left: x + size.width / 3,
duration: Duration(milliseconds: duration),
child: _top()),
],
)
複製程式碼
通過這種方式,H5
應該也能實現不錯的效果。不過在實際應用中,考慮的因素還是比較多的,如:弱網、機型、兜底方案等等
。至此文章就結束了,謝謝閱讀。
Demo程式碼書寫隨意,且還有很多值得優化的地方,歡迎評論區討論。
複製程式碼
Demo程式碼
地址
進入路徑: 首頁 —— 實驗室DEMO —— 裸眼3D