So for a class project, I have to figure out the most efficient way to draw on a canvas.
First thing that came to mind was using moveTo and lineTo repeatedly following mouse cursor, and thats exactly what I did.
I also added a strange "liner" pen which draws lines outwards from a point (side effect of bug, which I then turned into a tool)
Furthermore I added a coloring and sizing option, so you can be creative with it.
Sizing option, Spray tool, and Color Options are all non-functional rn.
I'm not really sure how to get the color or sizing option working if anyone wants to take a crack at it.
I want to know if anyone sees any bad practice uses that I have created, or has any improvements/tips that I should keep in mind as I continue development on the canvas.
Also the GUI and Buttons and everything, its all temporary, my main job is to actually finish the project.
https://repl.it/@skylerspark/Dynamic-Drawing-Utility-DDU
Heres the live development version, and heres the current version as of posting this code review:
const query = document.querySelector.bind(document);
// Config
let curLine = [0, 0],
curColor = "#000000",
curSize = 2;
// Cursor Coords
function drawingBoardGetMouse(cvs, e) {
let rect = cvs.getBoundingClientRect(),
scaleX = cvs.width / rect.width,
scaleY = cvs.height / rect.height;
return {
x: (e.clientX - rect.left) * scaleX,
y: (e.clientY - rect.top) * scaleY
};
}
// Dynamic Drawing Utility (DDU)
class drawingBoard {
constructor(canvas) {
// Generate a dynamic canvas selector, or manually select it yourself via the main args
this.cvs = canvas || document.querySelector("canvas");
this.ctx = this.cvs.getContext("2d");
this.cvs.addEventListener("mousedown", e => {
let m = drawingBoardGetMouse(this.cvs, e);
curLine = [m.x, m.y];
this.mouseDown = true;
});
this.cvs.addEventListener("mouseup", e => {
this.mouseDown = false;
});
this.cvs.addEventListener("mousemove", this.onMouseMove.bind(this));
}
draw(e) { // Free Draw Pen
let m = drawingBoardGetMouse(this.cvs, e);
this.ctx.beginPath();
this.ctx.fillStyle = curColor;
this.ctx.lineWidth = curSize;
this.ctx.moveTo(curLine[0], curLine[1]);
this.ctx.lineTo(m.x, m.y);
this.ctx.stroke();
curLine = [m.x, m.y];
}
draw2(e) { // Line Draw Pen
let m = drawingBoardGetMouse(this.cvs, e);
this.ctx.beginPath();
this.ctx.fillStyle = curColor;
this.ctx.lineWidth = curSize;
this.ctx.moveTo(curLine[0], curLine[1]);
this.ctx.lineTo(m.x, m.y);
this.ctx.stroke();
}
onMouseMove(event) { // Detect movement
if (!this.mouseDown) {
return; // If mouse isnt held down, dont draw
}
if (this.drawingMode == 1) {
return this.draw(event); // Free-draw
} else if (this.drawingMode == 2) {
return this.draw2(event); // Line-draw
} else if (this.drawingMode == 3) {
return this.draw3(event); // Spray-draw
}
}
dragAndDraw() {
this.drawingMode = 1;
}
dragAndLine() {
this.drawingMode = 2;
}
dragAndSpray() {
this.drawingMode = 3;
}
}
// API Usage
const draw = new drawingBoard(); // Initialize new board
query(".color").addEventListener("input", e => {
curColor = e.target.value;
});
query(".drawer").addEventListener("click", () => {
draw.dragAndDraw();
});
query(".liner").addEventListener("click", () => {
draw.dragAndLine();
});
query(".sprayer").addEventListener("click", () => {
draw.dragAndSpray();
});
* {
text-align: center;
vertical-align: top;
box-sizing: border-box;
}
.canvas {
display: inline-block;
border: 1px solid black;
}
.buttons {
display: inline-block;
}
button,
input {
width: 8em;
margin-bottom: 2px;
margin-left: -2px;
}
input {
text-align: left;
}
<canvas class="canvas" width="300" height="300"></canvas>
<div class="buttons">
<input type="color" class="color"><br>
<input type="text" class="size" placeholder="Size"><br>
<button class="drawer">Free Draw</button><br>
<button class="liner">Line Draw</button><br>
<button class="sprayer">Spray Draw</button>
</div>