<div class="container"> <h1>Canvas Drawing App</h1> <div class="toolbar"> <div class="tool-group"> <label>Color:</label> <input type="color" id="colorPicker" class="color-picker" value="#000000"> </div> <div class="divider"></div> <div class="tool-group"> <label>Size:</label> <input type="range" id="sizeSlider" class="size-slider" min="1" max="50" value="5"> <span class="size-value" id="sizeValue">5px</span> </div> <div class="divider"></div> <button class="btn btn-secondary" id="clearBtn">Clear Canvas</button> <button class="btn btn-primary" id="downloadBtn">Download</button> </div> <div class="canvas-wrapper"> <canvas id="drawingCanvas" width="850" height="500"></canvas> </div> </div>
* { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); min-height: 100vh; display: flex; align-items: center; justify-content: center; padding: 20px; } .container { background: white; border-radius: 12px; padding: 24px; box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3); max-width: 900px; width: 100%; } h1 { font-size: 24px; color: #2d3748; margin-bottom: 20px; text-align: center; } .toolbar { display: flex; gap: 12px; margin-bottom: 20px; flex-wrap: wrap; align-items: center; padding: 16px; background: #f7fafc; border-radius: 8px; } .tool-group { display: flex; align-items: center; gap: 8px; } .tool-group label { font-size: 14px; color: #4a5568; font-weight: 600; } .color-picker { width: 50px; height: 40px; border: 2px solid #e2e8f0; border-radius: 6px; cursor: pointer; transition: all 0.2s; } .color-picker:hover { border-color: #4facfe; transform: scale(1.05); } .size-slider { width: 120px; height: 6px; border-radius: 3px; background: #e2e8f0; outline: none; cursor: pointer; } .size-slider::-webkit-slider-thumb { appearance: none; width: 18px; height: 18px; border-radius: 50%; background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); cursor: pointer; transition: all 0.2s; } .size-slider::-webkit-slider-thumb:hover { transform: scale(1.2); } .size-value { font-size: 14px; color: #2d3748; font-weight: 600; min-width: 30px; } .btn { padding: 10px 18px; border: none; border-radius: 6px; font-size: 14px; font-weight: 600; cursor: pointer; transition: all 0.2s; } .btn-primary { background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; } .btn-primary:hover { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(79, 172, 254, 0.4); } .btn-secondary { background: #e2e8f0; color: #4a5568; } .btn-secondary:hover { background: #cbd5e0; } .btn:active { transform: translateY(0); } .canvas-wrapper { border: 3px solid #e2e8f0; border-radius: 8px; overflow: hidden; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); background: white; cursor: crosshair; } canvas { display: block; touch-action: none; } .divider { width: 1px; height: 30px; background: #cbd5e0; margin: 0 4px; }
const canvas = document.getElementById('drawingCanvas'); const ctx = canvas.getContext('2d'); const colorPicker = document.getElementById('colorPicker'); const sizeSlider = document.getElementById('sizeSlider'); const sizeValue = document.getElementById('sizeValue'); const clearBtn = document.getElementById('clearBtn'); const downloadBtn = document.getElementById('downloadBtn'); let isDrawing = false; let lastX = 0; let lastY = 0; // Initialize canvas with white background ctx.fillStyle = 'white'; ctx.fillRect(0, 0, canvas.width, canvas.height); // Set default drawing style ctx.lineCap = 'round'; ctx.lineJoin = 'round'; function startDrawing(e) { isDrawing = true; const rect = canvas.getBoundingClientRect(); lastX = e.clientX - rect.left; lastY = e.clientY - rect.top; } function draw(e) { if (!isDrawing) return; const rect = canvas.getBoundingClientRect(); const currentX = e.clientX - rect.left; const currentY = e.clientY - rect.top; ctx.strokeStyle = colorPicker.value; ctx.lineWidth = sizeSlider.value; ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(currentX, currentY); ctx.stroke(); lastX = currentX; lastY = currentY; } function stopDrawing() { isDrawing = false; } function clearCanvas() { ctx.fillStyle = 'white'; ctx.fillRect(0, 0, canvas.width, canvas.height); } function downloadCanvas() { const link = document.createElement('a'); link.download = 'drawing.png'; link.href = canvas.toDataURL(); link.click(); } // Mouse events canvas.addEventListener('mousedown', startDrawing); canvas.addEventListener('mousemove', draw); canvas.addEventListener('mouseup', stopDrawing); canvas.addEventListener('mouseout', stopDrawing); // Touch events for mobile canvas.addEventListener('touchstart', (e) => { e.preventDefault(); const touch = e.touches[0]; const mouseEvent = new MouseEvent('mousedown', { clientX: touch.clientX, clientY: touch.clientY }); canvas.dispatchEvent(mouseEvent); }); canvas.addEventListener('touchmove', (e) => { e.preventDefault(); const touch = e.touches[0]; const mouseEvent = new MouseEvent('mousemove', { clientX: touch.clientX, clientY: touch.clientY }); canvas.dispatchEvent(mouseEvent); }); canvas.addEventListener('touchend', (e) => { e.preventDefault(); const mouseEvent = new MouseEvent('mouseup', {}); canvas.dispatchEvent(mouseEvent); }); // Update size value display sizeSlider.addEventListener('input', () => { sizeValue.textContent = `${sizeSlider.value}px`; }); // Button events clearBtn.addEventListener('click', clearCanvas); downloadBtn.addEventListener('click', downloadCanvas);
Login to leave a comment
No comments yet. Be the first!
View Project
No comments yet. Be the first!