JavaScript模拟摇骰子核心依赖随机数生成与动画交互,通过Math.random()生成1-6的随机整数,结合CSS transition或JavaScript定时器实现骰子旋转动画,逐步展示点数变化,用户点击按钮触发动画,模拟骰子滚动效果,动画结束后更新DOM显示最终结果,兼顾随机性与动态交互,提升用户体验。
用JavaScript模拟摇骰子:从基础动画到趣味互动实现
骰子作为一种经典的随机工具,广泛应用于游戏、抽奖、决策等场景,在网页中实现"摇骰子"功能,不仅能增加页面的趣味性,还能提升用户交互体验,本文将从基础到进阶,详细介绍如何用JavaScript模拟摇骰子,包括2D简单效果、3D动态效果,以及交互优化和扩展应用。
摇骰子的核心需求分析
在开始编码前,我们需要明确模拟骰子的核心功能:
- 随机性:最终结果必须是1-6的随机整数,确保公平性;
- 动画效果:摇动过程需要有视觉反馈,模拟真实骰子的滚动感;
- 结果展示:动画结束后清晰显示点数,并能支持重复触发;
- 交互友好:用户可主动触发摇骰子,动画期间避免重复操作。
基础实现:2D骰子的简单模拟
对于初学者,可以先从2D骰子入手,通过切换不同点数的静态图片或CSS绘制,配合简单的翻转动画实现效果。
HTML结构
创建一个容器放置骰子,内部用div表示骰子的面(点数):
<div class="dice-container">
<div class="dice" id="dice">
<div class="dice-face dice-face-1">1</div>
<div class="dice-face dice-face-2">2</div>
<div class="dice-face dice-face-3">3</div>
<div class="dice-face dice-face-4">4</div>
<div class="dice-face dice-face-5">5</div>
<div class="dice-face dice-face-6">6</div>
</div>
<button id="rollBtn">摇骰子</button>
</div>
CSS样式
隐藏除当前点数外的所有面,添加翻转动画:
.dice-container {
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.dice {
width: 100px;
height: 100px;
position: relative;
transform-style: preserve-3d;
}
.dice-face {
position: absolute;
width: 100%;
height: 100%;
background: #fff;
border: 2px solid #333;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: bold;
display: none; /* 默认隐藏所有面 */
}
.dice-face.active {
display: flex; /* 显示当前点数 */
}
/* 翻转动画 */
@keyframes flip {
0% { transform: rotateY(0deg); }
50% { transform: rotateY(1800deg); } /* 多转几圈增强效果 */
100% { transform: rotateY(3600deg); }
}
.dice.rolling {
animation: flip 1s ease-in-out;
}
JavaScript逻辑
点击按钮时,触发随机点数切换和动画:
const dice = document.getElementById('dice');
const rollBtn = document.getElementById('rollBtn');
const faces = document.querySelectorAll('.dice-face');
rollBtn.addEventListener('click', () => {
// 禁用按钮,防止重复点击
rollBtn.disabled = true;
// 移除之前的active类,触发动画
faces.forEach(face => face.classList.remove('active'));
dice.classList.add('rolling');
// 1秒后(动画结束时)显示结果
setTimeout(() => {
const result = Math.floor(Math.random() * 6) + 1; // 1-6随机数
faces[result - 1].classList.add('active'); // 显示对应点数
dice.classList.remove('rolling');
rollBtn.disabled = false; // 重新启用按钮
}, 1000);
});
// 初始化显示1点
faces[0].classList.add('active');
进阶实现:3D骰子的动态效果
2D骰子效果较为简单,但缺乏真实感,我们可以通过CSS 3D变换,实现一个可旋转的3D骰子,让用户从不同角度观察摇动过程。
调整HTML结构
3D骰子需要6个面分别对应骰子的6个方向(前、后、左、右、上、下):
<div class="dice-container">
<div class="dice-3d" id="dice3d">
<div class="dice-face dice-face-1">1</div>
<div class="dice-face dice-face-2">2</div>
<div class="dice-face dice-face-3">3</div>
<div class="dice-face dice-face-4">4</div>
<div class="dice-face dice-face-5">5</div>
<div class="dice-face dice-face-6">6</div>
</div>
<button id="rollBtn3d">摇骰子</button>
</div>
CSS样式
为3D骰子添加透视效果和面的定位:
.dice-3d {
width: 100px;
height: 100px;
position: relative;
transform-style: preserve-3d;
transform: translateZ(-50px);
}
.dice-face {
position: absolute;
width: 100px;
height: 100px;
background: linear-gradient(135deg, #f5f5f5 0%, #e0e0e0 100%);
border: 2px solid #333;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
font-size: 24px;
font-weight: bold;
box-shadow: inset 0 0 20px rgba(0,0,0,0.1);
}
/* 定位6个面 */
.dice-face-1 { transform: rotateY(0deg) translateZ(50px); }
.dice-face-2 { transform: rotateY(90deg) translateZ(50px); }
.dice-face-3 { transform: rotateY(180deg) translateZ(50px); }
.dice-face-4 { transform: rotateY(-90deg) translateZ(50px); }
.dice-face-5 { transform: rotateX(90deg) translateZ(50px); }
.dice-face-6 { transform: rotateX(-90deg) translateZ(50px); }
/* 3D摇动动画 */
@keyframes roll3d {
0% { transform: rotateX(0deg) rotateY(0deg); }
25% { transform: rotateX(720deg) rotateY(360deg); }
50% { transform: rotateX(1440deg) rotateY(720deg); }
75% { transform: rotateX(2160deg) rotateY(1080deg); }
100% { transform: rotateX(2880deg) rotateY(1440deg); }
}
.dice-3d.rolling {
animation: roll3d 2s ease-out;
}
JavaScript逻辑
3D骰子的逻辑与2D类似,但需要根据结果旋转到正确的面:
const dice3d = document.getElementById('dice3d');
const rollBtn3d = document.getElementById('rollBtn3d');
const faces3d = document.querySelectorAll('.dice-face-3d .dice-face');
rollBtn3d.addEventListener('click', () => {
rollBtn3d.disabled = true;
dice3d.classList.add('rolling');
setTimeout(() => {
const result = Math.floor(Math.random() * 6) + 1;
// 根据结果设置旋转角度
const rotations = {
1: 'rotateX(0deg) rotateY(0deg)',
2: 'rotateX(0deg) rotateY(-90deg)',
3: 'rotateX(0deg) rotateY(-180deg)',
4: 'rotateX(0deg) rotateY(90deg)',
5: 'rotateX(-90deg) rotateY(0deg)',