Pro Animation App (Prototype)
by Sharxxy
HTML
<header>🎨 Animation App (Prototype)</header>
<div id="toolbar">
Brush Color: <input type="color" id="colorPicker" value="#000000">
Brush Size: <input type="range" id="brushSize" min="1" max="20" value="5">
<button id="addFrame">➕ Add Frame</button>
<button id="play">▶ Play</button>
<button id="export">💾 Export PNGs</button>
</div>
<div id="main">
<div id="canvas-container">
<canvas id="drawCanvas" width="600" height="400"></canvas>
</div>
<div id="timeline"></div>
</div>
CSS
body {
margin: 0;
font-family: Arial, sans-serif;
background: #1e1e1e;
color: white;
display: flex;
flex-direction: column;
height: 100vh;
}
header {
padding: 10px;
background: #2d2d2d;
text-align: center;
font-weight: bold;
}
#toolbar {
background: #333;
padding: 8px;
display: flex;
gap: 10px;
align-items: center;
}
#toolbar input[type=color],
#toolbar input[type=range],
#toolbar button {
cursor: pointer;
}
#main {
flex: 1;
display: flex;
overflow: hidden;
}
#canvas-container {
flex: 3;
background: #222;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
canvas {
background: white;
border: 1px solid #555;
}
#timeline {
flex: 1;
background: #2d2d2d;
padding: 10px;
overflow-x: auto;
white-space: nowrap;
}
.frame {
display: inline-block;
width: 40px;
height: 40px;
margin: 2px;
background: #444;
border: 2px solid transparent;
cursor: pointer;
}
.frame.active {
border: 2px solid #00adee;
}
JavaScript
const canvas = document.getElementById('drawCanvas');
const ctx = canvas.getContext('2d');
let drawing = false;
let frames = [ctx.getImageData(0, 0, canvas.width, canvas.height)];
let currentFrame = 0;
// Timeline
const timeline = document.getElementById('timeline');
function renderTimeline() {
timeline.innerHTML = '';
frames.forEach((f, i) => {
const div = document.createElement('div');
div.className = 'frame' + (i === currentFrame ? ' active' : '');
div.onclick = () => {
currentFrame = i;
ctx.putImageData(frames[currentFrame], 0, 0);
renderTimeline();
};
timeline.appendChild(div);
});
}
renderTimeline();
// Drawing
const colorPicker = document.getElementById('colorPicker');
const brushSize = document.getElementById('brushSize');
canvas.addEventListener('mousedown', () => drawing = true);
canvas.addEventListener('mouseup', () => {
drawing = false;
frames[currentFrame] = ctx.getImageData(0, 0, canvas.width, canvas.height);
});
canvas.addEventListener('mousemove', (e) => {
if (!drawing) return;
ctx.fillStyle = colorPicker.value;
ctx.beginPath();
ctx.arc(e.offsetX, e.offsetY, brushSize.value, 0, Math.PI * 2);
ctx.fill();
});
// Add Frame
document.getElementById('addFrame').onclick = () => {
const blank = ctx.createImageData(canvas.width, canvas.height);
frames.push(blank);
currentFrame = frames.length - 1;
ctx.putImageData(blank, 0, 0);
renderTimeline();
};
// Play Animation
document.getElementById('play').onclick = () => {
let i = 0;
const interval = setInterval(() => {
ctx.putImageData(frames[i], 0, 0);
i++;
if (i >= frames.length) clearInterval(interval);
}, 200);
};
// Export PNGs
...