解压小游戏“动态禅意沙画“
<!DOCTYPE html>
<html>
<head>
<title>动态禅意沙画</title>
<style>
body {
margin: 0;
height: 100vh;
background: #2c3e50;
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
}
#canvas {
width: 800px;
height: 500px;
background: #ecf0f1;
border-radius: 10px;
box-shadow: 0 0 30px rgba(0,0,0,0.3);
position: relative;
}
.sand {
position: absolute;
pointer-events: none;
border-radius: 50%;
mix-blend-mode: multiply;
animation: fade 3s forwards;
}
.tool {
position: fixed;
bottom: 30px;
padding: 15px 30px;
background: rgba(255,255,255,0.9);
border-radius: 25px;
cursor: pointer;
transition: all 0.3s;
font-family: Arial;
}
.tool:hover {
transform: scale(1.1);
box-shadow: 0 0 15px rgba(255,255,255,0.5);
}
@keyframes fade {
0% { opacity: 1; transform: scale(1); }
100% { opacity: 0; transform: scale(3); }
}
.pattern {
position: absolute;
width: 50px;
height: 50px;
background: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MCIgaGVpZ2h0PSI1MCI+PGNpcmNsZSBjeD0iMjUiIGN5PSIyNSIgcj0iMjAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzAwMCIgc3Ryb2tlLXdpZHRoPSIyIi8+PC9zdmc+');
animation: spin 20s linear infinite;
opacity: 0.1;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
</style>
</head>
<body>
<div id="canvas"></div>
<div class="tool" id="clearBtn">清空画布</div>
<!-- 内嵌音频 -->
<audio id="sound" src="data:audio/wav;base64,UklGRl9vT19XQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQ..."></audio>
<script>
const canvas = document.getElementById('canvas');
const colors = ['#e74c3c', '#3498db', '#2ecc71', '#f1c40f', '#9b59b6'];
let currentColor = 0;
let isDrawing = false;
// 生成背景图案
for(let i=0; i<8; i++) {
const pattern = document.createElement('div');
pattern.className = 'pattern';
pattern.style.left = Math.random() * 90 + '%';
pattern.style.top = Math.random() * 90 + '%';
pattern.style.animationDuration = Math.random() * 10 + 10 + 's';
canvas.appendChild(pattern);
}
canvas.addEventListener('mousedown', startDrawing);
canvas.addEventListener('mousemove', draw);
canvas.addEventListener('mouseup', stopDrawing);
canvas.addEventListener('mouseleave', stopDrawing);
document.getElementById('clearBtn').addEventListener('click', () => {
canvas.querySelectorAll('.sand').forEach(s => s.remove());
});
function startDrawing(e) {
isDrawing = true;
createSand(e);
}
function draw(e) {
if(!isDrawing) return;
createSand(e);
}
function stopDrawing() {
isDrawing = false;
}
function createSand(e) {
const rect = canvas.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
for(let i=0; i<3; i++) {
const sand = document.createElement('div');
sand.className = 'sand';
sand.style.left = x + 'px';
sand.style.top = y + 'px';
sand.style.background = colors[currentColor];
sand.style.width = Math.random() * 15 + 5 + 'px';
sand.style.height = sand.style.width;
sand.style.animation = `fade ${Math.random()*2 + 1}s linear`;
// 添加物理效果
const angle = Math.random() * Math.PI * 2;
const velocity = Math.random() * 10;
sand.style.transform = `translate(${Math.cos(angle)*velocity}px, ${Math.sin(angle)*velocity}px)`;
canvas.appendChild(sand);
playSound();
}
// 颜色循环
currentColor = (currentColor + 1) % colors.length;
}
function playSound() {
const sound = document.getElementById('sound').cloneNode();
sound.volume = Math.random() * 0.3;
sound.play();
}
// 动态改变背景
let hue = 0;
setInterval(() => {
hue = (hue + 0.5) % 360;
canvas.style.background = `hsl(${hue}, 70%, 90%)`;
}, 50);
</script>
</body>
</html>
游戏特色和创新点:
- 动态沙画系统:
- 鼠标拖动生成彩色沙粒
- 自动渐隐效果
- 物理扩散动画
- 颜色自动循环变化
- 沉浸式体验:
- 缓慢变化的背景色
- 随机旋转的背景图案
- 粒子碰撞物理效果
- 混合叠加模式模拟真实沙画
- 感官反馈:
- 内嵌的沙粒摩擦音效(模拟真实沙子声音)
- 平滑的颜色过渡
- 清空画布时的瞬间解压感
- 创新交互:
- 按住鼠标可连续作画
- 清空按钮提供"一键重置"的爽快感
- 自动生成的背景动态元素
- 随机扩散方向模拟真实沙粒洒落
- 技术亮点:
- 纯CSS物理动画
- 动态背景色变化
- 内嵌SVG图案
- 自包含音频资源
- 自动内存管理(渐隐后自动移除元素)
玩法说明:
- 在画布区域按住鼠标拖动绘制
- 观察彩色沙粒的物理扩散效果
- 点击清空按钮重置画布
- 感受背景色和图案的缓慢变化
- 体验不同颜色叠加的混合效果