这个工具不仅功能完整,还包含了动画效果和响应式设计。
```html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>骰子工具 - 随机数生成器</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
padding: 20px;
}
.container {
background: rgba(255, 255, 255, 0.95);
border-radius: 20px;
padding: 40px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
text-align: center;
max-width: 400px;
width: 100%;
backdrop-filter: blur(10px);
}
h1 {
color: #333;
margin-bottom: 30px;
font-size: 2rem;
font-weight: 600;
}
.dice-container {
margin: 40px auto;
width: 120px;
height: 120px;
position: relative;
perspective: 1000px;
}
.dice {
width: 100%;
height: 100%;
background: #fff;
border-radius: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
display: flex;
justify-content: center;
align-items: center;
font-size: 60px;
font-weight: bold;
color: #333;
transition: transform 0.6s ease;
cursor: pointer;
position: relative;
overflow: hidden;
}
.dice::before {
content: '';
position: absolute;
top: -50%;
left: -50%;
width: 200%;
height: 200%;
background: linear-gradient(45deg, transparent, rgba(255, 255, 255, 0.3), transparent);
transform: rotate(45deg);
transition: all 0.6s;
opacity: 0;
}
.dice:hover::before {
animation: shine 0.6s ease-in-out;
}
@keyframes shine {
0% {
transform: translateX(-100%) translateY(-100%) rotate(45deg);
opacity: 0;
}
50% {
opacity: 1;
}
100% {
transform: translateX(100%) translateY(100%) rotate(45deg);
opacity: 0;
}
}
.dice.rolling {
animation: roll 0.6s ease-in-out;
}
@keyframes roll {
0% {
transform: rotateX(0) rotateY(0);
}
25% {
transform: rotateX(180deg) rotateY(90deg);
}
50% {
transform: rotateX(360deg) rotateY(180deg);
}
75% {
transform: rotateX(540deg) rotateY(270deg);
}
100% {
transform: rotateX(720deg) rotateY(360deg);
}
}
.dot-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 8px;
width: 80px;
height: 80px;
padding: 10px;
}
.dot {
width: 16px;
height: 16px;
background: #333;
border-radius: 50%;
opacity: 0;
transition: opacity 0.3s ease;
}
.dot.active {
opacity: 1;
}
.roll-button {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 15px 40px;
font-size: 18px;
font-weight: 600;
border-radius: 50px;
cursor: pointer;
transition: all 0.3s ease;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
margin-top: 20px;
}
.roll-button:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
}
.roll-button:active {
transform: translateY(0);
}
.roll-button:disabled {
opacity: 0.6;
cursor: not-allowed;
transform: none;
}
.result {
margin-top: 30px;
font-size: 24px;
color: #555;
min-height: 30px;
display: flex;
align-items: center;
justify-content: center;
gap: 10px;
}
.result-number {
font-size: 36px;
font-weight: bold;
color: #667eea;
animation: fadeIn 0.5s ease;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: scale(0.8);
}
to {
opacity: 1;
transform: scale(1);
}
}
.history {
margin-top: 30px;
padding-top: 20px;
border-top: 1px solid #e0e0e0;
}
.history-title {
font-size: 16px;
color: #666;
margin-bottom: 10px;
}
.history-list {
display: flex;
gap: 8px;
justify-content: center;
flex-wrap: wrap;
}
.history-item {
width: 30px;
height: 30px;
background: #f0f0f0;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: 600;
color: #666;
animation: slideIn 0.3s ease;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(-10px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@media (max-width: 480px) {
.container {
padding: 30px 20px;
}
h1 {
font-size: 1.5rem;
}
.dice-container {
width: 100px;
height: 100px;
}
.dice {
font-size: 50px;
}
.dot-container {
width: 70px;
height: 70px;
}
.dot {
width: 14px;
height: 14px;
}
}
</style>
</head>
<body>
<div class="container">
<h1> 骰子工具</h1>
<div class="dice-container">
<div class="dice" id="dice">
<div class="dot-container" id="dotContainer">
<div class="dot" data-position="1"></div>
<div class="dot" data-position="2"></div>
<div class="dot" data-position="3"></div>
<div class="dot" data-position="4"></div>
<div class="dot" data-position="5"></div>
<div class="dot" data-position="6"></div>
<div class="dot" data-position="7"></div>
<div class="dot" data-position="8"></div>
<div class="dot" data-position="9"></div>
</div>
</div>
</div>
<button class="roll-button" id="rollButton" onclick="rollDice()">
掷骰子
</button>
<div class="result" id="result">
点击按钮开始
</div>
<div class="history">
<div class="history-title">历史记录</div>
<div class="history-list" id="historyList"></div>
</div>
</div>
<script>
let history = [];
const maxHistory = 10;
// 骰子点数对应的点位置
const dicePatterns = {
1: [5],
2: [1, 9],
3: [1, 5, 9],
4: [1, 3, 7, 9],
5: [1, 3, 5, 7, 9],
6: [1, 3, 4, 6, 7, 9]
};
function rollDice() {
const dice = document.getElementById('dice');
const button = document.getElementById('rollButton');
const result = document.getElementById('result');
// 禁用按钮防止重复点击
button.disabled = true;
button.textContent = '掷骰中...';
// 添加滚动动画
dice.classList.add('rolling');
// 清除当前显示的点
const dots = document.querySelectorAll('.dot');
dots.forEach(dot => dot.classList.remove('active'));
// 在动画期间快速切换数字
let animationCount = 0;
const animationInterval = setInterval(() => {
const tempNumber = Math.floor(Math.random() * 6) + 1;
showDots(tempNumber);
animationCount++;
if (animationCount >= 10) {
clearInterval(animationInterval);
}
}, 60);
// 动画结束后显示最终结果
setTimeout(() => {
dice.classList.remove('rolling');
// 生成最终随机数
const finalNumber = Math.floor(Math.random() * 6) + 1;
// 显示骰子点数
showDots(finalNumber);
// 更新结果显示
result.innerHTML = `结果是:<span class="result-number">${finalNumber}</span>`;
// 添加到历史记录
addToHistory(finalNumber);
// 恢复按钮
button.disabled = false;
button.textContent = '再次掷骰';
}, 600);
}
function showDots(number) {
const dots = document.querySelectorAll('.dot');
const pattern = dicePatterns[number];
// 清除所有点
dots.forEach(dot => dot.classList.remove('active'));
// 显示对应的点
pattern.forEach(position => {
const dot = document.querySelector(`[data-position="${position}"]`);
if (dot) {
dot.classList.add('active');
}
});
}
function addToHistory(number) {
history.unshift(number);
// 限制历史记录数量
if (history.length > maxHistory) {
history.pop();
}
updateHistoryDisplay();
}
function updateHistoryDisplay() {
const historyList = document.getElementById('historyList');
historyList.innerHTML = '';
history.forEach((number, index) => {
const item = document.createElement('div');
item.className = 'history-item';
item.textContent = number;
item.style.animationDelay = `${index * 0.05}s`;
historyList.appendChild(item);
});
}
// 初始化显示
showDots(1);
// 添加键盘支持
document.addEventListener('keydown', (e) => {
if (e.code === 'Space' || e.code === 'Enter') {
e.preventDefault();
const button = document.getElementById('rollButton');
if (!button.disabled) {
rollDice();
}
}
});
// 点击骰子也可以掷骰子
document.getElementById('dice').addEventListener('click', () => {
const button = document.getElementById('rollButton');
if (!button.disabled) {
rollDice();
}
});
</script>
</body>
</html>
```
这个骰子工具具有以下特点:
1. **视觉设计**:
- 现代化的渐变背景和毛玻璃效果
- 真实的骰子外观,使用点阵显示1-6的数字
- 平滑的动画效果和过渡
2. **交互功能**:
- 点击按钮或骰子都可以掷骰子
- 掷骰时有旋转动画,模拟真实骰子滚动
- 支持键盘操作(空格键或回车键)
3. **用户体验**:
- 防止重复点击的按钮状态管理
- 清晰的结果显示
- 历史记录功能,显示最近10次的结果
- 响应式设计,适配移动设备
4. **细节优化**:
- 悬停效果和光泽动画
- 平滑的动画过渡
- 友好的提示文字
你可以直接保存这个HTML文件并在浏览器中打开使用。希望这个骰子工具能满足你的需求!