I have the following code that will allow me to draw pictures on a canvas, similar to MS Paint. So, once the user presses down on the left mouse button he/she can move the mouse across the canvas to draw a picture. Drawing stops once the user lifts their finger off of the mouse button.
var colors = document.querySelectorAll('#colors div');
var link = document.getElementById('download');
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var drawing = false;
var prev;
document.getElementById('current').style.backgroundColor = context.strokeStyle;
for (var i = 0; i < colors.length; i++) {
colors[i].addEventListener('click', function(e) {
var src = e.srcElement;
var color = src.style.backgroundColor;
context.strokeStyle = color;
document.getElementById('current').style.backgroundColor = color;
});
colors[i].style.height = 100 / colors.length + '%';
colors[i].style.backgroundColor = colors[i].id;
}
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
link.addEventListener('click', function() {
link.href = canvas.toDataURL();
link.download = 'image.png';
});
canvas.addEventListener('mousedown', function(e) {
drawing = true;
});
canvas.addEventListener('mousemove', function(e) {
if (drawing) {
var coord = {
'x': e.clientX - this.offsetLeft,
'y': e.clientY - this.offsetTop
};
if (prev !== undefined) {
context.beginPath();
context.moveTo(prev.x, prev.y);
context.lineTo(coord.x, coord.y);
context.stroke();
}
prev = coord;
}
});
canvas.addEventListener('mouseup', function() {
drawing = false;
prev = undefined;
});
#draw {
border: 2px outset black;
border-radius: 5px;
display: inline-block;
margin: 5px;
padding: 10px;
}
#container {
border: 2px solid black;
width: 300px;
height: 300px;
position: relative;
}
#canvas {
background-color: lightgrey;
}
#colors {
float: right;
position: relative;
width: 20%;
height: 100%;
}
#colors div {
width: 100%
}
#buttons {
width: 100%;
height: auto;
}
#buttons * {
width: 33%;
background-color: lightgrey;
margin-top: 5px;
margin-left: 5px;
display: inline;
}
#download {
text-align: center;
border-radius: 2px;
padding-left: 5px;
padding-right: 5px;
border: 2px outset lightgrey;
font-family: 'Arial';
background-color: lightgrey;
font-size: 10pt;
cursor: context-menu;
}
#download:link {
text-decoration: none;
color: black;
}
#download:active {
border: 2px inset #00acff;
border-radius: 2px;
}
#current {
height: 100%;
width: 10%;
border: 1px solid black;
display: inline;
position: relative;
margin-left: 25px;
}
<div id='draw'>
<div id='container'>
<canvas id='canvas' width='240' height='300'></canvas>
<div id='colors'>
<div id='red'></div>
<div id='blue'></div>
<div id='green'></div>
<div id='black'></div>
<div id='yellow'></div>
<div id='cyan'></div>
<div id='magenta'></div>
</div>
<div id='currentColor'></div>
</div>
<div id='buttons'>
<input type='button' id='clear' value='Clear Canvas' onclick='clearCanvas()' />
<a id='download'>Download Image</a>
<input type='button' id='current' />
</div>
</div>
http://jsfiddle.net/SirToadstool/eywraw8t/341261/
Now while this code works within JSFiddle, testing it outside has lines that the user draws being of different coordinates than that of the mouse pointer.
I have a feeling that the CSS I have included within the code may be messing up how the coordinates get calculated in the Javascript, but I'm unsure of what to change to compensate, and have tried using clientX/Y
and screenX/Y
for coordinates instead of just event.x/event.y
.
Any suggestions as to how I can correct calculating the coordinates when drawing?