Paint an image without removing it on html5 canvas - html

I have a black and white image and i would like to paint it with the color i picked without removing the image. When i start to paint its painting the image borders either.
I would like to still have the image over there and paint just the "background" of a PNG image just like this script: "http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/#demo-sizes"
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="js/jquery-1.11.2.min.js"></script>
<!--http://perfectionkills.com/exploring-canvas-drawing-techniques/-->
<script type="text/javascript">
var isFirefox = typeof InstallTrigger !== 'undefined';
var CanvasLogBook = function() {
this.index = 0;
this.logs = [];
this.logDrawing();
};
CanvasLogBook.prototype.sliceAndPush = function(imageObject) {
var array;
if (this.index == this.logs.length-1) {
this.logs.push(imageObject);
array = this.logs;
} else {
var tempArray = this.logs.slice(0, this.index+1);
tempArray.push(imageObject);
array = tempArray;
}
if (array.length > 1) {
this.index++;
}
return array;
};
CanvasLogBook.prototype.logDrawing = function() {
if (isFirefox) {
var image = new Image();
image.src = document.getElementById('can').toDataURL();
//var canvas = document.getElementsByClassName("can");
//image.src = canvas.toDataURL();
this.logs = this.sliceAndPush(image);
} else {
var imageData = document.getElementById('can').toDataURL();
this.logs = this.sliceAndPush(imageData);
}
};
CanvasLogBook.prototype.undo = function() {
ctx.clearRect(0, 0, $('#can').width(), $('#can').height());
if (this.index > 0) {
this.index--;
this.showLogAtIndex(this.index);
}
};
CanvasLogBook.prototype.redo = function() {
if (this.index < this.logs.length-1) {
ctx.clearRect(0, 0, $('#can').width(), $('#can').height());
this.index++;
this.showLogAtIndex(this.index);
}
};
CanvasLogBook.prototype.showLogAtIndex = function(index) {
ctx.clearRect(0, 0, $('#can').width(), $('#can').height());
if (isFirefox) {
var image = this.logs[index];
ctx.drawImage(image, 0, 0);
} else {
var image = new Image();
image.src = this.logs[index];
ctx.drawImage(image, 0, 0);
}
};
$( document ).ready(function() {
var canvasLogBook = new CanvasLogBook();
$( "#undo" ).click(function() {
canvasLogBook.undo();
});
$( "#redo" ).click(function() {
canvasLogBook.redo();
});
$( "canvas" ).click(function() {
canvasLogBook.logDrawing();
});
});
var img = document.createElement("img"); // Create a <button> element
img.setAttribute('src','img.png');
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "black",
y = 10;
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);
ctx.drawImage(img,90, 20); //desenho a img no começo
}
function color(obj) {
var cor_sombra_selecionado = $('input[name=sombra]:checked').val();
if ( (cor_sombra_selecionado == '') || (cor_sombra_selecionado =='nenhuma') ){
ctx.shadowColor = obj.id;
} else {
ctx.shadowColor = cor_sombra_selecionado;
}
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 = 10;
else y = 10;
}
function sombra_funcao(cor) {
var cor_sombra_selecionado = $('input[name=sombra]:checked').val();
console.log(cor_sombra_selecionado + ' cliquei na cor da sombra');
if ( (cor_sombra_selecionado == '') || (cor_sombra_selecionado =='nenhuma') ){
ctx.shadowColor = x;
} else {
ctx.shadowColor = cor_sombra_selecionado;
}
}
function draw() {
var cor_sombra_selecionado = $('input[type=radio]:checked').val();
console.log(cor_sombra_selecionado + ' cliquei na cor');
if ( (cor_sombra_selecionado == '') || (cor_sombra_selecionado =='nenhuma') ){
ctx.shadowColor = x;
} else {
ctx.shadowColor = cor_sombra_selecionado;
}
ctx.beginPath();
ctx.lineCap = "round";
ctx.lineJoin = 'round';
ctx.shadowBlur = 4;
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
console.log("dsa");
ctx.closePath();
}
function erase() {
var m = confirm("Want to clear");
if (m) {
ctx.clearRect(0, 0, w, h);
document.getElementById("canvasimg").style.display = "none";
}
ctx.drawImage(img,90, 20); //desenho o bg
}
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.strokeStyle = x;
ctx.beginPath();
ctx.fillStyle = x;
//ctx.fillRect(currX, currY, 10, 10,10,10);
ctx.arc(currX, currY,4,0,2*Math.PI);
//ctx.arc(currX, currY,2,2,2,2*Math.PI);
ctx.lineCap = "round";
ctx.lineJoin = 'round';
//ctx.stroke();
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();
}
}
}
/*$( document ).ready(function() {
(function($) {
var tool;
var history = {
redo_list: [],
undo_list: [],
saveState: function(canvas, list, keep_redo) {
keep_redo = keep_redo || false;
if(!keep_redo) {
this.redo_list = [];
}
(list || this.undo_list).push(canvas.toDataURL());
},
undo: function(canvas, ctx) {
this.restoreState(canvas, ctx, this.undo_list, this.redo_list);
},
redo: function(canvas, ctx) {
this.restoreState(canvas, ctx, this.redo_list, this.undo_list);
},
restoreState: function(canvas, ctx, pop, push) {
if(pop.length) {
this.saveState(canvas, push, true);
var restore_state = pop.pop();
var img = new Element('img', {'src':restore_state});
img.onload = function() {
ctx.clearRect(0, 0, 600, 400);
ctx.drawImage(img, 0, 0, 600, 400, 0, 0, 600, 400);
}
}
}
};
});
$( "#undo" ).click(function() {
console.log("das");
history.undo(canvas, ctx);
});
}); //ready */
</script>
</head>
<body onload="init()">
<div class="container">
<div class="row">
<div class="col-md-12"><h3>Desenhar</h3></div>
</div>
<div class="row">
</div>
<div class="row">
<canvas id="can" class='teste' width="500" height="400" style="border:2px solid;float:right"></canvas>
<div class="col-md-6">
<div class="col-md-12">
<h3>Cores</h3>
<div class="col-md-2"> <label style="background:green;"><input type='radio' name='cor' id='green' onclick="color(this)">Verde</label> </div>
<div class="col-md-2"> <label style="background:blue;"><input type='radio' name='cor' id='blue' onclick="color(this)">Azul</label> </div>
<div class="col-md-2"> <label style="background:red;"><input type='radio' name='cor' id='red' onclick="color(this)">Vermelho</label> </div>
<div class="col-md-2"> <label style="background:yellow;"><input type='radio' name='cor' id='yellow' onclick="color(this)">Amarelo</label> </div>
<div class="col-md-2"> <label style="background:orange;"><input type='radio' name='cor' id='orange' onclick="color(this)">Laranja</label> </div>
<div class="col-md-2"> <label style="background:white;"><input type='radio' name='cor' id='white' onclick="color(this)">Branco</label> </div>
</div>
</div>
<div class="col-md-6">
<div class="col-md-12">
<h3>Sombras</h3>
<div class="col-md-2"> <label style="background:green;"><input type='radio' name='sombra' value='green' onclick="sombra_funcao('green')">Verde</label> </div>
<div class="col-md-2"> <label style="background:blue;"><input type='radio' name='sombra' value='blue' onclick="sombra_funcao('blue')">Azul</label> </div>
<div class="col-md-2"> <label style="background:red;"><input type='radio' name='sombra' value='red' onclick="sombra_funcao('red')">Vermelho</label> </div>
<div class="col-md-2"> <label style="background:yellow;"><input type='radio' name='sombra' value='yellow' onclick="sombra_funcao('yellow')">Amarelo</label> </div>
<div class="col-md-2"> <label style="background:orange;"><input type='radio' name='sombra' value='orange' onclick="sombra_funcao('orange')">Laranja</label> </div>
<div class="col-md-2"> <label style="background:white;"><input type='radio' name='sombra' value='nenhuma' onclick="sombra_funcao('nenhuma')" checked>Nenhuma</label> </div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<img id="canvasimg" style="position:relative;float:left;border:1px solid #000" style="display:none;">
<input type="button" value="save" id="btn" size="30" onclick="save()" style="">
<input type="button" value="clear" id="clr" size="23" onclick="erase()" style="">
<span class="controller" id="undo">desfazer </span>
<span class="controller" id="redo">redo</span>
</div>
</div>
</div>
</body>
</html>

A very different solution comes to mind now that canvas has come to stage two: more blending modes, which simplifies the whole process:
Draw the image, make sure background is white, lines black ("dah" perhaps, but important)
Change composite (blending) mode to multiply - note: does not work yet in IE (incl. v.11).
Draw your heart out on top of it; create master pieces such as this:
(uh!... a rave-duck)
This mode will also act more like real paper and markers, ie. subtractive light when blending the colors together.
Here you don't need to worry about alpha channel/transparency as it uses only blending mode (no composition but the regular source-over, takes place).
You can further adjust blending ratio by adjusting the global alpha (note also that you will get those overlaps on the line connections - not covered in this answer, but one possible solution here (overlap), and for recording points here).
ctx.globalAlpha = 0.75; // example, set/adjust before drawing
Demo
var img = new Image;
img.onload = setup;
img.src = "http://i.stack.imgur.com/xL8it.png";
function setup() {
var canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d"),
lastPos, isDown = false;
ctx.drawImage(this, 0, 0, canvas.width, canvas.height); // draw duck
ctx.lineCap = "round"; // make lines prettier
ctx.lineWidth = 16;
ctx.globalCompositeOperation = "multiply"; // KEY MODE HERE
canvas.onmousedown = function(e) {
isDown = true;
lastPos = getPos(e);
ctx.strokeStyle = "hsl(" + (Math.random() * 360) + ", 100%, 85%)";
};
window.onmousemove = function(e) {
if (!isDown) return;
var pos = getPos(e);
ctx.beginPath();
ctx.moveTo(lastPos.x, lastPos.y);
ctx.lineTo(pos.x, pos.y);
ctx.stroke();
lastPos = pos;
};
window.onmouseup = function(e) {isDown = false};
function getPos(e) {
var rect = canvas.getBoundingClientRect();
return {x: e.clientX - rect.left, y: e.clientY - rect.top}
}
}
canvas{border:1px solid #000;cursor:crosshair}
<canvas width=400 height=400></canvas>

Redraw the outline on top whenever the user paints an added color
This is probably the easiest way of always having the original outline above the painted canvas. If you have a colored background outside the original image then redrawing the original image will eliminate any coloring outside the outline.
An interesting alternative: Use Compositing to color behind the original outline
If you want your new colorings to always be behind the original outline, you can set context.globalCompositeOperation='destination-over' and then all your new colorings will always be drawn behind the existing outline.
Note: This technique works by only coloring new pixels where the new pixel doesn't overlap any existing colored pixel.
So, to use this technique, you must make these changes on your outline image:
Use an outline that is not already filled with a color. William Malone's nice work uses a duck that is already filled with white. You would have to remove that interior white color.
Fill the background outside the outline with a color (not transparent)
I include a modified image of William Malone's duck outline that's properly set up to use compositing to always "draw within the lines". Although you can't see it from the image on a white background...
the background outside the image is colored white
and the interior of the duck is transparent.
Here's a quack example, I mean quick example (pun intended!):
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
var isDown=false;
var startX,startY;
var img=new Image();img.onload=start;img.src="https://dl.dropboxusercontent.com/u/139992952/multple/duck.png";
function start(){
cw=canvas.width=img.width;
ch=canvas.height=img.height;
ctx.fillStyle='gold';
ctx.drawImage(img,0,0);
ctx.globalCompositeOperation='destination-over';
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
}
function handleMouseDown(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// Put your mousedown stuff here
isDown=true;
}
function handleMouseUp(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// Put your mouseup stuff here
isDown=false;
}
function handleMouseOut(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
// Put your mouseOut stuff here
isDown=false;
}
function handleMouseMove(e){
if(!isDown){return;}
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
ctx.beginPath();
ctx.arc(mouseX,mouseY,10,0,Math.PI*2);
ctx.closePath();
ctx.fill();
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<canvas id="canvas" width=300 height=300></canvas>

Related

Shadow displaying when dragging image

When user upload image and when he try to drag the image , the image will display shadow along with dragging, but i don't want to display the shadow....
codepen : https://codepen.io/kidsdial/pen/xMNbVz
$(document).ready(function () {
// dont have a webserver so im using base64string instead
var maskedImageUrlb ="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaAAAAGECAYAAABwC/R5AAAACXBIWXMAAC4jAAAuIwF4pT92AAAF+mlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAxLTE5VDE4OjExOjMxKzA1OjMwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDE5LTAxLTE5VDE4OjExOjMxKzA1OjMwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMS0xOVQxODoxMTozMSswNTozMCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3NDhiN2JiYi1kNDY4LWY5NDctYTdjMy1jYzMzZTQzYjc2ODgiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDo0ZTJmZTkyNS01NzIyLTMxNGMtOTU2OC01NjQyNDFhYmVhYjMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDplZDNhMTc5My0yNTY5LTdhNDQtYTNiYi1kN2Y4ZGJkZmRjODkiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmVkM2ExNzkzLTI1NjktN2E0NC1hM2JiLWQ3ZjhkYmRmZGM4OSIgc3RFdnQ6d2hlbj0iMjAxOS0wMS0xOVQxODoxMTozMSswNTozMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NDhiN2JiYi1kNDY4LWY5NDctYTdjMy1jYzMzZTQzYjc2ODgiIHN0RXZ0OndoZW49IjIwMTktMDEtMTlUMTg6MTE6MzErMDU6MzAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz79f9E7AAAfmklEQVR4nO3de5BedZ3n8bddqa5UisqkqMiwTkRkERkMiNwUQbzgBYaLoiKKV3QcdRhlHGQZ1nUpF+94Q1xFRUZRUBEcBAYZQGSQASZExBgQY4xUNmKKyoZUNtvb29Pb7B/fbul0+vL00+ec77m8X1Vd6XS6n+cjdvfn+f3O7/x+T3r88ceRpJItBfaa9Pa08T9XAMuBJcBiYDdg0fj7MxkGxoBRYNv425ZJ7z8C/A9gI7Bp/G1bgf9bVJAnWUCSCrII2B9YCfw5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";
// maskedImage two
var mask2 = $(".container").mask({
maskImageUrl: maskedImageUrlb,
onMaskImageCreate: function (img) {
// add your style to the img example below
img.css({ "position" : "fixed" , "left": 173, "top": 1 })
}
});
fileupa2.onchange = function () {
mask2.loadImage(URL.createObjectURL(fileupa2.files[0]));
};
}); // end of document ready
// jq plugin for mask
(function ($) {
var JQmasks = [];
$.fn.mask = function (options) {
// This is the easiest way to have default options.
var settings = $.extend({
// These are the defaults.
maskImageUrl: undefined,
imageUrl: undefined,
scale: 1,
id: new Date().getUTCMilliseconds().toString(),
x: 0, // image start position
y: 0, // image start position
onMaskImageCreate: function (div) { },
}, options);
var container = $(this);
let prevX = 0,
prevY = 0,
draggable = false,
img,
canvas,
context,
image,
timeout,
initImage = false,
startX = settings.x,
startY = settings.y,
div;
container.mousePosition = function(event){
return { x: event.pageX || event.offsetX, y: event.pageY || event.offsetY };
}
container.selected = function (ev) {
var pos = container.mousePosition(ev);
var item =$(".masked-img canvas").filter(function(){
var offset = $(this).offset()
var x = pos.x - offset.left;
var y = pos.y - offset.top;
var d = this.getContext('2d').getImageData(x, y, 1, 1).data;
return d[0] >0
});
JQmasks.forEach(function(el){
var id = item.length> 0 ? $(item).attr("id") : "";
if (el.id ==id )
el.item.enable();
else el.item.disable();
});
};
container.enable = function(){
draggable = true;
$(canvas).attr("active", "true");
div.css({ "z-index": 2 });
}
container.disable = function(){
draggable = false;
$(canvas).attr("active", "false");
div.css({ "z-index": 1 });
}
container.onDragStart = function (evt) {
container.selected(evt);
prevX = evt.clientX;
prevY = evt.clientY;
};
container.getImagePosition = function () {
return { x: settings.x, y: settings.y, scale: settings.scale };
};
container.onDragOver = function (evt) {
if (draggable && $(canvas).attr("active") === "true") {
var x = settings.x + evt.clientX - prevX;
var y = settings.y + evt.clientY - prevY;
if (x == settings.x && y == settings.y)
return; // position has not changed
settings.x += evt.clientX - prevX;
settings.y += evt.clientY - prevY;
prevX = evt.clientX;
prevY = evt.clientY;
container.updateStyle();
}
};
container.updateStyle = function () {
clearTimeout(timeout);
timeout = setTimeout(function () {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.globalCompositeOperation = "source-over";
image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.src = settings.maskImageUrl;
image.onload = function () {
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, image.width, image.height);
div.css({ "width": image.width, "height": image.height });
};
img = new Image();
img.src = settings.imageUrl;
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function () {
settings.x =settings.x == 0 && initImage ? (canvas.width - (img.width * settings.scale )) / 2 : settings.x;
settings.y =settings.y == 0 && initImage ? (canvas.height - (img.height * settings.scale )) / 2 : settings.y;
context.globalCompositeOperation = 'source-atop';
context.drawImage(img, settings.x, settings.y, img.width * settings.scale, img.height * settings.scale);
initImage = false;
};
}, 0);
};
// change the draggable image
container.loadImage = function (imageUrl) {
if (img)
img.remove();
// reset the code.
settings.y = startY;
settings.x = startX;
prevX = prevY = 0;
settings.imageUrl = imageUrl;
initImage = true;
container.updateStyle();
};
// change the masked Image
container.loadMaskImage = function (imageUrl, from) {
if (div)
div.remove();
canvas = document.createElement("canvas");
context = canvas.getContext('2d');
canvas.setAttribute("draggable", "true");
canvas.setAttribute("id", settings.id);
settings.maskImageUrl = imageUrl;
div = $("<div/>", {
"class": "masked-img"
}).append(canvas);
div.find("canvas").on('touchstart mousedown', function (event) {
if (event.handled === false) return;
event.handled = true;
container.onDragStart(event);
});
div.find("canvas").on('touchend mouseup', function (event) {
if (event.handled === false) return;
event.handled = true;
container.selected(event);
});
div.find("canvas").bind("dragover", container.onDragOver);
container.append(div);
if (settings.onMaskImageCreate)
settings.onMaskImageCreate(div);
container.loadImage(settings.imageUrl);
};
container.loadMaskImage(settings.maskImageUrl);
JQmasks.push({item: container , id: settings.id})
return container;
};
}(jQuery));
.container {
border: 1px solid #DDDDDD;
display: flex;
background: red;
width:612px;
height:612px;
}
.container canvas {
display: block;
}
.masked-img {
overflow: hidden;
margin-top: 50px;
position: relative;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js">
</script>
image 2
<input id="fileupa2" type="file" >
<div class="container">
</div>
I don't want to display shadow when dragging....
Please let me know if you have any doubts on this....
Thanks in Advance....
Listen for the dragStart event :
div.find("canvas").on('dragstart', function (event) {
so you can use DataTransfer.setDragImage() :
When a drag occurs, a translucent image is generated from the drag target (the element the dragstart event is fired at), and follows the mouse pointer during the drag. This image is created automatically, so you do not need to create it yourself. However, if a custom image is desired, the DataTransfer.setDragImage() method can be used to set the custom image to be used. The image will typically be an element but it can also be a or any other image element.
And update the container.onDragStart function to :
container.onDragStart = function (evt) {
container.selected(evt);
prevX = evt.clientX;
prevY = evt.clientY;
evt.originalEvent.dataTransfer.setDragImage(null, 0, 0); // add this line
};
Here's an example with a custom " shadow" iamge :
$(document).ready(function() {
// dont have a webserver so im using base64string instead
var maskedImageUrlb = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAaAAAAGECAYAAABwC/R5AAAACXBIWXMAAC4jAAAuIwF4pT92AAAF+mlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDIgNzkuMTYwOTI0LCAyMDE3LzA3LzEzLTAxOjA2OjM5ICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdEV2dD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlRXZlbnQjIiB4bWxuczpkYz0iaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS8iIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOCAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDE5LTAxLTE5VDE4OjExOjMxKzA1OjMwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDE5LTAxLTE5VDE4OjExOjMxKzA1OjMwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAxOS0wMS0xOVQxODoxMTozMSswNTozMCIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3NDhiN2JiYi1kNDY4LWY5NDctYTdjMy1jYzMzZTQzYjc2ODgiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDo0ZTJmZTkyNS01NzIyLTMxNGMtOTU2OC01NjQyNDFhYmVhYjMiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDplZDNhMTc5My0yNTY5LTdhNDQtYTNiYi1kN2Y4ZGJkZmRjODkiIGRjOmZvcm1hdD0iaW1hZ2UvcG5nIiBwaG90b3Nob3A6Q29sb3JNb2RlPSIzIiBwaG90b3Nob3A6SUNDUHJvZmlsZT0ic1JHQiBJRUM2MTk2Ni0yLjEiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmVkM2ExNzkzLTI1NjktN2E0NC1hM2JiLWQ3ZjhkYmRmZGM4OSIgc3RFdnQ6d2hlbj0iMjAxOS0wMS0xOVQxODoxMTozMSswNTozMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTggKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3NDhiN2JiYi1kNDY4LWY5NDctYTdjMy1jYzMzZTQzYjc2ODgiIHN0RXZ0OndoZW49IjIwMTktMDEtMTlUMTg6MTE6MzErMDU6MzAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE4IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz79f9E7AAAfmklEQVR4nO3de5BedZ3n8bddqa5UisqkqMiwTkRkERkMiNwUQbzgBYaLoiKKV3QcdRhlHGQZ1nUpF+94Q1xFRUZRUBEcBAYZQGSQASZExBgQY4xUNmKKyoZUNtvb29Pb7B/fbul0+vL00+ec77m8X1Vd6XS6n+cjdvfn+f3O7/x+T3r88ceRpJItBfaa9Pa08T9XAMuBJcBiYDdg0fj7MxkGxoBRYNv425ZJ7z8C/A9gI7Bp/G1bgf9bVJAnWUCSCrII2B9YCfw5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";
// maskedImage two
var mask2 = $(".container").mask({
maskImageUrl: maskedImageUrlb,
onMaskImageCreate: function(img) {
// add your style to the img example below
img.css({
"position": "fixed",
"left": 173,
"top": 1
})
}
});
fileupa2.onchange = function() {
mask2.loadImage(URL.createObjectURL(fileupa2.files[0]));
};
}); // end of document ready
// jq plugin for mask
(function($) {
var JQmasks = [];
$.fn.mask = function(options) {
// This is the easiest way to have default options.
var settings = $.extend({
// These are the defaults.
maskImageUrl: undefined,
imageUrl: undefined,
scale: 1,
id: new Date().getUTCMilliseconds().toString(),
x: 0, // image start position
y: 0, // image start position
onMaskImageCreate: function(div) {},
}, options);
var container = $(this);
let prevX = 0,
prevY = 0,
draggable = false,
img,
canvas,
context,
image,
timeout,
initImage = false,
startX = settings.x,
startY = settings.y,
div;
container.mousePosition = function(event) {
return {
x: event.pageX || event.offsetX,
y: event.pageY || event.offsetY
};
}
container.selected = function(ev) {
var pos = container.mousePosition(ev);
var item = $(".masked-img canvas").filter(function() {
var offset = $(this).offset()
var x = pos.x - offset.left;
var y = pos.y - offset.top;
var d = this.getContext('2d').getImageData(x, y, 1, 1).data;
return d[0] > 0
});
JQmasks.forEach(function(el) {
var id = item.length > 0 ? $(item).attr("id") : "";
if (el.id == id)
el.item.enable();
else el.item.disable();
});
};
container.enable = function() {
draggable = true;
$(canvas).attr("active", "true");
div.css({
"z-index": 2
});
}
container.disable = function() {
draggable = false;
$(canvas).attr("active", "false");
div.css({
"z-index": 1
});
}
container.onDragStart = function(evt) {
container.selected(evt);
prevX = evt.clientX;
prevY = evt.clientY;
var img = new Image();
img.src = 'https://www.what-dog.net/Images/faces2/scroll001.jpg';
evt.originalEvent.dataTransfer.setDragImage(img, 10, 10);
};
container.getImagePosition = function() {
return {
x: settings.x,
y: settings.y,
scale: settings.scale
};
};
container.onDragOver = function(evt) {
if (draggable && $(canvas).attr("active") === "true") {
var x = settings.x + evt.clientX - prevX;
var y = settings.y + evt.clientY - prevY;
if (x == settings.x && y == settings.y)
return; // position has not changed
settings.x += evt.clientX - prevX;
settings.y += evt.clientY - prevY;
prevX = evt.clientX;
prevY = evt.clientY;
container.updateStyle();
}
};
container.updateStyle = function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
context.clearRect(0, 0, canvas.width, canvas.height);
context.beginPath();
context.globalCompositeOperation = "source-over";
image = new Image();
image.setAttribute('crossOrigin', 'anonymous');
image.src = settings.maskImageUrl;
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, image.width, image.height);
div.css({
"width": image.width,
"height": image.height
});
};
img = new Image();
img.src = settings.imageUrl;
img.setAttribute('crossOrigin', 'anonymous');
img.onload = function() {
settings.x = settings.x == 0 && initImage ? (canvas.width - (img.width * settings.scale)) / 2 : settings.x;
settings.y = settings.y == 0 && initImage ? (canvas.height - (img.height * settings.scale)) / 2 : settings.y;
context.globalCompositeOperation = 'source-atop';
context.drawImage(img, settings.x, settings.y, img.width * settings.scale, img.height * settings.scale);
initImage = false;
};
}, 0);
};
// change the draggable image
container.loadImage = function(imageUrl) {
if (img)
img.remove();
// reset the code.
settings.y = startY;
settings.x = startX;
prevX = prevY = 0;
settings.imageUrl = imageUrl;
initImage = true;
container.updateStyle();
};
// change the masked Image
container.loadMaskImage = function(imageUrl, from) {
if (div)
div.remove();
canvas = document.createElement("canvas");
context = canvas.getContext('2d');
canvas.setAttribute("draggable", "true");
canvas.setAttribute("id", settings.id);
settings.maskImageUrl = imageUrl;
div = $("<div/>", {
"class": "masked-img"
}).append(canvas);
div.find("canvas").on('dragstart', function(event) {
if (event.handled === false) return;
event.handled = true;
container.onDragStart(event);
});
div.find("canvas").on('touchend mouseup', function(event) {
if (event.handled === false) return;
event.handled = true;
container.selected(event);
});
div.find("canvas").bind("dragover", container.onDragOver);
container.append(div);
if (settings.onMaskImageCreate)
settings.onMaskImageCreate(div);
container.loadImage(settings.imageUrl);
};
container.loadMaskImage(settings.maskImageUrl);
JQmasks.push({
item: container,
id: settings.id
})
return container;
};
}(jQuery));
.container {
border: 1px solid #DDDDDD;
display: flex;
background: red;
width: 612px;
height: 612px;
}
.container canvas {
display: block;
}
.masked-img {
overflow: hidden;
margin-top: 50px;
position: relative;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js">
</script>
image 2
<input id="fileupa2" type="file">
<div class="container">
</div>

Why is my css not working?

I dont know why this ccs text is not working... The background should have a color.
If anybody sees my mistake, Thnx!
I have to add more details but I think it is clear too all of you, if not just ask!
THNX!
<html>
<head>
<style type="css/text">
#my_canvas {
margin: 10;
background-color: white;
border:black 3px solid;
}
Body {
background-color: slategrey;
}
</style>
</head>
<body>
<script type="text/javascript">
var bg = new Image();
var sh = new Image();
var po = new Image();
bg.src = "ruimte.jpg";
sh.src = "schiet.jpg";
po.src = "pop.gif";
function Canvas(){
var ctx = document.getElementById('my_canvas').getContext('2d');
var afst = 10;
function background () {
this.x = 0, this.y = 0, this.w = bg.width, this.h = bg.height;
this.draw = function() {
this.x -= 2;
ctx.drawImage(bg,this.x,this.y);
if(this.x <= -499) {this.x = 0;}
}
}
function blok () {
this.x = 0, this.y = 0, this.w = 40, this.h = 40, this.color = "orange";
this.draw = function() {
//ctx.fillStyle = this.color;
//ctx.fillRect(this.x,this.y,this.w,this.h);
ctx.drawImage(po,this.x,this.y);
}
}
var background = new background();
var blok = new blok();
function draw() {
ctx.save();
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
//draw
background.draw();
blok.draw();
ctx.restore();
}
var animateInterval = setInterval(draw,30);
document.addEventListener('keydown', function(event) {
var key_press = String.fromCharCode(event.keyCode);
//alert(event.keyCode+" | "+key_press);
if(event.keyCode == 40) { blok.y += afst}
if(event.keyCode == 37) { blok.x -= afst}
if(event.keyCode == 39) { blok.x += afst}
if(event.keyCode == 38) { blok.y -= afst}
if(event.keyCode == 32) { alert("hoi")}
});
}
window.addEventListener('load', function(event) {
Canvas();
});
</script>
<canvas id="my_canvas" width=1000px" height="500px">
Please get a new browser to watch canvas!
</canvas>
</body>
css/text is not a stylesheet format recognised by browsers, so they ignore your stylesheet. You mean text/css.
As of HTML 5, the type attribute is optional for style elements so omit it entirely and you avoid this kind of mistake.

Moving already Drawn shape on html5 canvas

I'm having trouble keeping one object on my canvas. The initially drawn box rendered it in the correct position, but it disappears when I drag it:
var canvas = document.getElementById('canvas'),
context = canvas.getContext('2d'),
eraseAllButton = document.getElementById('eraseAllButton'),
strokeStyleSelect = document.getElementById('strokeStyleSelect'),
guidewireCheckbox = document.getElementById('guidewireCheckbox'),
drawingSurfaceImageData,
mousedown = {},
rubberbandRect = {},
dragging = false,
guidewires = guidewireCheckbox.checked,
w = 90, h = 90;
count = 0;
boxesXCo = 0;
boxesYCo = 0;
i = 0;
// Functions..........................................................
function drawGrid(color, stepx, stepy) {
context.save()
context.strokeStyle = color;
context.lineWidth = 0.5;
context.clearRect(0, 0, context.canvas.width, context.canvas.height);
for (var i = stepx + 0.5; i < context.canvas.width; i += stepx) {
context.beginPath();
context.moveTo(i, 0);
context.lineTo(i, context.canvas.height);
context.stroke();
}
for (var i = stepy + 0.5; i < context.canvas.height; i += stepy) {
context.beginPath();
context.moveTo(0, i);
context.lineTo(context.canvas.width, i);
context.stroke();
}
context.restore();
}
function windowToCanvas(x, y) {
var bbox = canvas.getBoundingClientRect();
return { x: x - bbox.left * (canvas.width / bbox.width),
y: y - bbox.top * (canvas.height / bbox.height) };
}
// Save and restore drawing surface...................................
function saveDrawingSurface() {
drawingSurfaceImageData = context.getImageData(0, 0,
canvas.width,
canvas.height);
}
function restoreDrawingSurface() {
context.putImageData(drawingSurfaceImageData, 0, 0);
}
function drawRubberbandShape(loc) {
context.beginPath();
context.moveTo(mousedown.x, mousedown.y);
//context.lineTo(loc.x, loc.y);
context.stroke();
}
function updateRubberband(loc) {
//updateRubberbandRectangle(loc);
context.restore();
drawRubberbandShape(loc);
}
// Guidewires.........................................................
function drawHorizontalLine (y) {
context.beginPath();
context.moveTo(0,y+0.5);
context.lineTo(context.canvas.width,y+0.5);
context.stroke();
}
function drawVerticalLine (x) {
context.beginPath();
context.moveTo(x+0.5,0);
context.lineTo(x+0.5,context.canvas.height);
context.stroke();
}
function drawGuidewires(x, y) {
context.save();
context.strokeStyle = 'rgba(0,0,230,0.4)';
context.lineWidth = 0.5;
drawVerticalLine(x);
drawHorizontalLine(y);
context.restore();
}
// Canvas event handlers..............................................
canvas.onmousedown = function (e) {
var loc = windowToCanvas(e.clientX, e.clientY);
e.preventDefault(); // prevent cursor change
context.restore();
saveDrawingSurface();
mousedown.x = loc.x;
mousedown.y = loc.y;
dragging = true;
if (i ==0)
i++;
else if(((mousedown.x<=(boxesXCo+w)&&(mousedown.x>=boxesXCo))&&
((mousedown.y<=(boxesYCo+h)&&(mousedown.y>=boxesYCo)))))
i--;
};
canvas.onmousemove = function (e) {
var loc;
if (dragging) {
e.preventDefault(); // prevent selections
loc = windowToCanvas(e.clientX, e.clientY);
restoreDrawingSurface();
//updateRubberband(loc);
if(guidewires) {
drawGuidewires(loc.x, loc.y);
}
}
if(((mousedown.x<=(boxesXCo+w)&&(mousedown.x>=boxesXCo))&&
((mousedown.y<=(boxesYCo+h)&&(mousedown.y>=boxesYCo))))
&& (dragging)&&(i == 1 )){
context.restore();
restoreDrawingSurface();
context.fillStyle = strokeStyleSelect.value;
context.fillRect(e.clientX,e.clientY,w,h);
};
//Trying to implement moving shapes but need to store values of drawn objs
};
canvas.onmouseup = function (e) {
loc = windowToCanvas(e.clientX, e.clientY);
restoreDrawingSurface();
updateRubberband(loc);
dragging = false;
if(i == 0);
else {
saveDrawingSurface();
restoreDrawingSurface();
context.fillRect(e.clientX,e.clientY, w, h);
boxesXCo = e.clientX;
boxesYCo = e.clientY;
context.restore();
i++;}
/*else if(i == 1)
{
context.restore();
}*/
//context.fillRect(mousedown.x,mousedown.y,w,h,"FF0982");
};
// Controls event handlers.......................................
eraseAllButton.onclick = function (e) {
context.clearRect(0, 0, canvas.width, canvas.height);
drawGrid('lightgray', 10, 10);
saveDrawingSurface();
count =0;
context.restore();
};
strokeStyleSelect.onchange = function (e) {
context.strokeStyle = strokeStyleSelect.value;
context.fillStyle = strokeStyleSelect.value;
};
guidewireCheckbox.onchange = function (e) {
guidewires = guidewireCheckbox.checked;
};
// Initialization................................................
context.strokeStyle = strokeStyleSelect.value;
context.fillStyle = strokeStyleSelect.value;
drawGrid('lightgray', 10, 10);
//context.fillRect(mousedown.x,mousedown.y,(mousedown.x+50),(mousedown.x+50),"FF0982");
//context.drawRect(mousedown.x-50,mousedown.y-50,mousedown.x+50,mousedown.y+50);
thanx again
Rather than drawing to canvas on each mouse movement, use window.requestFrameAnimation to draw constantly.
At a guess, I'd assume either the browser rendering is interfering or the coordinates are out but I can't run your code to make sure.
I've written some pseudo code that shows what I do for rendering things. You'll need to implement this for yourself, it won't run out of the box, it's just intended as a guide.
var Box = function() {
};
Box.prototype = {
x: 0,
y: 0,
draw: function (canvas) {
// draw the item on the canvas
}
};
var box = new Box();
window.requestAnimationFrame(function() {
box.draw(canvas);
window.requestAnimationFrame();
});
canvas.onmousemove = function(e) {
if (dragging) {
box.x = e.clientX;
box.y = e.clientY;
}
}

How to pass image from one jsp to another jsp

On a button click I call a script to get the canvas Image. I take the location. I need to pass this image source into another jsp file where I need to display this image.
Can you please help me out in this.
<%# page contentType="text/html;charset=UTF-8" %>
<html>
<head>
<script>
function draw() {
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "black";
ctx.beginPath();
var x;
var y;
canvas.onmousedown = function(e) {
x = e.clientX;
y = e.clientY;
ctx.moveTo(x, y);
}
canvas.onmouseup = function(e) {
x = null;
y = null;
}
canvas.onmousemove = function(e) {
if (x == null || y == null) {
return;
}
x = e.clientX;
y = e.clientY;
x -= canvas.offsetLeft;
y -= canvas.offsetTop;
ctx.lineTo(x, y);
ctx.stroke();
ctx.moveTo(x, y);
}
};
function to_image(){
var canvas = document.getElementById("canvas");
document.getElementById("theimage").src = canvas.toDataURL();
}
function clear_image(){
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
context.fillStyle = '#ffffff';
context.clearRect(0, 0, canvas.width, canvas.height);
canvas.width = canvas.width;
}
</script>
</head>
<body onload="draw();">
<canvas id="canvas" width="300" height="300"
style="border: 1px solid black;"></canvas>
<div><button onclick="to_image()">Draw to Image</button></div>
<div><button onclick="clear_image()">Clear</button></div>
<image id="theimage"></image>
</body>
</html>
I need to pass the value of document.getElementById("theimage").src into another jsp and access that value to dispaly the image.
Can anybody help me out in this.
If you meant you will load that second page with image on a button click from the first page(for which you have pasted code)then just update the code as:
{
var canvas = document.getElementById("canvas");
var dataUrl = canvas.toDataURL();
//-- Following code can be placed wherever you want to call another page.
window.location = "urlToSecondJSPPage.jsp?imgUrl="+dataUrl;
}
And then imgUrl(url parameter) can be accessed from second page.

Draw on HTML5 Canvas using a mouse

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?
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>
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!
}
Here's the most straightforward way to create a drawing application with canvas:
Attach a mousedown, mousemove, and mouseup event listener to the canvas DOM
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.
on mousemove, continuously add a new point to the path with lineTo(), and color the last segment with stroke().
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.
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();
};
}());
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>
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>
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>
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>
I took the first answer and Changed as per my need.
Now
Works on mobile device also.
more responsive,
no issue with scroll
<html>
<head>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.2/dist/css/bootstrap.min.css" integrity="sha384-xOolHFLEh07PJGoPkLv1IbcEPTNtaed2xpHsD9ESMhqIYd0nLMwNLD69Npy4HI+N" crossorigin="anonymous">
<style>
.selected::before {
content: 'x';
height: 30px;
width: 30px;
left: 18px;
top: -8px;
font-size: 3rem;
position: absolute;
}
.select-colour{
height: 30px;
width: 30px;
}
</style>
</head>
<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);
canvas.addEventListener("touchmove", function (e) {
findxy('move', e, 'touch')
}, false);
canvas.addEventListener("touchstart", function (e) {
findxy('down', e, 'touch')
}, false);
canvas.addEventListener("touchend", function (e) {
findxy('up', e, 'touch')
}, false);
}
function color(obj) {
x = obj.id;
if (x == "white") y = 14;
else y = 2;
var prevSelected = document.getElementsByClassName("selected");
// If it exists, remove it.
if(prevSelected.length > 0) {
prevSelected[0].classList.remove("selected");
}
document.getElementById(obj.id).classList.add("selected");
}
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 download() {
var link = document.createElement('a');
var dataURL = canvas.toDataURL();
link.href = dataURL;
link.download = 'mydrawing.png';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
function findxy(res, e, source) {
if(source){
var clientX = e.changedTouches[0].clientX;
var clientY = e.changedTouches[0].clientY;
}else{
var clientX = e.clientX;
var clientY = e.clientY;
}
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = clientX - canvas.getBoundingClientRect().left;
currY = 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 = clientX - canvas.getBoundingClientRect().left;
currY = clientY - canvas.getBoundingClientRect().top;
draw();
}
}
}
</script>
<body onload="init()">
<div style="">
<div style="float: left;">
<canvas id="can" width="600" height="500" style=" border:5px solid;"></canvas>
</div>
<div style="margin-left:20px; float:left;">
<div class="row">
<div class="col-12">Choose Color</div>
<div class="col-2 pt-3"><div class="select-colour" style="background:green;" id="green" onclick="color(this)"></div></div>
<div class="col-2 pt-3"><div class="select-colour" style="background:blue;" id="blue" onclick="color(this)"></div></div>
<div class="col-2 pt-3"><div class="select-colour" style="background:red;" id="red" onclick="color(this)"></div></div>
<div class="col-2 pt-3"><div class="select-colour" style="background:yellow;" id="yellow" onclick="color(this)"></div></div>
<div class="col-2 pt-3"><div class="select-colour" style="background:orange;" id="orange" onclick="color(this)"></div></div>
<div class="col-2 pt-3"><div class="select-colour" style="background:black;" id="black" onclick="color(this)"></div></div>
<div class="col-12 pt-3 pb-3" style="">Eraser</div>
<div class="col-2 pt-3"><div class="select-colour" style="background:white;border:2px solid;" id="white" onclick="color(this)"></div></div>
</div>
<div class="row">
<div class="col-6 col-lg-12 mt-3">
<input type="button" value="Download" id="download" size="23" onclick="download()" class="btn btn-primary">
</div>
<div class="col-6 col-lg-12 mt-3">
<input type="button" value="clear" id="clr" size="23" onclick="erase()" class="btn btn-light">
</div>
</div>
</div>
</div>
</body>
</html>
Also check this one here:
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/
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>
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>
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>