首頁  >  文章  >  微信小程式  >  手把手帶你在小程式中怎麼實現3d裸眼輪播效果

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

青灯夜游
青灯夜游轉載
2022-01-11 18:59:563887瀏覽

小程式輪播如何達到3d裸眼效果?以下這篇文章來為大家介紹實現方法,為春節氣氛添燈加彩,希望對大家有幫助!

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

一個APP眾多功能模組中,首頁輪播圖扮演著重要角色,它是分發重點資訊的入口。想起幾個月前看過一篇文章--《自如客APP裸眼3D效果的實現》,該文提及在安卓app端實現瞭如下裸眼3d banner輪播效果圖:

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

受該文啟發,決定“依葫蘆畫瓢”,嘗試在小程式端模擬實現一個春節氛圍滿滿的3d裸眼效果輪播圖。

原理

仔細觀察上面實現的動態效果圖,可以看出該banner圖並非常規的一張圖片,而是採用了一張圖內容分層的方式疊加顯示(上文提及的文章有提到,是採用了背景層,前景和中景三個疊加後呈現,可以先移步上文了解),然後監聽手機方向感測器,根據方向對前景和背景進行移動,造成視覺上的景深效果。

有趣的是,如果你使用的是iPhone手機,相信你應該能發現在首頁狀態下,隨著手機不同方向的轉動,背景圖會跟著反方向輕微移動,也能給人一種類似的景深效果。 (效果如下圖)

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

實戰

介紹完了原理,那就開始實戰吧。

翻閱小程式文檔,我們需要使用兩個API:wx.startDeviceMotionListening 和 wx.onDeviceMotionChange。 這裡我們需要重點關注的是wx.onDeviceMotionChange這個API返回的內容,根據文檔,該API返回如下三個值:

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

如果你是第一次接觸這個API,相信你看了文件也是一頭霧水,接下來我將用chrome瀏覽器調試工具幫你徹底理解這三個值分別是什麼意思。

使用chrome開發者工具理解API回傳值

開啟瀏覽器開發者工具,依照下列步驟開啟感測器偵錯:

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

#開啟後,看這裡:

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

咦?這不是一樣的嗎?沒錯,這裡顯示的三個值剛好與該API回傳值對應。可以看到在alpha=0,beta=90,gamma=0的情況下,代表手機是垂直立在平面,我門可以點擊選項或直接在輸入框中修改值,就可以直觀的看到隨著值的變化,手機的翻轉狀態變化,例如手機平放桌面時,三個參數值如下:

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

#有了上面即時模擬的工具,接下來這個圖就好理解了:

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

  • alpha:表示裝置沿著Z 軸旋轉的角度,範圍為0~360;
  • beta:表示設備在x軸上的旋轉角度,範圍為-180~180。它描述的是設備由前向後旋轉的情況;
  • gamma:表示設備在y軸上的旋轉角度,範圍為-90~90。它描述的是設備由左向右旋轉的情況。

程式碼

wxml:

<view class="swiper-box">
  <image src="{{item}}" wx:for="{{background}}" class="swiper-bg {{animationStart || current === index ? &#39;fadeIn&#39; : &#39;fadeOut&#39;}} "></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: [&#39;https://cloud-minapp-39237.cloud.ifanrusercontent.com/1n6jtVIbbJ3rnAv7.jpg&#39;, &#39;https://cloud-minapp-39237.cloud.ifanrusercontent.com/1n6mBOvOutOFQ3E8.png&#39;,],
    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()改變元素偏移距離。

最終實現效果

手把手帶你在小程式中怎麼實現3d裸眼輪播效果

這裡看起來效果不是特別明顯,原因有兩個:

  • 素材图是我网上找到拼凑而成,总体合成效果并不美观,想达到较逼真的效果需要设计配合出素材图;
  • 在偏移至最大值时,未做缓冲动画,不合符直觉(这里后面有时间再研究实现);

额外的动画效果

其实借助该方向API,我们还可以作为触发动画的触发器。例如在手机翻转到一定角度值时,我们可以播放烟花效果

安装lottie-miniprogram包

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(&#39;#canvas&#39;).node(res => {
      const canvas = res.node
      const context = canvas.getContext(&#39;2d&#39;)
      lottie.setup(canvas)
      lottieInstance = lottie.loadAnimation({
        path: &#39;https://assets10.lottiefiles.com/packages/lf20_1qfekvox.json&#39;,
        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裸眼輪播效果的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除