一個APP眾多功能模組中,首頁輪播圖扮演著重要角色,它是分發重點資訊的入口。想起幾個月前看過一篇文章--《自如客APP裸眼3D效果的實現》,該文提及在安卓app端實現瞭如下裸眼3d banner輪播效果圖:
受該文啟發,決定「依葫蘆畫瓢」,嘗試在小程式端模擬實現一個春節氛圍滿滿的3d裸眼效果輪播圖。
仔細觀察上面實現的動態效果圖,可以看出該banner圖並非常規的一張圖片,而是採用了一張圖內容分層的方式疊加顯示(上文提及的文章有提到,是採用了背景層,前景和中景三個疊加後呈現,可以先移步上文了解),然後監聽手機方向感測器,根據方向對前景和背景進行移動,造成視覺上的景深效果。
有趣的是,如果你使用的是iPhone手機,相信你應該能發現在首頁狀態下,隨著手機不同方向的轉動,背景圖會跟著反方向輕微移動,也能給人一種類似的景深效果。(效果如下圖)
介紹完了原理,那就開始實戰吧。
翻閱小程式檔案,我們需要用到兩個API:wx.startDeviceMotionListening 和 wx.onDeviceMotionChange。 這裡我們需要重點關注的是wx.onDeviceMotionChange這個API返回的內容,根據檔案,該API返回如下三個值:
如果你是第一次接觸這個API,相信你看了檔案也是一頭霧水,接下來我將用chrome瀏覽器偵錯工具幫你徹底理解這三個值分別是什麼意思。
開啟瀏覽器開發者工具,按照如下步驟開啟感測器偵錯:
開啟後,看這裡:
咦?這不是一樣的嗎?沒錯,這裡顯示的三個值剛好與該API返回值對應。可以看到在alpha=0,beta=90,gamma=0的情況下,代表手機是垂直立在平面,我門可以點選選項或者直接在輸入框中修改值,就可以直觀的看到隨著值的變化,手機的翻轉狀態變化,例如手機平放桌面時,三個引數值如下:
有了上面實時模擬的工具,接下來這個圖就好理解了:
wxml:
<view class="swiper-box"> <image src="{{item}}" wx:for="{{background}}" class="swiper-bg {{animationStart || current === index ? 'fadeIn' : 'fadeOut'}} "></image> <swiper indicator-dots="{{true}}" indicator-active-color="#fff" interval="{{3000}}" autoplay="{{true}}" circular="{{true}}" bindchange="handleChange" bindtransition="handleTransition" bindanimationfinish="handleFinish"> <block wx:for="{{background}}" wx:key="*this"> <swiper-item> <view class="swiper-item-content" > <image class="icon" src="../../images/cloud.png" style="width: 90px; height: 90px;transform: translate3d({{x}}px, {{y}}px, {{z}}px);" wx:if="{{index === 0}}"></image> <image class="icon" src="../../images/firecrackers.png" style="width: 90px; height: 90px;transform: translate3d({{x}}px, {{y}}px, {{z}}px);" wx:else></image> <text class="text" wx:if="{{index === 0}}">新年快樂</text> <text class="text" wx:else>大吉大利</text> </view> </swiper-item> </block> </swiper> </view>
這裡注意的是,由於swiper只能巢狀swiper-item元件,所以需要將背景圖放置於swiper同級,並用定位的方式顯示
js:
// index.js // 獲取應用範例 const app = getApp() Page({ data: { background: ['https://cloud-minapp-39237.cloud.ifanrusercontent.com/1n6jtVIbbJ3rnAv7.jpg', 'https://cloud-minapp-39237.cloud.ifanrusercontent.com/1n6mBOvOutOFQ3E8.png',], x: 0, y: 0, z: 0, animationFinish: true, // 動畫是否執行完成 animationStart: false, // 是否開始執行動畫 current: 0, }, // 動畫開始執行 handleTransition(e) { if (this.data.animationFinish) { this.setData({ animationFinish: false, animationStart: true, }) } }, // 動畫執行結束 handleFinish() { this.setData({ animationFinish: true, animationStart: false, }) }, // current值變化 handleChange(e) { this.setData({ current: e.detail.current, }) }, onLoad() { const that = this; // 監聽方向變化 wx.startDeviceMotionListening({ success() { wx.onDeviceMotionChange(function (res) { const { alpha, // 0-360 beta, // -180-180 gamma // -90- 90 } = res const disX = gamma / 90 * 20 const disY = beta / 90 * 12 let z = 0 if (disX > 0 || disY > 0) { z = 20 } else { z = -20 } that.setData({ x: disX, y: disY, z }) }) } }) } })
這裡要做解釋的程式碼是
const disY = beta / 90 * 12
正常我們使用手機是螢幕朝上,所以取相對值一半即可。
根據計算得到的偏移x,y後,頁面通過transform: translate3d()
改變元素偏移距離。
這裡看起來效果不是特別明顯,原因有兩個:
其實藉助該方向API,我們還可以作為觸發動畫的觸發器。例如在手機翻轉到一定角度值時,我們可以播放煙花效果
npm i lottie-miniprogram
安裝完之後記得在微信開發者工具中點選構建npm包
wxml:
<canvas id="canvas" type="2d" style="position: absolute;top: 0;left: 0;width: 300px; height: 200px;z-index: 99;"></canvas>
js:
onLoad() { // 初始化lottie動畫 wx.createSelectorQuery().select('#canvas').node(res => { const canvas = res.node const context = canvas.getContext('2d') lottie.setup(canvas) lottieInstance = lottie.loadAnimation({ path: 'https://assets10.lottiefiles.com/packages/lf20_1qfekvox.json', autoplay: true, loop: false, rendererSettings:{ context } }) }).exec() }
然後在wx.onDeviceMotionChange
中呼叫
lottieInstance.play()
處理觸發即可
完整程式碼
https://github.com/pengjinlong/cases/tree/main/spring-article
本文轉載自:https://juejin.cn/post/7051490823497580574
作者:碼克吐溫
【相關學習推薦:】
以上就是手把手帶你在小程式中怎麼實現3d裸眼輪播效果的詳細內容,更多請關注TW511.COM其它相關文章!