Close Menu

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    How to make Awesome Radar Animation using HTML & CSS

    8 May 2025

    How to create Cross Road Game using HTML CSS and JS

    2 May 2025

    How to create 3D Animated Bee website using HTML CSS and JS

    28 April 2025
    Facebook X (Twitter) Instagram YouTube Telegram Threads
    Coding StellaCoding Stella
    • Home
    • Blog
    • HTML & CSS
      • Login Form
    • JavaScript
    • Hire us!
    Coding StellaCoding Stella
    Home - JavaScript - How to make Drawing App / Paint App in HTML CSS & JavaScript
    JavaScript

    How to make Drawing App / Paint App in HTML CSS & JavaScript

    Coding StellaBy Coding Stella29 February 2024No Comments8 Mins Read
    Share Facebook Twitter Pinterest LinkedIn Tumblr Reddit Email WhatsApp Copy Link

    Let’s create a Drawing App using HTML, CSS, and JavaScript. This project is perfect for those who want to unleash their creativity while learning coding basics.

    We’ll keep it simple and fun, using HTML to set up the canvas, CSS for some basic styling, and JavaScript to handle the drawing functionality. No need for anything complex – just straightforward coding!

    Let’s dive into building this Drawing App. Whether you’re a beginner or looking for a creative coding challenge, let’s get started and let your imagination run wild on the digital canvas!

    HTML :

    The HTML code is a structure for a drawing app webpage. It includes sections for tools (shapes, options, colors), external styles and scripts, and a canvas for drawing. Tools are represented as list items with icons and labels. External resources include “style.css” for styling and “script.js” for interactive functionality.

    <!DOCTYPE html>
    <html lang="en" dir="ltr">
      <head>
        <meta charset="utf-8">
        <title>Drawing App JavaScript | codingstella</title>
        <link rel="stylesheet" href="style.css">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="script.js" defer></script>
      </head>
      <body>
        <div class="container">
          <section class="tools-board">
            <div class="row">
              <label class="title">Shapes</label>
              <ul class="options">
                <li class="option tool" id="rectangle">
                  <img src="icons/rectangle.svg" alt="">
                  <span>Rectangle</span>
                </li>
                <li class="option tool" id="circle">
                  <img src="icons/circle.svg" alt="">
                  <span>Circle</span>
                </li>
                <li class="option tool" id="triangle">
                  <img src="icons/triangle.svg" alt="">
                  <span>Triangle</span>
                </li>
                <li class="option">
                  <input type="checkbox" id="fill-color">
                  <label for="fill-color">Fill color</label>
                </li>
              </ul>
            </div>
            <div class="row">
              <label class="title">Options</label>
              <ul class="options">
                <li class="option active tool" id="brush">
                  <img src="icons/brush.svg" alt="">
                  <span>Brush</span>
                </li>
                <li class="option tool" id="eraser">
                  <img src="icons/eraser.svg" alt="">
                  <span>Eraser</span>
                </li>
                <li class="option">
                  <input type="range" id="size-slider" min="1" max="30" value="5">
                </li>
              </ul>
            </div>
            <div class="row colors">
              <label class="title">Colors</label>
              <ul class="options">
                <li class="option"></li>
                <li class="option selected"></li>
                <li class="option"></li>
                <li class="option"></li>
                <li class="option">
                  <input type="color" id="color-picker" value="#4A98F7">
                </li>
              </ul>
            </div>
            <div class="row buttons">
              <button class="clear-canvas">Clear Canvas</button>
              <button class="save-img">Save As Image</button>
            </div>
          </section>
          <section class="drawing-board">
            <canvas></canvas>
          </section>
        </div>
        
      </body>
    </html>

    CSS :

    The CSS code imports the “Poppins” font and sets global styles like resetting margins and defining the default font family. It styles sections of the webpage, including backgrounds, borders, and interactive elements within the tools board, rows, options, and color choices.

    /* Import Google font - Poppins */
    @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap');
    *{
      margin: 0;
      padding: 0;
      box-sizing: border-box;
      font-family: 'Poppins', sans-serif;
    }
    body{
      display: flex;
      align-items: center;
      justify-content: center;
      min-height: 100vh;
      background: #4A98F7;
    }
    .container{
      display: flex;
      width: 100%;
      gap: 10px;
      padding: 10px;
      max-width: 1050px;
    }
    section{
      background: #fff;
      border-radius: 7px;
    }
    .tools-board{
      width: 210px;
      padding: 15px 22px 0;
    }
    .tools-board .row{
      margin-bottom: 20px;
    }
    .row .options{
      list-style: none;
      margin: 10px 0 0 5px;
    }
    .row .options .option{
      display: flex;
      cursor: pointer;
      align-items: center;
      margin-bottom: 10px;
    }
    .option:is(:hover, .active) img{
      filter: invert(17%) sepia(90%) saturate(3000%) hue-rotate(900deg) brightness(100%) contrast(100%);
    }
    .option :where(span, label){
      color: #5A6168;
      cursor: pointer;
      padding-left: 10px;
    }
    .option:is(:hover, .active) :where(span, label){
      color: #4A98F7;
    }
    .option #fill-color{
      cursor: pointer;
      height: 14px;
      width: 14px;
    }
    #fill-color:checked ~ label{
      color: #4A98F7;
    }
    .option #size-slider{
      width: 100%;
      height: 5px;
      margin-top: 10px;
    }
    .colors .options{
      display: flex;
      justify-content: space-between;
    }
    .colors .option{
      height: 20px;
      width: 20px;
      border-radius: 50%;
      margin-top: 3px;
      position: relative;
    }
    .colors .option:nth-child(1){
      background-color: #fff;
      border: 1px solid #bfbfbf;
    }
    .colors .option:nth-child(2){
      background-color: #000;
    }
    .colors .option:nth-child(3){
      background-color: #E02020;
    }
    .colors .option:nth-child(4){
      background-color: #6DD400;
    }
    .colors .option:nth-child(5){
      background-color: #4A98F7;
    }
    .colors .option.selected::before{
      position: absolute;
      content: "";
      top: 50%;
      left: 50%;
      height: 12px;
      width: 12px;
      background: inherit;
      border-radius: inherit;
      border: 2px solid #fff;
      transform: translate(-50%, -50%);
    }
    .colors .option:first-child.selected::before{
      border-color: #ccc;
    }
    .option #color-picker{
      opacity: 0;
      cursor: pointer;
    }
    .buttons button{
      width: 100%;
      color: #fff;
      border: none;
      outline: none;
      padding: 11px 0;
      font-size: 0.9rem;
      margin-bottom: 13px;
      background: none;
      border-radius: 4px;
      cursor: pointer;
    }
    .buttons .clear-canvas{
      color: #6C757D;
      border: 1px solid #6C757D;
      transition: all 0.3s ease;
    }
    .clear-canvas:hover{
      color: #fff;
      background: #6C757D;
    }
    .buttons .save-img{
      background: #4A98F7;
      border: 1px solid #4A98F7;
    }
    .drawing-board{
      flex: 1;
      overflow: hidden;
    }
    .drawing-board canvas{
      width: 100%;
      height: 100%;
    }

    JavaScript:

    The JavaScript code initializes variables and sets up event listeners for a drawing app. It handles user interactions like selecting tools, adjusting brush size, choosing colors, clearing the canvas, and saving images. Overall, it provides interactive drawing features for the webpage.

    const canvas = document.querySelector("canvas"),
    toolBtns = document.querySelectorAll(".tool"),
    fillColor = document.querySelector("#fill-color"),
    sizeSlider = document.querySelector("#size-slider"),
    colorBtns = document.querySelectorAll(".colors .option"),
    colorPicker = document.querySelector("#color-picker"),
    clearCanvas = document.querySelector(".clear-canvas"),
    saveImg = document.querySelector(".save-img"),
    ctx = canvas.getContext("2d");
    
    // global variables with default value
    let prevMouseX, prevMouseY, snapshot,
    isDrawing = false,
    selectedTool = "brush",
    brushWidth = 5,
    selectedColor = "#000";
    
    const setCanvasBackground = () => {
        // setting whole canvas background to white, so the downloaded img background will be white
        ctx.fillStyle = "#fff";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = selectedColor; // setting fillstyle back to the selectedColor, it'll be the brush color
    }
    
    window.addEventListener("load", () => {
        // setting canvas width/height.. offsetwidth/height returns viewable width/height of an element
        canvas.width = canvas.offsetWidth;
        canvas.height = canvas.offsetHeight;
        setCanvasBackground();
    });
    
    const drawRect = (e) => {
        // if fillColor isn't checked draw a rect with border else draw rect with background
        if(!fillColor.checked) {
            // creating circle according to the mouse pointer
            return ctx.strokeRect(e.offsetX, e.offsetY, prevMouseX - e.offsetX, prevMouseY - e.offsetY);
        }
        ctx.fillRect(e.offsetX, e.offsetY, prevMouseX - e.offsetX, prevMouseY - e.offsetY);
    }
    
    const drawCircle = (e) => {
        ctx.beginPath(); // creating new path to draw circle
        // getting radius for circle according to the mouse pointer
        let radius = Math.sqrt(Math.pow((prevMouseX - e.offsetX), 2) + Math.pow((prevMouseY - e.offsetY), 2));
        ctx.arc(prevMouseX, prevMouseY, radius, 0, 2 * Math.PI); // creating circle according to the mouse pointer
        fillColor.checked ? ctx.fill() : ctx.stroke(); // if fillColor is checked fill circle else draw border circle
    }
    
    const drawTriangle = (e) => {
        ctx.beginPath(); // creating new path to draw circle
        ctx.moveTo(prevMouseX, prevMouseY); // moving triangle to the mouse pointer
        ctx.lineTo(e.offsetX, e.offsetY); // creating first line according to the mouse pointer
        ctx.lineTo(prevMouseX * 2 - e.offsetX, e.offsetY); // creating bottom line of triangle
        ctx.closePath(); // closing path of a triangle so the third line draw automatically
        fillColor.checked ? ctx.fill() : ctx.stroke(); // if fillColor is checked fill triangle else draw border
    }
    
    const startDraw = (e) => {
        isDrawing = true;
        prevMouseX = e.offsetX; // passing current mouseX position as prevMouseX value
        prevMouseY = e.offsetY; // passing current mouseY position as prevMouseY value
        ctx.beginPath(); // creating new path to draw
        ctx.lineWidth = brushWidth; // passing brushSize as line width
        ctx.strokeStyle = selectedColor; // passing selectedColor as stroke style
        ctx.fillStyle = selectedColor; // passing selectedColor as fill style
        // copying canvas data & passing as snapshot value.. this avoids dragging the image
        snapshot = ctx.getImageData(0, 0, canvas.width, canvas.height);
    }
    
    const drawing = (e) => {
        if(!isDrawing) return; // if isDrawing is false return from here
        ctx.putImageData(snapshot, 0, 0); // adding copied canvas data on to this canvas
    
        if(selectedTool === "brush" || selectedTool === "eraser") {
            // if selected tool is eraser then set strokeStyle to white 
            // to paint white color on to the existing canvas content else set the stroke color to selected color
            ctx.strokeStyle = selectedTool === "eraser" ? "#fff" : selectedColor;
            ctx.lineTo(e.offsetX, e.offsetY); // creating line according to the mouse pointer
            ctx.stroke(); // drawing/filling line with color
        } else if(selectedTool === "rectangle"){
            drawRect(e);
        } else if(selectedTool === "circle"){
            drawCircle(e);
        } else {
            drawTriangle(e);
        }
    }
    
    toolBtns.forEach(btn => {
        btn.addEventListener("click", () => { // adding click event to all tool option
            // removing active class from the previous option and adding on current clicked option
            document.querySelector(".options .active").classList.remove("active");
            btn.classList.add("active");
            selectedTool = btn.id;
        });
    });
    
    sizeSlider.addEventListener("change", () => brushWidth = sizeSlider.value); // passing slider value as brushSize
    
    colorBtns.forEach(btn => {
        btn.addEventListener("click", () => { // adding click event to all color button
            // removing selected class from the previous option and adding on current clicked option
            document.querySelector(".options .selected").classList.remove("selected");
            btn.classList.add("selected");
            // passing selected btn background color as selectedColor value
            selectedColor = window.getComputedStyle(btn).getPropertyValue("background-color");
        });
    });
    
    colorPicker.addEventListener("change", () => {
        // passing picked color value from color picker to last color btn background
        colorPicker.parentElement.style.background = colorPicker.value;
        colorPicker.parentElement.click();
    });
    
    clearCanvas.addEventListener("click", () => {
        ctx.clearRect(0, 0, canvas.width, canvas.height); // clearing whole canvas
        setCanvasBackground();
    });
    
    saveImg.addEventListener("click", () => {
        const link = document.createElement("a"); // creating <a> element
        link.download = `${Date.now()}.jpg`; // passing current date as link download value
        link.href = canvas.toDataURL(); // passing canvasData as link href value
        link.click(); // clicking link to download image
    });
    
    canvas.addEventListener("mousedown", startDraw);
    canvas.addEventListener("mousemove", drawing);
    canvas.addEventListener("mouseup", () => isDrawing = false);

    In summary, making a Drawing App using HTML, CSS, and JavaScript is both fun and educational. It’s a great project for beginners to learn coding basics while getting creative. So, let’s dive in, draw, and enjoy the process of building something cool!

    If your project has problems, don’t worry. Just click to download the source code and face your coding challenges with excitement. Have fun coding!

    Share. Copy Link Twitter Facebook LinkedIn Email WhatsApp
    Previous ArticleHow to make Custom File Upload Button in HTML CSS & JavaScript
    Next Article Master Frontend in 100 Days Ebook
    Coding Stella
    • Website

    Related Posts

    JavaScript

    How to create Cross Road Game using HTML CSS and JS

    2 May 2025
    JavaScript

    How to create 3D Animated Bee website using HTML CSS and JS

    28 April 2025
    JavaScript

    How to create Animated File Upload Modal using JavaScript

    23 April 2025
    Add A Comment
    Leave A Reply Cancel Reply

    Trending Post

    Master Frontend in 100 Days Ebook

    2 March 202419K Views

    How to make Modern Login Form using HTML & CSS | Glassmorphism

    11 January 202416K Views

    How to make I love you Animation in HTML CSS & JavaScript

    14 February 202414K Views

    How to make Valentine’s Day Card using HTML & CSS

    13 February 202412K Views
    Follow Us
    • Instagram
    • Facebook
    • YouTube
    • Twitter
    ads
    Featured Post

    How to create Cross Road Game using HTML CSS and JS

    2 May 2025

    How to make Ghibli style moving castle in HTML CSS & JavaScript

    28 March 2025

    How to Make Animated Login Form in HTML and CSS

    12 December 2023

    How to Make a Personal Portfolio Website Using HTML CSS & JavaScript

    9 December 2023
    Latest Post

    How to make Awesome Radar Animation using HTML & CSS

    8 May 2025

    How to create Cross Road Game using HTML CSS and JS

    2 May 2025

    How to create 3D Animated Bee website using HTML CSS and JS

    28 April 2025

    How to create Animated File Upload Modal using JavaScript

    23 April 2025
    Facebook X (Twitter) Instagram YouTube
    • About Us
    • Privacy Policy
    • Return and Refund Policy
    • Terms and Conditions
    • Contact Us
    • Buy me a coffee
    © 2025 Coding Stella. Made with 💙 by @coding.stella

    Type above and press Enter to search. Press Esc to cancel.

    Ad Blocker Enabled!
    Ad Blocker Enabled!
    Looks like you're using an ad blocker. We rely on advertising to help fund our site.
    Okay! I understood