Paint App
Simple canvas painting application
by Ben Gillbanks
HTML
<div class="canvas-wrapper">
<canvas id="imageCanvas" width="400" height="400"></canvas>
<canvas id="drawCanvas" width="400" height="400"></canvas>
</div>
<div class="tools">
<button>Paint</button>
<button>Fill</button>
</div>
CSS
body {
margin: 0;
padding: 0;
}
.canvas-wrapper {
position: relative;
border: 1px solid #000;
height: 400px;
width: 400px;
}
.canvas-wrapper canvas {
position: absolute;
}
.canvas-wrapper #imageCanvas {
pointer-events: none;
}
JavaScript
const config = {
lineWidth: 5,
lineCap: 'round',
lineJoin: 'round',
strokeColor: '#000',
};
const canvas = document.getElementById('drawCanvas');
const imageCanvas = document.getElementById('imageCanvas');
const context = canvas.getContext('2d');
const imageContext = imageCanvas.getContext('2d');
let painting = false;
let points = [];
const minDistance = 5;
function startPosition(e) {
painting = true;
points = [];
draw(e);
}
function endPosition(e) {
draw(e);
imageContext.drawImage( canvas, 0, 0 );
clearCanvas();
painting = false;
}
function calculateDistance(point1, point2) {
const deltaX = point2.x - point1.x;
const deltaY = point2.y - point1.y;
return Math.sqrt(deltaX ** 2 + deltaY ** 2);
}
function draw(e) {
if (!painting) return;
const rect = canvas.getBoundingClientRect();
const currentPoint = { x: e.clientX - rect.left, y: e.clientY - rect.top };
//const currentPoint = { x: e.clientX - canvas.offsetLeft, y: e.clientY - canvas.offsetTop };
if (points.length > 0 && calculateDistance(currentPoint, points[points.length - 1]) < minDistance) {
return;
}
clearCanvas();
points.push(currentPoint);
context.lineWidth = config.lineWidth;
context.lineCap = config.lineCap;
context.lineJoin = config.lineJoin;
context.strokeStyle = config.strokeColor;
context.beginPath();
context.moveTo(points[0].x, points[0].y);
if ( 1 === points.length ) {
context.lineTo(points[0].x, points[0].y);
} else {
for (let i = 1; i < points.length - 2; i++) {
const c = (points[i].x + points[i + 1].x) / 2;
const d = (points[i].y + points[i + 1].y) / 2;
context.quadraticCurveTo(points[i].x, points[i].y, c, d);
}
context.quadraticCurveTo(
points[points.length - 2].x,
points[points.length - 2].y,
points[points.length - 1].x,
points[points.length - 1].y
);
}
context.stroke();
}
function clearCanvas() {
...