function midPointBtw(p1, p2) { return { x: p1.x + (p2.x - p1.x) / 2, y: p1.y + (p2.y - p1.y) / 2, }; } const brushSelect = document.querySelector("#size"), canvas = document.querySelector('#draw'), colorSelect = document.querySelector("#color-picker"), colors = document.querySelectorAll("#colors span"), /* resetButton = document.querySelector('#reset'), */ saveButton = document.querySelector("#save"), tools = document.querySelectorAll("#tools span"); /* canvas.height = window.innerHeight ; canvas.width = window.innerWidth * .9; //90% canvas width, 10% toolbar width */ var ctx = canvas.getContext('2d'); ctx.fillStyle = "rgba(0, 0, 0, 0)"; ctx.lineJoin = ctx.lineCap = "round"; ctx.lineWidth = 1; ctx.strokeStyle = "black"; /* ctx.fillRect(0, 0, canvas.width, canvas.height); */ const startingCanvas = canvas.toDataURL(); let brushSize = "5px", currentColor = "black", currentTool = "pencil", isDrawing = false, lastX = 0, lastY = 0, rect = ""; var points = []; var snapshot; const startDraw = (e) => { snapshot = ctx.getImageData(0, 0, canvas.width, canvas.height); console.log(e); isDrawing = true; points.push({ x: e.offsetX, y: e.offsetY }); }; const continuousDraw = (e) => { if (!isDrawing) return; points.push({ x: e.offsetX, y: e.offsetY }); ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.putImageData(snapshot, 0, 0); var p1 = points[0]; var p2 = points[1]; ctx.beginPath(); ctx.moveTo(p1.x, p1.y); console.log(points); for (var i = 1, len = points.length; i < len; i++) { // we pick the point between pi+1 & pi+2 as the // end point and p1 as our control point var midPoint = midPointBtw(p1, p2); ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y); p1 = points[i]; p2 = points[i + 1]; } // Draw last line as a straight line while // we wait for the next point to be able to calculate // the bezier control point ctx.lineTo(p1.x, p1.y); ctx.stroke(); }; //normal functions used here to preverse "this" from event listeners function changeColor() { currentColor = this.dataset.color; ctx.strokeStyle = currentTool !== "eraser" ? this.dataset.color : "white"; colors.forEach((color) => color === this ? color.classList.add("active-color") : color.classList.remove("active-color") ); } function colorPicker() { currentColor = this.value; ctx.strokeStyle = currentTool !== "eraser" ? this.value : "white"; colors.forEach((color) => color.classList.remove("active-color")); } //currently everything is setup to work with 3 tool types. If more tools are added, the conditionals will have to be reworked function setTool() { if (this.dataset.name === "pencil") { ctx.lineWidth = 1; currentTool = "pencil"; } else { ctx.lineWidth = brushSize > 1 ? brushSize : 5; currentTool = this.dataset.name === "eraser" ? "eraser" : "brush"; } tools.forEach((tool) => tool === this ? tool.classList.add("active-tool") : tool.classList.remove("active-tool") ); ctx.lineCap = this.dataset.name === "eraser" ? "square" : "round"; if (this.dataset.name === "eraser") { ctx.globalCompositeOperation = "destination-out"; //ctx.strokeStyle = "white"; } else { ctx.globalCompositeOperation = "source-over"; /* if(ctx.globalCompositeOperation == 'destination-out'){ ctx.globalCompositeOperation = 'source-in'; } */ ctx.strokeStyle = currentColor; } //ctx.strokeStyle = this.dataset.name === 'eraser' ? ctx.globalCompositeOperation = 'destination-out' : currentColor; } function downloadImage(e) { if (startingCanvas === canvas.toDataURL()) return e.preventDefault(); this.download = prompt("Please name your picture:"); if (this.download === "null") return e.preventDefault(); this.href = canvas.toDataURL("image/png"); } function reset() { if (startingCanvas === canvas.toDataURL()) return; if (!confirm("Are you sure you want to delete all of your work?")) return; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillRect(0, 0, canvas.width, canvas.height); } //toolbar event listeners brushSelect.addEventListener("click", () => { brushSize = brushSelect.value; ctx.lineWidth = currentTool === "pencil" ? 1 : brushSize; }); colorSelect.addEventListener("change", colorPicker); saveButton.addEventListener("click", downloadImage); /* resetButton.addEventListener('click', reset); */ tools.forEach((tool) => tool.addEventListener("click", setTool)); colors.forEach((color) => color.addEventListener("click", changeColor)); // canvas event listeners canvas.addEventListener('mousedown', startDraw); canvas.addEventListener('mousemove', continuousDraw); canvas.addEventListener('mouseup', () => {isDrawing = false; points.length = 0; }); canvas.addEventListener('touchstart', startDraw); canvas.addEventListener('touchmove', continuousDraw); canvas.addEventListener('touchend', () => {isDrawing = false; points.length = 0; });