Draw on HTML5 Canvas using a mouse

HtmlCanvasGestureGesture Recognition

Html Problem Overview


I want to draw on a HTML Canvas using a mouse (for example, draw a signature, draw a name, ...)

How would I go about implementing this?

Html Solutions


Solution 1 - Html

Here is a working sample.

 <html>
    <script type="text/javascript">
    var canvas, ctx, flag = false,
        prevX = 0,
        currX = 0,
        prevY = 0,
        currY = 0,
        dot_flag = false;

    var x = "black",
        y = 2;
    
    function init() {
        canvas = document.getElementById('can');
        ctx = canvas.getContext("2d");
        w = canvas.width;
        h = canvas.height;
    
        canvas.addEventListener("mousemove", function (e) {
            findxy('move', e)
        }, false);
        canvas.addEventListener("mousedown", function (e) {
            findxy('down', e)
        }, false);
        canvas.addEventListener("mouseup", function (e) {
            findxy('up', e)
        }, false);
        canvas.addEventListener("mouseout", function (e) {
            findxy('out', e)
        }, false);
    }
    
    function color(obj) {
        switch (obj.id) {
            case "green":
                x = "green";
                break;
            case "blue":
                x = "blue";
                break;
            case "red":
                x = "red";
                break;
            case "yellow":
                x = "yellow";
                break;
            case "orange":
                x = "orange";
                break;
            case "black":
                x = "black";
                break;
            case "white":
                x = "white";
                break;
        }
        if (x == "white") y = 14;
        else y = 2;
    
    }
    
    function draw() {
        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(currX, currY);
        ctx.strokeStyle = x;
        ctx.lineWidth = y;
        ctx.stroke();
        ctx.closePath();
    }
    
    function erase() {
        var m = confirm("Want to clear");
        if (m) {
            ctx.clearRect(0, 0, w, h);
            document.getElementById("canvasimg").style.display = "none";
        }
    }
    
    function save() {
        document.getElementById("canvasimg").style.border = "2px solid";
        var dataURL = canvas.toDataURL();
        document.getElementById("canvasimg").src = dataURL;
        document.getElementById("canvasimg").style.display = "inline";
    }
    
    function findxy(res, e) {
        if (res == 'down') {
            prevX = currX;
            prevY = currY;
            currX = e.clientX - canvas.offsetLeft;
            currY = e.clientY - canvas.offsetTop;
    
            flag = true;
            dot_flag = true;
            if (dot_flag) {
                ctx.beginPath();
                ctx.fillStyle = x;
                ctx.fillRect(currX, currY, 2, 2);
                ctx.closePath();
                dot_flag = false;
            }
        }
        if (res == 'up' || res == "out") {
            flag = false;
        }
        if (res == 'move') {
            if (flag) {
                prevX = currX;
                prevY = currY;
                currX = e.clientX - canvas.offsetLeft;
                currY = e.clientY - canvas.offsetTop;
                draw();
            }
        }
    }
    </script>
    <body onload="init()">
        <canvas id="can" width="400" height="400" style="position:absolute;top:10%;left:10%;border:2px solid;"></canvas>
        <div style="position:absolute;top:12%;left:43%;">Choose Color</div>
        <div style="position:absolute;top:15%;left:45%;width:10px;height:10px;background:green;" id="green" onclick="color(this)"></div>
        <div style="position:absolute;top:15%;left:46%;width:10px;height:10px;background:blue;" id="blue" onclick="color(this)"></div>
        <div style="position:absolute;top:15%;left:47%;width:10px;height:10px;background:red;" id="red" onclick="color(this)"></div>
        <div style="position:absolute;top:17%;left:45%;width:10px;height:10px;background:yellow;" id="yellow" onclick="color(this)"></div>
        <div style="position:absolute;top:17%;left:46%;width:10px;height:10px;background:orange;" id="orange" onclick="color(this)"></div>
        <div style="position:absolute;top:17%;left:47%;width:10px;height:10px;background:black;" id="black" onclick="color(this)"></div>
        <div style="position:absolute;top:20%;left:43%;">Eraser</div>
        <div style="position:absolute;top:22%;left:45%;width:15px;height:15px;background:white;border:2px solid;" id="white" onclick="color(this)"></div>
        <img id="canvasimg" style="position:absolute;top:10%;left:52%;" style="display:none;">
        <input type="button" value="save" id="btn" size="30" onclick="save()" style="position:absolute;top:55%;left:10%;">
        <input type="button" value="clear" id="clr" size="23" onclick="erase()" style="position:absolute;top:55%;left:15%;">
    </body>
    </html>

Solution 2 - Html

I think, other examples here are too complicated. This one is simpler and JS only...

// create canvas element and append it to document body
var canvas = document.createElement('canvas');
document.body.appendChild(canvas);

// some hotfixes... ( ≖_≖)
document.body.style.margin = 0;
canvas.style.position = 'fixed';

// get canvas 2D context and set him correct size
var ctx = canvas.getContext('2d');
resize();

// last known position
var pos = { x: 0, y: 0 };

window.addEventListener('resize', resize);
document.addEventListener('mousemove', draw);
document.addEventListener('mousedown', setPosition);
document.addEventListener('mouseenter', setPosition);

// new position from mouse event
function setPosition(e) {
  pos.x = e.clientX;
  pos.y = e.clientY;
}

// resize canvas
function resize() {
  ctx.canvas.width = window.innerWidth;
  ctx.canvas.height = window.innerHeight;
}

function draw(e) {
  // mouse left button must be pressed
  if (e.buttons !== 1) return;

  ctx.beginPath(); // begin

  ctx.lineWidth = 5;
  ctx.lineCap = 'round';
  ctx.strokeStyle = '#c0392b';

  ctx.moveTo(pos.x, pos.y); // from
  setPosition(e);
  ctx.lineTo(pos.x, pos.y); // to

  ctx.stroke(); // draw it!
}

Solution 3 - Html

Here's the most straightforward way to create a drawing application with canvas:

  1. Attach a mousedown, mousemove, and mouseup event listener to the canvas DOM
  2. on mousedown, get the mouse coordinates, and use the moveTo() method to position your drawing cursor and the beginPath() method to begin a new drawing path.
  3. on mousemove, continuously add a new point to the path with lineTo(), and color the last segment with stroke().
  4. on mouseup, set a flag to disable the drawing.

From there, you can add all kinds of other features like giving the user the ability to choose a line thickness, color, brush strokes, and even layers.

Solution 4 - Html

I was looking to use this method for signatures as well, i found a sample on http://codetheory.in/.

I've added the below code to a jsfiddle

Html:

<div id="sketch">
	<canvas id="paint"></canvas>
</div>

Javascript:

 (function() {
	var canvas = document.querySelector('#paint');
	var ctx = canvas.getContext('2d');
	
	var sketch = document.querySelector('#sketch');
	var sketch_style = getComputedStyle(sketch);
	canvas.width = parseInt(sketch_style.getPropertyValue('width'));
	canvas.height = parseInt(sketch_style.getPropertyValue('height'));

	var mouse = {x: 0, y: 0};
	var last_mouse = {x: 0, y: 0};
	
	/* Mouse Capturing Work */
	canvas.addEventListener('mousemove', function(e) {
		last_mouse.x = mouse.x;
		last_mouse.y = mouse.y;
		
		mouse.x = e.pageX - this.offsetLeft;
		mouse.y = e.pageY - this.offsetTop;
	}, false);
	
	
	/* Drawing on Paint App */
	ctx.lineWidth = 5;
	ctx.lineJoin = 'round';
	ctx.lineCap = 'round';
	ctx.strokeStyle = 'blue';
	
	canvas.addEventListener('mousedown', function(e) {
		canvas.addEventListener('mousemove', onPaint, false);
	}, false);
	
	canvas.addEventListener('mouseup', function() {
		canvas.removeEventListener('mousemove', onPaint, false);
	}, false);
	
	var onPaint = function() {
		ctx.beginPath();
		ctx.moveTo(last_mouse.x, last_mouse.y);
		ctx.lineTo(mouse.x, mouse.y);
		ctx.closePath();
		ctx.stroke();
	};
	
}());

Solution 5 - Html

Here is my very simple working canvas draw and erase.

https://jsfiddle.net/richardcwc/d2gxjdva/

//Canvas
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
//Variables
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = 0;
var mousex = mousey = 0;
var mousedown = false;
var tooltype = 'draw';

//Mousedown
$(canvas).on('mousedown', function(e) {
    last_mousex = mousex = parseInt(e.clientX-canvasx);
	last_mousey = mousey = parseInt(e.clientY-canvasy);
    mousedown = true;
});

//Mouseup
$(canvas).on('mouseup', function(e) {
    mousedown = false;
});

//Mousemove
$(canvas).on('mousemove', function(e) {
    mousex = parseInt(e.clientX-canvasx);
    mousey = parseInt(e.clientY-canvasy);
    if(mousedown) {
        ctx.beginPath();
        if(tooltype=='draw') {
            ctx.globalCompositeOperation = 'source-over';
            ctx.strokeStyle = 'black';
            ctx.lineWidth = 3;
        } else {
            ctx.globalCompositeOperation = 'destination-out';
            ctx.lineWidth = 10;
        }
        ctx.moveTo(last_mousex,last_mousey);
        ctx.lineTo(mousex,mousey);
        ctx.lineJoin = ctx.lineCap = 'round';
        ctx.stroke();
    }
    last_mousex = mousex;
    last_mousey = mousey;
    //Output
    $('#output').html('current: '+mousex+', '+mousey+'<br/>last: '+last_mousex+', '+last_mousey+'<br/>mousedown: '+mousedown);
});

//Use draw|erase
use_tool = function(tool) {
    tooltype = tool; //update
}

canvas {
    cursor: crosshair;
    border: 1px solid #000000;
}

<canvas id="canvas" width="800" height="500"></canvas>
<input type="button" value="draw" onclick="use_tool('draw');" />
<input type="button" value="erase" onclick="use_tool('erase');" />
<div id="output"></div>

Solution 6 - Html

I had to provide a simple example for this subject so I'll share here:

http://jsfiddle.net/Haelle/v6tfp2e1

class SignTool {
  constructor() {
    this.initVars()
    this.initEvents()
  }

  initVars() {
    this.canvas = $('#canvas')[0]
    this.ctx = this.canvas.getContext("2d")
    this.isMouseClicked = false
    this.isMouseInCanvas = false
    this.prevX = 0
    this.currX = 0
    this.prevY = 0
    this.currY = 0
  }

  initEvents() {
    $('#canvas').on("mousemove", (e) => this.onMouseMove(e))
    $('#canvas').on("mousedown", (e) => this.onMouseDown(e))
    $('#canvas').on("mouseup", () => this.onMouseUp())
    $('#canvas').on("mouseout", () => this.onMouseOut())
    $('#canvas').on("mouseenter", (e) => this.onMouseEnter(e))
  }
  
  onMouseDown(e) {
  	this.isMouseClicked = true
    this.updateCurrentPosition(e)
  }
  
  onMouseUp() {
  	this.isMouseClicked = false
  }
  
  onMouseEnter(e) {
  	this.isMouseInCanvas = true
    this.updateCurrentPosition(e)
  }
  
  onMouseOut() {
  	this.isMouseInCanvas = false
  }

  onMouseMove(e) {
    if (this.isMouseClicked && this.isMouseInCanvas) {
    	this.updateCurrentPosition(e)
      this.draw()
    }
  }
  
  updateCurrentPosition(e) {
      this.prevX = this.currX
      this.prevY = this.currY
      this.currX = e.clientX - this.canvas.offsetLeft
      this.currY = e.clientY - this.canvas.offsetTop
  }
  
  draw() {
    this.ctx.beginPath()
    this.ctx.moveTo(this.prevX, this.prevY)
    this.ctx.lineTo(this.currX, this.currY)
    this.ctx.strokeStyle = "black"
    this.ctx.lineWidth = 2
    this.ctx.stroke()
    this.ctx.closePath()
  }
}

var canvas = new SignTool()

canvas {
  position: absolute;
  border: 2px solid;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="canvas" width="500" height="300"></canvas>

Solution 7 - Html

A super short version, here, without position:absolute in vanilla JavaScript. The main idea is to move the canvas' context to the right coordinates and draw a line. Uncomment click handler and comment mousedown & mousemove handlers below to get a feel for how it is working.

<!DOCTYPE html>
<html>
<body>

<p style="margin: 50px">Just some padding in y direction</p>

<canvas id="myCanvas" width="300" height="300" style="background: #000; margin-left: 100px;">Your browser does not support the HTML5 canvas tag.</canvas>

<script>
	const c = document.getElementById("myCanvas");
	// c.addEventListener("click", penTool); // fires after mouse left btn is released
    c.addEventListener("mousedown", setLastCoords); // fires before mouse left btn is released
    c.addEventListener("mousemove", freeForm);
    
    
    const ctx = c.getContext("2d");
    
    function setLastCoords(e) {
    	const {x, y} = c.getBoundingClientRect();
        lastX = e.clientX - x;
        lastY = e.clientY - y;
    }
    
    function freeForm(e) {
    	if (e.buttons !== 1) return; // left button is not pushed yet
        penTool(e);
    }
    
    function penTool(e) {
    	const {x, y} = c.getBoundingClientRect();
        const newX = e.clientX - x;
        const newY = e.clientY - y;
        
        ctx.beginPath();
        ctx.lineWidth = 5;
        ctx.moveTo(lastX, lastY);
        ctx.lineTo(newX, newY);
        ctx.strokeStyle = 'white';
        ctx.stroke();
        ctx.closePath();
        
        lastX = newX;
        lastY = newY;
    }
    
	let lastX = 0;
    let lastY = 0;  
</script>

</body>
</html>

Solution 8 - Html

It's been years since the question was asked and was answered.

For anyone who looks for a simple drawing canvas (eg, for taking the signature from the user/customer), here I am posting a more simplified jquery version of the currently accepted answer

$(document).ready(function() {
  var flag, dot_flag = false,
	prevX, prevY, currX, currY = 0,
	color = 'black', thickness = 2;
  var $canvas = $('#canvas');
  var ctx = $canvas[0].getContext('2d');

  $canvas.on('mousemove mousedown mouseup mouseout', function(e) {
    prevX = currX;
    prevY = currY;
    currX = e.clientX - $canvas.offset().left;
    currY = e.clientY - $canvas.offset().top;
    if (e.type == 'mousedown') {
      flag = true;
    }
    if (e.type == 'mouseup' || e.type == 'mouseout') {
      flag = false;
    }
    if (e.type == 'mousemove') {
      if (flag) {
        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(currX, currY);
        ctx.strokeStyle = color;
        ctx.lineWidth = thickness;
        ctx.stroke();
        ctx.closePath();
      }
    }
  });

  $('.canvas-clear').on('click', function(e) {
    c_width = $canvas.width();
    c_height = $canvas.height();
    ctx.clearRect(0, 0, c_width, c_height);
    $('#canvasimg').hide();
  });
});

<html>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
  <body>
    <canvas id="canvas" width="400" height="400" style="position:absolute;top:10%;left:10%;border:2px solid;"></canvas>
    <input type="button" value="Clear" class="canvas-clear" />
  </body>
</html>

Solution 9 - Html

Alco check this one:
Example:
https://github.com/williammalone/Simple-HTML5-Drawing-App

Documentation:
http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/

This document includes following codes:-

HTML:

<canvas id="canvas" width="490" height="220"></canvas>

JS:

context = document.getElementById('canvas').getContext("2d");

$('#canvas').mousedown(function(e){
  var mouseX = e.pageX - this.offsetLeft;
  var mouseY = e.pageY - this.offsetTop;
		
  paint = true;
  addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
  redraw();
});

$('#canvas').mouseup(function(e){
  paint = false;
});

$('#canvas').mouseleave(function(e){
  paint = false;
});

var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;

function addClick(x, y, dragging)
{
  clickX.push(x);
  clickY.push(y);
  clickDrag.push(dragging);
}

//Also redraw
function redraw(){
  context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
  
  context.strokeStyle = "#df4b26";
  context.lineJoin = "round";
  context.lineWidth = 5;
			
  for(var i=0; i < clickX.length; i++) {		
    context.beginPath();
    if(clickDrag[i] && i){
      context.moveTo(clickX[i-1], clickY[i-1]);
     }else{
       context.moveTo(clickX[i]-1, clickY[i]);
     }
     context.lineTo(clickX[i], clickY[i]);
     context.closePath();
     context.stroke();
  }
}

And another awesome example
http://perfectionkills.com/exploring-canvas-drawing-techniques/

Solution 10 - Html

I used what 1083202 did but removed all the controlles, and implemented the change that KWILLIAMS suggested, that made it non sensitive to scrolling. I also made the canvas big, basically over my whole page 2000x1600 px, excepts for the margins. I did remove all the drawing tools and buttons, and used "blue" as the only color.

I put the JS-code in a separate file named myJS.js, and put that in a folder named "JS" localy:

I then used a Stylus on my Laptop to write on the tuchpad, witch works out a bit better then with the finger or mouse.

The document I use it for is kind of informal, for internal use, but it is nice to be able to put some pen strokes on it before making a pdf-file.

    var canvas, ctx, flag = false,
        prevX = 0,
        currX = 0,
        prevY = 0,
        currY = 0,
        dot_flag = false;

    var x = "blue",
        y = 3;
    
    function init() {
        canvas = document.getElementById('can');
        ctx = canvas.getContext("2d");
        w = canvas.width;
        h = canvas.height;
    
        canvas.addEventListener("mousemove", function (e) {
            findxy('move', e)
        }, false);
        canvas.addEventListener("mousedown", function (e) {
            findxy('down', e)
        }, false);
        canvas.addEventListener("mouseup", function (e) {
            findxy('up', e)
        }, false);
        canvas.addEventListener("mouseout", function (e) {
            findxy('out', e)
        }, false);
    }
 
    function draw() {
        ctx.beginPath();
        ctx.moveTo(prevX, prevY);
        ctx.lineTo(currX, currY);
        ctx.strokeStyle = x;
        ctx.lineWidth = y;
        ctx.stroke();
        ctx.closePath();
    }
   
    function findxy(res, e) {
        if (res == 'down') {
            prevX = currX;
            prevY = currY;
            currX = e.clientX - canvas.getBoundingClientRect().left;
            currY = e.clientY - canvas.getBoundingClientRect().top;
    
            flag = true;
            dot_flag = true;
            if (dot_flag) {
                ctx.beginPath();
                ctx.fillStyle = x;
                ctx.fillRect(currX, currY, 2, 2);
                ctx.closePath();
                dot_flag = false;
            }
        }
        if (res == 'up' || res == "out") {
            flag = false;
        }
        if (res == 'move') {
            if (flag) {
                prevX = currX;
                prevY = currY;
                currX = e.clientX - canvas.getBoundingClientRect().left;
                currY = e.clientY - canvas.getBoundingClientRect().top;
                draw();
            }
        }
    }

<html> 



<body onload="init()">
<p>Below you can draw:</p>
<canvas id="can" width="750" height="1050" style="position:absolute;">Below you can write:</canvas>
</body>

Solution 11 - Html

Let me know if you have trouble implementing this. It uses processing.js and has features for changing colors and making the draw point larger and smaller.

<html>
<head>
<!--script librarires-->
<script type="text/javascript" src="processing.js"></script>
<script type="text/javascript" src="init.js"></script>

<!--styles -->
<style type="text/css" src="stylesheet.css">
</style> 
</head>
<body>
<!--toolbox -->
<div id="draggable toolbox"></div>
<script type="application/processing">
// new script
int prevx, prevy;
int newx, newy;
boolean cliked;
color c1 = #000000;
int largeur=2;
int ps = 20;
int px = 50;
int py = 50;

void setup() {
size(500,500);
frameRate(25);
background(50);

 prevx = mouseX;
 prevy = mouseY;
 cliked = false;
 }

void draw() {
 //couleur
 noStroke(0);
 fill(#FFFFFF);//blanc
rect(px, py, ps, ps);
 fill(#000000);
 rect(px, py+(ps), ps, ps);
 fill(#FF0000);
 rect(px, py+(ps*2), ps, ps);
 fill(#00FF00);
 rect(px, py+(ps*3), ps, ps);
 fill(#FFFF00);
 rect(px, py+(ps*4), ps, ps);
 fill(#0000FF);
 rect(px, py+(ps*5), ps, ps);
 //largeur
 fill(#FFFFFF);
 rect(px, py+(ps*7), ps, ps);
  fill(#FFFFFF);
 rect(px, py+(ps*8), ps, ps);
 stroke(#000000);
 line(px+2, py+(ps*7)+(ps/2), px+(ps-2), py+(ps*7)+(ps/2));
 line(px+(ps/2), py+(ps*7)+1, px+(ps/2), py+(ps*8)-1);
 line(px+2, py+(ps*8)+(ps/2), px+(ps-2), py+(ps*8)+(ps/2));

 if(cliked==false){
  prevx = mouseX;
 prevy = mouseY;  
 }
 if(mousePressed) { 
  cliked = true;
 newx = mouseX;
  newy = mouseY;
  strokeWeight(largeur);
  stroke(c1);
  line(prevx, prevy, newx, newy);
  prevx = newx;
 prevy = newy;
 }else{
  cliked= false;
  }
}
void mouseClicked() {
 if (mouseX>=px && mouseX<=(px+ps)){
  //couleur
  if (mouseY>=py && mouseY<=py+(ps*6)){ 
   c1 = get(mouseX, mouseY);
  }
   //largeur
  if (mouseY>=py+(ps*7) && mouseY<=py+(ps*8)){ 
   largeur += 2;
  }
 if (mouseY>=py+(ps*8) && mouseY<=py+(ps*9)){ 
   if (largeur>2){
    largeur -= 2;
   }
  }
 }
}
</script><canvas></canvas>
</body>
</html>

Solution 12 - Html

if you have background image for your canvas, you will have to make some tweaks to have it work properly because white erasing trick will hide the background.

here is a gist with the code.

<html>
	<script type="text/javascript">
	var canvas, canvasimg, backgroundImage, finalImg;
	var	mouseClicked = false;
	var prevX = 0;
	var currX = 0;
	var prevY = 0;
	var currY = 0;
	var fillStyle = "black";
	var globalCompositeOperation = "source-over";
	var lineWidth = 2;

	function init() {
	  var imageSrc = '/abstract-geometric-pattern_23-2147508597.jpg'
	  backgroundImage = new Image();
	  backgroundImage.src = imageSrc;
	  canvas = document.getElementById('can');
	  finalImg = document.getElementById('finalImg');
	  canvasimg = document.getElementById('canvasimg');
	  canvas.style.backgroundImage = "url('" + imageSrc + "')";
	  canvas.addEventListener("mousemove", handleMouseEvent);
	  canvas.addEventListener("mousedown", handleMouseEvent);
	  canvas.addEventListener("mouseup", handleMouseEvent);
	  canvas.addEventListener("mouseout", handleMouseEvent);
	}

	function getColor(btn) {
	  globalCompositeOperation = 'source-over';
	  lineWidth = 2;
	  switch (btn.getAttribute('data-color')) {
	    case "green":
	    fillStyle = "green";
	    break;
	    case "blue":
	    fillStyle = "blue";
	    break;
	    case "red":
	    fillStyle = "red";
	    break;
	    case "yellow":
	    fillStyle = "yellow";
	    break;
	    case "orange":
	    fillStyle = "orange";
	    break;
	    case "black":
	    fillStyle = "black";
	    break;
	    case "eraser":
	    globalCompositeOperation = 'destination-out';
	    fillStyle = "rgba(0,0,0,1)";
	    lineWidth = 14;
	    break;
	  }
	  
	}

	function draw(dot) {
	  var ctx = canvas.getContext("2d");
	  ctx.beginPath();
	  ctx.globalCompositeOperation = globalCompositeOperation;
	  if(dot){
	    ctx.fillStyle = fillStyle;
	    ctx.fillRect(currX, currY, 2, 2);
	  } else {
	    ctx.beginPath();
	    ctx.moveTo(prevX, prevY);
	    ctx.lineTo(currX, currY);
	    ctx.strokeStyle = fillStyle;
	    ctx.lineWidth = lineWidth;
	    ctx.stroke();
	  }
	  ctx.closePath();
	}

	function erase() {
	  if (confirm("Want to clear")) {
	  	var ctx = canvas.getContext("2d");
	    ctx.clearRect(0, 0, canvas.width, canvas.height);
	    document.getElementById("canvasimg").style.display = "none";
	  }
	}

	function save() {
	  canvas.style.border = "2px solid";
	  canvasimg.width = canvas.width;
	  canvasimg.height = canvas.height;
	  var ctx2 = canvasimg.getContext("2d");
	  // comment next line to save the draw only
	  ctx2.drawImage(backgroundImage, 0, 0);
	  ctx2.drawImage(canvas, 0, 0);
	  finalImg.src = canvasimg.toDataURL();
	  finalImg.style.display = "inline";
	}

	function handleMouseEvent(e) {
	  if (e.type === 'mousedown') {
	    prevX = currX;
	    prevY = currY;
	    currX = e.offsetX;
	    currY = e.offsetY;
	    mouseClicked = true;
	    draw(true);
	  }
	  if (e.type === 'mouseup' || e.type === "mouseout") {
	    mouseClicked = false;
	  }
	  if (e.type === 'mousemove') {
	    if (mouseClicked) {
	      prevX = currX;
	      prevY = currY;
	      currX = e.offsetX;
	      currY = e.offsetY;
	      draw();
	    }
	  }
	}
	</script>
	<body onload="init()">
	  <canvas id="can" width="400" height="400" style="position:absolute;top:10%;left:10%;border:2px solid;">
	  </canvas>
	  <div style="position:absolute;top:12%;left:43%;">Choose Color</div>
	  <div style="position:absolute;top:15%;left:45%;width:10px;height:10px;background:green;" data-color="green" onclick="getColor(this)"></div>
	  <div style="position:absolute;top:15%;left:46%;width:10px;height:10px;background:blue;" data-color="blue" onclick="getColor(this)"></div>
	  <div style="position:absolute;top:15%;left:47%;width:10px;height:10px;background:red;" data-color="red" onclick="getColor(this)"></div>
	  <div style="position:absolute;top:17%;left:45%;width:10px;height:10px;background:yellow;" data-color="yellow" onclick="getColor(this)"></div>
	  <div style="position:absolute;top:17%;left:46%;width:10px;height:10px;background:orange;" data-color="orange" onclick="getColor(this)"></div>
	  <div style="position:absolute;top:17%;left:47%;width:10px;height:10px;background:black;" data-color="black" onclick="getColor(this)"></div>
	  <div style="position:absolute;top:20%;left:43%;">Eraser</div>
	  <div style="position:absolute;top:22%;left:45%;width:15px;height:15px;background:white;border:2px solid;" data-color="eraser" onclick="getColor(this)"></div>
	  <canvas id="canvasimg" style="display:none;" ></canvas>
	  <img id="finalImg" style="position:absolute;top:10%;left:52%;display:none;" >
	  <input type="button" value="save" id="btn" size="30" onclick="save()" style="position:absolute;top:55%;left:10%;">
	  <input type="button" value="clear" id="clr" size="23" onclick="erase()" style="position:absolute;top:55%;left:15%;">
	</body>
	</html>

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMartinJooView Question on Stackoverflow
Solution 1 - Htmluser1083202View Answer on Stackoverflow
Solution 2 - HtmlMatěj PokornýView Answer on Stackoverflow
Solution 3 - HtmlEric RowellView Answer on Stackoverflow
Solution 4 - HtmlSam JonesView Answer on Stackoverflow
Solution 5 - HtmlRichardView Answer on Stackoverflow
Solution 6 - HtmlHaelleView Answer on Stackoverflow
Solution 7 - HtmlNitinView Answer on Stackoverflow
Solution 8 - HtmlMunawirView Answer on Stackoverflow
Solution 9 - HtmlvusanView Answer on Stackoverflow
Solution 10 - HtmlMichael LarssonView Answer on Stackoverflow
Solution 11 - HtmlexpiredninjaView Answer on Stackoverflow
Solution 12 - HtmlMohammed EssehemyView Answer on Stackoverflow