Reputation: 608
I am trying to draw a line using canvas. While drawing a line my mouse pointer coordinates and canvas coordinates are mismatching. If I drag mouse at top of my canvas it draws a line at bottom. Can anyone identify what I am doing wrong here. I tried the below example.
Fiddle : https://jsfiddle.net/Shathiran/bpunb9dn/5/
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('drawCanvas');
ctx = canvas.getContext("2d");
w = ctx.clientWidth;
h = ctx.clientHeight;
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.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();
}
}
}
init();
<div class="paper">
<canvas id="drawCanvas" style="width:100%; height:100%;border: 1px solid #000"> </canvas>
</div>
Upvotes: 1
Views: 2424
Reputation: 21575
You are getting the mouse positions fine. The problem here is how you are assigning the width
and height
of your canvas, mainly because you are setting it via CSS as a style (which "stretches" the canvas) other that the width
and height
attributes (see this question for more information). To fix this set your width/height
as HTML attributes to your canvas.
For example:
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('drawCanvas');
canvas.setAttribute('width', canvas.parentNode.offsetWidth);
canvas.setAttribute('height', canvas.parentNode.offsetHeight);
ctx = canvas.getContext("2d");
w = ctx.clientWidth;
h = ctx.clientHeight;
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;
var cRect = canvas.getBoundingClientRect();
currX = e.clientX - cRect.offsetLeft;
currY = e.clientY - cRect.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();
}
}
}
init();
<div class="paper" width="400">
<canvas id="drawCanvas" width="200" height="200" style="border: 1px solid #000"> </canvas>
</div>
Note you can set the canvas height and width to 100% by using window.innerWidth
and window.innerHeight
. Although if you want it to dyncamically change you need to update it on resize:
canvas.setAttribute('width', window.innerWidth);
canvas.setAttribute('height', window.innerHeight);
Upvotes: 4