寫一個搖骰子的效果
年前接到一個需求,做一個春節拜年的動態效果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個面的點數佈局與實際骰子情況有點出入,讀者可按照實際情況進行優化
效果圖如下:
第二部分 將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效果】,大家快去體驗下吧,歡迎底下留言交流