年前接到一个需求,做一个春节拜年的动态效果H5,中间有一个小的效果是摇一个骰子,然后根据摇中的数字,随机对应一条祝福语。交互效果描述如下:
- 摇动的时候,有骰子翻转摇动的效果;
- 骰子转动停止后,显示出摇中的数字那一面,并有立体感;
- 骰子摇动过程中有音乐。
开发环境如下:
Vue:2.7.14
实现难点:
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空间开展;
transform-style: preserve-3d
第二步:以1点朝上、6点朝下为视角的话,设置第六个点沿Z轴反方向位移一半的边长,其余均沿着Z轴正方向位移一半的边长;
伪代码如下:
第六个点:translateZ(-1/2*边长)
第一、二、三、四、5个点:translateZ(1/2*边长)
第三步:针对第二个、三个、四个、五个 进行rotate变换(X轴、Y轴)
【关键点:进行translateZ位移变换后,其transform-origin没有改变还是之前未发生位移前的中心点,也就是说这四个面的中心点是一样的,也就是这个立体骰子的中心点,仔细想想是不是这样】
伪代码如下:
第二个点:roteteX(-90deg)
第五个点:roteteX(90deg)
第三个点:roteteY(90deg)
第四个点:roteteY(-90deg)
第四步:基本完成了一个骰子的立体形状
等等,这为什么看起来像是一个平面图,不着急,将整体立方体倾斜一些后即可实现【作为初始值】
transform: rotateX(45deg) rotateY(0deg) rotateZ(-45deg);
第三部分 让骰子🎲动起来
目标:点击骰子的时候,让骰子🎲动起来的,并记录骰子🎲静止下来的点数;
方法方式:通过CSS3的animation属性来让骰子🎲动起来;通过webkitAnimationEnd事件来监听动画结束事件;确定的点数可以通过随机Math.random来实现。代码实现如下:
// 添加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
// 通过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需要做一些初始定义:
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效果】,大家快去体验下吧,欢迎底下留言交流