← back to Model Arena
data/artifacts/10c3c876aa67/qwen3-14b.html
130 lines
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Fractal Tree</title>
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background: #222;
height: 100%;
width: 100%;
}
canvas {
display: block;
}
#slider {
position: absolute;
top: 10px;
left: 10px;
width: 200px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<input type="range" id="slider" min="1" max="10" value="5">
<script>
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const slider = document.getElementById('slider');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
let depth = 5;
let wind = 0;
let frame = 0;
function resize() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
}
window.addEventListener('resize', resize);
resize();
const leaves = [];
const leafCount = 100;
function createLeaf() {
const leaf = {
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: Math.random() * 4 + 2,
alpha: 1,
fallSpeed: Math.random() * 0.5 + 0.2,
rotation: Math.random() * Math.PI * 2,
angleSpeed: (Math.random() - 0.5) * 0.05
};
leaves.push(leaf);
}
for (let i = 0; i < leafCount; i++) {
createLeaf();
}
function drawLeaf(leaf) {
ctx.save();
ctx.translate(leaf.x, leaf.y);
ctx.rotate(leaf.rotation);
ctx.fillStyle = `rgba(34, 139, 34, ${leaf.alpha})`;
ctx.beginPath();
ctx.arc(0, 0, leaf.size, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
leaf.y += leaf.fallSpeed;
leaf.rotation += leaf.angleSpeed;
leaf.alpha -= 0.005;
if (leaf.alpha <= 0) {
createLeaf();
}
}
function drawTree(x, y, length, angle, branchWidth, branchDepth) {
if (branchDepth === 0) return;
const newX = x + Math.cos(angle) * length;
const newY = y + Math.sin(angle) * length;
const newAngle = angle + (Math.random() - 0.5) * 0.3 + wind * 0.1;
const newLength = length * 0.7;
const newBranchWidth = branchWidth * 0.7;
const newBranchDepth = branchDepth - 1;
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(newX, newY);
ctx.strokeStyle = `hsl(${(frame % 255) + 120}, 80%, 50%)`;
ctx.lineWidth = branchWidth;
ctx.stroke();
if (branchDepth > 2 && Math.random() < 0.3) {
ctx.fillStyle = `hsl(${(frame % 255) + 120}, 80%, 50%)`;
ctx.beginPath();
ctx.arc(newX, newY, 8, 0, Math.PI * 2);
ctx.fill();
}
drawTree(newX, newY, newLength, newAngle, newBranchWidth, newBranchDepth);
drawTree(newX, newY, newLength, newAngle - 0.3, newBranchWidth, newBranchDepth);
drawTree(newX, newY, newLength, newAngle + 0.3, newBranchWidth, newBranchDepth);
}
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
wind = Math.sin(frame * 0.01) * 0.1;
drawTree(canvas.width / 2, canvas.height - 50, 100, -Math.PI / 2, 10, depth);
leaves.forEach(drawLeaf);
frame++;
requestAnimationFrame(animate);
}
slider.addEventListener('input', () => {
depth = parseInt(slider.value);
});
animate();
</script>
</body>
</html>