<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5不断繁衍的花动画特效</title>
<style>
body {
margin: 0;
padding: 0;
overflow: hidden;
background: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
canvas {
display: block;
position: absolute;
top: 0;
left: 0;
}
.hidden-link {
position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);
color: rgba(255, 255, 255, 0.3);
font-size: 12px;
text-decoration: none;
z-index: 100;
font-family: Arial, sans-serif;
}
</style>
</head>
<body>
<canvas id="flowerCanvas"></canvas>
<script>
const canvas = document.getElementById('flowerCanvas');
const ctx = canvas.getContext('2d');
// 设置画布大小为窗口大小
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
// 花朵数组
const flowers = [];
const colors = [
'#FF5F5F', '#FF9F5F', '#FFDF5F',
'#5FFF5F', '#5FDFFF', '#5F5FFF',
'#DF5FFF', '#FF5FDF'
];
// 花朵类
class Flower {
constructor(x, y, size, color, petals, angle) {
this.x = x;
this.y = y;
this.size = size;
this.color = color;
this.petals = petals;
this.angle = angle || 0;
this.growthRate = 0.5 + Math.random() * 2;
this.maxSize = 20 + Math.random() * 50;
this.children = [];
this.branchAngle = Math.random() * Math.PI * 2;
this.branchTimer = 100 + Math.random() * 200;
this.age = 0;
this.lifespan = 500 + Math.random() * 1000;
}
update() {
// 生长
if (this.size < this.maxSize) {
this.size += this.growthRate * 0.1;
}
// 旋转
this.angle += 0.005;
// 繁殖计时
this.branchTimer--;
this.age++;
// 如果达到繁殖时间且未达到最大数量
if (this.branchTimer <= 0 && flowers.length < 150 && this.age < this.lifespan) {
this.branch();
this.branchTimer = 100 + Math.random() * 200;
}
// 更新子花朵
this.children.forEach(child => child.update());
// 死亡
if (this.age >= this.lifespan) {
this.size *= 0.98;
if (this.size < 1) {
const index = flowers.indexOf(this);
if (index > -1) {
flowers.splice(index, 1);
}
}
}
}
branch() {
// 创建新花朵
const distance = 30 + Math.random() * 50;
const angle = this.branchAngle + (Math.random() - 0.5) * Math.PI / 2;
const newX = this.x + Math.cos(angle) * distance;
const newY = this.y + Math.sin(angle) * distance;
// 确保新花朵在画布内
if (newX > 0 && newX < canvas.width && newY > 0 && newY < canvas.height) {
const newFlower = new Flower(
newX,
newY,
5,
colors[Math.floor(Math.random() * colors.length)],
5 + Math.floor(Math.random() * 5),
angle
);
flowers.push(newFlower);
this.children.push(newFlower);
// 改变下一次的分支角度
this.branchAngle += Math.PI / 4 + (Math.random() - 0.5) * Math.PI / 2;
}
}
draw() {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angle);
// 绘制花瓣
for (let i = 0; i < this.petals; i++) {
const angle = (i * (Math.PI * 2 / this.petals));
ctx.beginPath();
ctx.ellipse(
Math.cos(angle) * this.size * 0.8,
Math.sin(angle) * this.size * 0.8,
this.size * 0.6,
this.size * 0.3,
angle,
0,
Math.PI * 2
);
ctx.fillStyle = this.color;
ctx.fill();
}
// 绘制花蕊
ctx.beginPath();
ctx.arc(0, 0, this.size * 0.3, 0, Math.PI * 2);
ctx.fillStyle = '#FFDF00';
ctx.fill();
ctx.restore();
// 绘制子花朵
this.children.forEach(child => child.draw());
}
}
// 初始花朵
function initFlowers() {
for (let i = 0; i < 3; i++) {
flowers.push(new Flower(
canvas.width / 2 + (Math.random() - 0.5) * 100,
canvas.height / 2 + (Math.random() - 0.5) * 100,
5,
colors[Math.floor(Math.random() * colors.length)],
5 + Math.floor(Math.random() * 5)
));
}
}
// 动画循环
function animate() {
// 半透明背景创造拖尾效果
ctx.fillStyle = 'rgba(0, 0, 0, 0.05)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 更新和绘制所有花朵
flowers.forEach(flower => {
flower.update();
flower.draw();
});
// 如果花朵数量太少,添加新的
if (flowers.length < 3) {
initFlowers();
}
requestAnimationFrame(animate);
}
// 处理窗口大小变化
window.addEventListener('resize', () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
});
// 点击添加新花朵
canvas.addEventListener('click', (e) => {
flowers.push(new Flower(
e.clientX,
e.clientY,
5,
colors[Math.floor(Math.random() * colors.length)],
5 + Math.floor(Math.random() * 5)
));
});
// 初始化并开始动画
initFlowers();
animate();
</script>
</body>
</html>
486

被折叠的 条评论
为什么被折叠?



