寫一個搖骰子的效果

語言: CN / TW / HK

    年前接到一個需求,做一個春節拜年的動態效果H5,中間有一個小的效果是搖一個骰子,然後根據搖中的數字,隨機對應一條祝福語。互動效果描述如下:
1. 搖動的時候,有骰子翻轉搖動的效果; 2. 骰子轉動停止後,顯示出搖中的數字那一面,並有立體感; 3. 骰子搖動過程中有音樂。

開發環境如下: markdown Vue:2.7.14 實現難點: markdown 1. 如何繪製骰子🎲立體圖形(通過HTML+CSS3的方式); 2. 如何展示立方體,並有立體感; 3. 骰子🎲動起來; 工程實現如下:
第一部分: 繪製骰子六個面(HTML+CSS3)
1.常識:骰子六個面的對應關係,1點---6點、2點---5點、3點---4點;
2.6個面都使用flex佈局,每個點數都是利用flex佈局容器、元素之間的一些組合關係,都是正方形;
3.目前6個面的點數佈局與實際骰子情況有點出入,讀者可按照實際情況進行優化
效果圖如下:

![image.png](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/58b575f339064b12ac973a930163c1fc~tplv-k3u1fbpfcp-watermark.image?)

第二部分 將6個面組合在一起,形成立體感

1.開始進入立體空間內的想象。
第一步:先通過position進行定位,設定top:0;left:0實現6個面都疊加在一起,並開啟3D檢視,讓每個面在3D空間開展;
css transform-style: preserve-3d 第二步:以1點朝上、6點朝下為視角的話,設定第六個點沿Z軸反方向位移一半的邊長,其餘均沿著Z軸正方向位移一半的邊長;
虛擬碼如下: plain 第六個點:translateZ(-1/2*邊長) 第一、二、三、四、5個點:translateZ(1/2*邊長)

第三步:針對第二個、三個、四個、五個 進行rotate變換(X軸、Y軸)
關鍵點:進行translateZ位移變換後,其transform-origin沒有改變還是之前未發生位移前的中心點,也就是說這四個面的中心點是一樣的,也就是這個立體骰子的中心點,仔細想想是不是這樣 虛擬碼如下:

plain 第二個點:roteteX(-90deg) 第五個點:roteteX(90deg) 第三個點:roteteY(90deg) 第四個點:roteteY(-90deg) 第四步:基本完成了一個骰子的立體形狀

等等,這為什麼看起來像是一個平面圖,不著急,將整體立方體傾斜一些後即可實現【作為初始值】 css transform: rotateX(45deg) rotateY(0deg) rotateZ(-45deg);

至此,一個骰子🎲靜態形象就做成了

第三部分 讓骰子🎲動起來
目標:點選骰子的時候,讓骰子🎲動起來的,並記錄骰子🎲靜止下來的點數;
方法方式:通過CSS3的animation屬性來讓骰子🎲動起來;通過webkitAnimationEnd事件來監聽動畫結束事件;確定的點數可以通過隨機Math.random來實現。程式碼實現如下:

css // 新增animation動畫keyframes規則 @keyframes rotate { to { transform: rotateX(360deg) rotateY(360deg) rotateZ(90deg); scale: 1.5; } } // 新增動畫class .dice-animation { animation: rotate 1s linear 0s 5 normal; } // 通過控制點選開關isDiceAnimation來判斷是否新增動畫class ```js // 通過webkitAnimationEnd事件來監聽動畫結束事件,並賦值隨機數 async onAnimationEnd() { this.diceDom.addEventListener('webkitAnimationEnd', () => { // 準備抽取的隨機數、抽取的隨機結果 let random = Math.floor(Math.random() * 6), result = this.possibility[random]

// 瀏覽器反應不過來加過渡
setTimeout(() => {
  // 讓骰子旋轉到正確的角度,更改動畫屬性,以待下一次動畫的正常執行
  this.diceExistTransformStyle = `rotateX(${result.x}deg) rotateY(${result.y}deg) rotateZ(${result.z}deg`
  this.isDiceAnimation = false;
  this.resultValue = result.value;
}, 0);

}) } 其中,要實現每個面都是同一個型別的斜檢視this.possibility需要做一些初始定義:js possibility: [ {value: 1, x: 45, y: 0, z: -45}, {value: 2, x: 135, y: -45, z: 0}, {value: 3, x: -45, y: -45, z: -90}, {value: 4, x: 135, y: 45, z: -90}, {value: 5, x: -45, y: 45, z: 0}, {value: 6, x: 45, y: 180, z: -45}, ] ``` 至此,一個動態的骰子效果實現了【額外增加了一個scale變大變小的animation效果】,大家快去體驗下吧,歡迎底下留言交流

jcode