diff --git a/assets/images/logo.png b/assets/images/logo.png new file mode 100644 index 0000000..4f06be8 Binary files /dev/null and b/assets/images/logo.png differ diff --git a/index.html b/index.html index 801d84a..de0d9e7 100644 --- a/index.html +++ b/index.html @@ -3,59 +3,102 @@ - DrawBoard - + + + + + + + + + + + + + + + + + + + + + + + + + + DrawBoard + -
+
- +
+ +
+ + diff --git a/main.js b/main.js index 7c0e9a6..d1e3d70 100644 --- a/main.js +++ b/main.js @@ -1,108 +1,143 @@ const canvas = document.getElementById("canvas"); +const sizeElement = document.getElementById("size"); +const colorElement = document.getElementById("color"); +const clearElement = document.getElementById("clear"); +const increaseButton = document.getElementById("increase"); +const decreaseButton = document.getElementById("decrease"); +const redoButton = document.getElementById("redo"); +const undoButton = document.getElementById("undo"); const ctx = canvas.getContext("2d"); -function setUpCanvas() { - const canvas = document.getElementById("canvas"); - const ctx = canvas.getContext("2d"); - ctx.translate(0.5, 0.5); - var sizeWidth = (100 * window.innerWidth) / 100 - 60, - sizeHeight = (100 * window.innerHeight) / 100 || 766; - canvas.width = sizeWidth; - canvas.height = sizeHeight; - canvas.style.width = sizeWidth; - canvas.style.height = sizeHeight; -} -window.onload = setUpCanvas(); -const sizeEl = document.getElementById("size"); -const colorEl = document.getElementById("color"); -const clearEl = document.getElementById("clear"); -const increaseBtn = document.getElementById("increase"); -const decreaseBtn = document.getElementById("decrease"); +// Resize the canvas +function resizeCanvas() { + canvas.width = window.innerWidth - 170; + canvas.height = window.innerHeight - 40; +} +window.addEventListener("resize", resizeCanvas); +resizeCanvas(); -let size = 1; -let x = undefined; -let y = undefined; let color = "black"; -let isPressed = false; - -canvas.addEventListener("mousedown", (e) => { - isPressed = true; - x = e.offsetX; - y = e.offsetY; +// Update the Color of the brush +colorElement.addEventListener("change", (e) => { + color = e.target.value; }); -canvas.addEventListener("mouseup", () => { - isPressed = false; - - x = undefined; - y = undefined; -}); +let size = 1; +// Update the size of the brush on the screen using input Field function updateValue(e) { const newSize = parseInt(e.target.value, 10); - // Check if parsing was successful and newSize is a valid integer if (!isNaN(newSize)) { size = newSize; - sizeEl.value = size; + sizeElement.value = size; } else { console.log("Invalid input. Please enter a numeric value."); } } -canvas.addEventListener("mousemove", (e) => { - if (isPressed) { - const x2 = e.offsetX; - const y2 = e.offsetY; - - drawCircle(x2, y2); - drawLine(x, y, x2, y2); - x = x2; - y = y2; - } -}); - -function drawCircle(x, y) { - ctx.beginPath(); - ctx.arc(x, y, size, 0, Math.PI * 2); - ctx.fillStyle = color; - ctx.fill(); -} - -function drawLine(x1, y1, x2, y2) { - ctx.beginPath(); - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.strokeStyle = color; - ctx.lineWidth = size * 2; - ctx.stroke(); -} - -increaseBtn.addEventListener("click", () => { +// Increase and decrease the size of the brush using buttons +increaseButton.addEventListener("click", () => { size += 1; if (size > 50) { size = 50; } - sizeEl.value = size; + sizeElement.value = size; updateSizeOnScreen(); }); -decreaseBtn.addEventListener("click", () => { +decreaseButton.addEventListener("click", () => { size -= 1; if (size < 1) { size = 1; } - sizeEl.value = size; + sizeElement.value = size; updateSizeOnScreen(); }); -colorEl.addEventListener("change", (e) => { - color = e.target.value; +// Drawing Constraints +let isDrawing = false; +let lines = []; +let undoStack = []; +let points = []; +var mouse = { x: 0, y: 0 }; +var previous = { x: 0, y: 0 }; + +// Drawing Functionality +canvas.addEventListener("mousedown", (e) => { + isDrawing = true; + previous = { x: mouse.x, y: mouse.y }; + mouse = mousePos(canvas, e); + points = []; + points.push({ x: mouse.x, y: mouse.y }); +}); + +canvas.addEventListener("mousemove", (e) => { + if (isDrawing) { + previous = { x: mouse.x, y: mouse.y }; + mouse = mousePos(canvas, e); + points.push({ x: mouse.x, y: mouse.y }); + ctx.beginPath(); + ctx.moveTo(previous.x, previous.y); + ctx.lineTo(mouse.x, mouse.y); + ctx.strokeStyle = color; + ctx.lineWidth = size; + ctx.lineCap = "round"; + ctx.stroke(); + } +}); + +canvas.addEventListener("mouseup", (e) => { + isDrawing = false; + lines.push(points); + console.log(lines); }); -clearEl.addEventListener("click", () => { +// Helps to clear everything on the canvas +clearElement.addEventListener("click", () => { ctx.clearRect(0, 0, canvas.width, canvas.height); }); + +// Undo Redo Event Listeners +undoButton.addEventListener("click", Undo); +redoButton.addEventListener("click", redo); + +// Function to find the mouse position +function mousePos(canvas, e) { + var ClientRect = canvas.getBoundingClientRect(); + return { + x: Math.round(e.clientX - ClientRect.left), + y: Math.round(e.clientY - ClientRect.top), + }; +} + +// Function to draw the paths again on the canvas +function drawPaths() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + lines.forEach((path) => { + ctx.beginPath(); + ctx.moveTo(path[0].x, path[0].y); + for (let i = 1; i < path.length; i++) { + ctx.lineTo(path[i].x, path[i].y); + } + ctx.strokeStyle = color; + ctx.lineWidth = size; + ctx.lineCap = "round"; + ctx.stroke(); + }); +} + +// Undo Redo Functionality +function Undo() { + if (lines.length === 0) return; + undoStack.push(lines.pop()); + drawPaths(); +} +function redo() { + if (undoStack.length === 0) return; + lines.push(undoStack.pop()); + drawPaths(); +} diff --git a/style.css b/style.css index ba8ecd4..d7f378f 100644 --- a/style.css +++ b/style.css @@ -1,79 +1,117 @@ -@import url("https://fonts.googleapis.com/css2?family=Poppins:wght@200;400;600&display=swap"); - +/* CSS Reset */ * { margin: 0; padding: 0; box-sizing: border-box; } +/* Body */ body { + font-family: "Poppins", sans-serif; + background: url(https://source.unsplash.com/E8Ufcyxz514/2400x1823) no-repeat + center center/cover; + text-align: center; +} + +/* Outer container */ +.container { + padding: 20px; display: flex; - height: 100vh; - align-items: center; justify-content: center; - margin: 0; - font-family: "Poppins", sans-serif; + align-items: center; + height: 100vh; + width: 100vw; } -.tooltip { - position: relative; - display: inline-block; - border-bottom: 1px dotted black; + +/* Sidebar */ +.sidebar { + max-width: 120px; + margin: 20px 0px; + margin-right: 20px; + height: 100%; + padding: 5px; + display: flex; + flex-direction: column; + justify-content: space-between; + align-items: center; + border: 1px solid rgba(255, 255, 255, 0.25); + border-radius: 20px; + background-color: rgba(0, 0, 0, 0.15); + box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.25); + backdrop-filter: blur(15px); + z-index: 2; } +/* Label */ .tooltip .tooltiptext { visibility: hidden; width: 120px; - background-color: black; + background-color: rgba(38, 70, 83, 0.7); color: #fff; - text-align: center; border-radius: 6px; padding: 5px 0; - - /* Position the tooltip */ position: absolute; - z-index: 1; + z-index: 2; } - .tooltip:hover .tooltiptext { visibility: visible; } -.enclosed { +/* Size field Container */ +.size { display: flex; - width: 100%; - height: 100%; + justify-content: center; + align-items: center; + margin: 20px 0; } -.sidebar { - background-color: #393e40; +/* Increase and Decrease Button */ +#increase, +#decrease { + width: 35px; + height: 30px; + font-size: 20px; + background-color: rgba(173, 181, 189, 0.5); + border: none; color: white; - padding: 20px 0px; - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-between; + transition: border-color 0.3s; } -.toolbox { - display: flex; - flex-direction: column; - align-items: center; - gap: 10px; - width: 60px; +#increase:hover, +#decrease:hover { + border: 1px solid white; } -.toolbox div { - display: block; + +#increase { + border-top-right-radius: 10px; + border-bottom-right-radius: 10px; } -canvas { - background-color: #efefef; - border: 2px solid #000000; + +#decrease { + border-top-left-radius: 10px; + border-bottom-left-radius: 10px; } -.color-picker { + +/* Size Input Field */ +.input-field { + width: 30px; + height: 30px; border: none; + outline: none; + color: white; + font-size: 20px; + text-align: center; + transition: border-color 0.3s; + background-color: rgba(173, 181, 189, 0.5); } -input[type="color"] { + +/* To remove the arrow up/down from the size input field */ +.input-field::-webkit-inner-spin-button, +.input-field::-webkit-outer-spin-button { -webkit-appearance: none; - appearance: none; +} + +.color-picker { border: none; width: 32px; height: 32px; @@ -84,26 +122,36 @@ input[type="color"]::-webkit-color-swatch-wrapper { input[type="color"]::-webkit-color-swatch { border: none; } -.toolbox div { - display: block; -} -#redo, -#undo { +button { + font-size: 20px; background-color: transparent; border: none; color: white; - padding: 5px 0px; } -#increase, -#decrease, + #clear { font-size: 20px; background-color: transparent; border: none; color: white; - padding: 5px 5px; } -.text-center { - text-align: center; + +.toolbox { + display: flex; + flex-direction: column; + justify-content: flex-end; + gap: 20px; + align-items: center; + margin-bottom: 20px; + height: 100%; +} + +canvas { + border: 1px solid rgba(255, 255, 255, 0.25); + border-radius: 20px; + background-color: rgba(0, 0, 0, 0.15); + box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.25); + backdrop-filter: blur(15px); + z-index: 1; }