Canvas is a drawing app that provides a digital canvas for creating art. It includes tools such as an extensive color palette for both the brush and background, an eraser, size ranges for the brush and eraser, as well as convenient undo, redo, and clear buttons.
- Draw Freely: Utilize a brush tool for freehand drawing.
- Color Selection: Pick and change colors seamlessly with a color picker.
- Tool Variety: Choose between brush, eraser, and background (paint bucket) tools.
- Size Control: Adjust the size of the brush and eraser using a slider.
- Undo and Redo: Easily undo and redo actions for precise editing.
- Download Image: Save their canvas with a download button.
- Vanilla JS: Powers interactivity and logic.
- HTML: Defines the structure and layout of the Canvas app.
- CSS (Sass): Styles for a visually appealing user experience.
- Canvas API: Renders the canvas and enables drawing functionality.
- Pickr Library: Facilitates color picking.
- Webpack: Bundles and transpiles the JavaScript source code.
- npm: Manages project dependencies.
The Canvas app is built with a modular and organized structure, making it easy to understand and extend. Here are some key components of the implementation:
To change the background color in the Canvas app, the bgColorChange
method is used. This method also ensures that the paths drawn with the eraser tool have their color updated accordingly.
bgColorChange() {
const drawnPaths = this.canvasHandler.RedoAndUndoHandler.drawnPaths;
const redoStack = this.canvasHandler.RedoAndUndoHandler.redoStack;
this.canvasHandler.eraseAndClearHandler.clear();
this.canvasHandler.RedoAndUndoHandler.drawnPaths = drawnPaths;
this.canvasHandler.RedoAndUndoHandler.redoStack = redoStack;
drawnPaths.forEach((path) =>
this.canvasHandler.RedoAndUndoHandler.redrawPath(path)
);
this.canvasHandler.canvas.style.backgroundColor = this.bgColor;
}
In Canvas, the eraser tool is implemented using the isErase
attribute in the paths. When paths are redrawn, the redrawPath
method checks this attribute to determine whether a point should be treated as an eraser point. Here's how it works:
redrawPath(path) {
path.forEach((point, idx) => {
if (idx === 0) {
this.canvasHandler.ctx.beginPath();
this.canvasHandler.ctx.moveTo(point.x, point.y);
} else {
this.canvasHandler.ctx.lineTo(point.x, point.y);
if (path.isErase) {
point.color = this.canvasHandler.colorHandler.bgColor;
}
this.canvasHandler.brushHandler.setBrushStyling(
point.color,
point.brushSize
);
this.canvasHandler.ctx.stroke();
}
});
}