convert to es6 without breaking the functionality of code - javascript

I want to convert my working code into Es6 without braking. Can anyone help me. I have tried to convert it into es6 but something went wrong and my code didn't work. Must of the time I have used es5 and so I am looking for any kind of help. The following program allows user to draw on canvas
I really appreciate your answer.
var flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false,
ratio;
function init(fieldId) {
//fieldId are multiple Ids, but I get here one at a time
let canvas = document.getElementById("can-" + fieldId);
let ctx = canvas.getContext("2d");
ratio = 400 / 800;
canvas.width =
document.body.clientWidth < 800 ? document.body.clientWidth : 800;
canvas.height = canvas.width * ratio;
function draw(ctx) {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function findxy(res, e, c) {
let ctx = c.getContext("2d");
if (res == "down") {
prevX = currX;
prevY = currY;
currX = e.clientX - c.getBoundingClientRect().left;
currY = e.clientY - c.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 - c.getBoundingClientRect().left;
currY = e.clientY - c.getBoundingClientRect().top;
draw(ctx);
}
}
}
function resizeCanvas(canvas) {
ratio = 400 / 800;
canvas.width =
document.body.clientWidth < 800 ? document.body.clientWidth : 800;
canvas.height = canvas.width * ratio;
}
img {
display: none;
}

There's a package called Lebab for converting es5 to es6.
Lebal documentation

Related

resize canvas and paint on right place

I have a canvas and I have loaded an Image on canvas. I can paint on the canvas
but in small browser size, some part of canvas will be hidden. So i have
used jQuery resize and it resize the canvas and show full image inside it and this is fine .
It resize canvas and full image is displayed. However, If I now paint on it , it paints/draws
far away the actual place. It happens only in resizing canvas but not on the full width of
browser. Is there any way to solve this issue.
I am looking for a ways to resize canvas and show full image on small device and should paint on actual place not far away.
Initially I want to show abit bigger canvas of width alteast 800px and height 400px
<canvas data-fieldid="1" id="can-1"class="image-canvas"></canvas>
Below is the js code that allows user to draw on image of canvas
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
sdsdfds
<script>
var flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "red",
y = 3;
function init(fieldId) {
//fieldId are multiple Ids, but I get here one at a time
let canvas = document.getElementById('can-' + fieldId);
let ctx = canvas.getContext("2d");
ratio = 400 / 800;
canvas.width =
document.body.clientWidth < 800 ? document.body.clientWidth : 800;
canvas.height = canvas.width * ratio;
let base_image = new Image();
base_image.crossOrigin = "anonymous"
base_image.src = document.getElementById('image_' + fieldId).src
base_image.onload = function() {
ctx.drawImage(base_image,0,0,canvas.width, canvas.height);
};
canvas.addEventListener("mousemove", function(e) {
findxy('move', e, this)
}, false);
canvas.addEventListener("mousedown", function(e) {
findxy('down', e, this)
}, false);
canvas.addEventListener("mouseup", function(e) {
findxy('up', e, this)
}, false);
canvas.addEventListener("mouseout", function(e) {
findxy('out', e, this)
}, false);
}
function draw(ctx) {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function findxy(res, e,c) {
let ctx = c.getContext('2d');
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - c.getBoundingClientRect().left;
currY = e.clientY - c.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 - c.getBoundingClientRect().left;
currY = e.clientY - c.getBoundingClientRect().top;
draw(ctx);
}
}
}
$(document).ready(function() {
$(".image-canvas").each(function(canvas) {
init($(this).data("fieldid"));
});
});
</script>
The issue is CSS. When using 100% width and heights you will have issues. You can set the image width to the clientWidth and use the image ratio to maintain aspect. Use an event listener for resize to have the canvas change size is a browser is resized. Using an if statment we can have a max width of 800 and anything less is the clientWidth.
You mouse position should now be accurate without CSS.
var flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false,
ratio;
var x = "red",
y = 3;
function init(fieldId) {
//fieldId are multiple Ids, but I get here one at a time
let canvas = document.getElementById("can-" + fieldId);
let ctx = canvas.getContext("2d");
ratio = 400 / 800;
canvas.width =
document.body.clientWidth < 800 ? document.body.clientWidth : 800;
canvas.height = canvas.width * ratio;
let base_image = new Image();
base_image.crossOrigin = "anonymous";
base_image.src = document.getElementById("image_" + fieldId).src;
base_image.onload = function () {
ctx.drawImage(base_image, 0, 0, canvas.width, canvas.height);
};
canvas.addEventListener(
"mousemove",
function (e) {
findxy("move", e, this);
},
false
);
canvas.addEventListener(
"mousedown",
function (e) {
findxy("down", e, this);
},
false
);
canvas.addEventListener(
"mouseup",
function (e) {
findxy("up", e, this);
},
false
);
canvas.addEventListener(
"mouseout",
function (e) {
findxy("out", e, this);
},
false
);
window.addEventListener("resize", () => {
resizeCanvas(canvas)
ctx.drawImage(base_image, 0, 0, canvas.width, canvas.height);
})
}
function draw(ctx) {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function findxy(res, e, c) {
let ctx = c.getContext("2d");
if (res == "down") {
prevX = currX;
prevY = currY;
currX = e.clientX - c.getBoundingClientRect().left;
currY = e.clientY - c.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 - c.getBoundingClientRect().left;
currY = e.clientY - c.getBoundingClientRect().top;
draw(ctx);
}
}
}
$(document).ready(function () {
$(".image-canvas").each(function (canvas) {
//console.log($(this).data("fieldid"))
init($(this).data("fieldid"));
});
});
function resizeCanvas(canvas) {
ratio = 400 / 800;
canvas.width =
document.body.clientWidth < 800 ? document.body.clientWidth : 800;
canvas.height = canvas.width * ratio;
}
img {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<canvas data-fieldid='1'
id="can-1"
class="image-canvas"
style="position:absolute;top:10px;border:1px dotted;">
</canvas>
<canvas data-fieldid='2'
id="can-2"
class="image-canvas"
style="position:absolute;top:450px;border:1px dotted;">
</canvas>
<img src="https://images.unsplash.com/photo-1494548162494-384bba4ab999?ixid=MnwxMjA3fDB8MHxzZWFyY2h8MXx8c3VucmlzZXxlbnwwfHwwfHw%3D&ixlib=rb-1.2.1&w=1000&q=80" alt='view' id="image_1" class="images" />
<img src="https://media.istockphoto.com/photos/colored-powder-explosion-abstract-closeup-dust-on-backdrop-colorful-picture-id1072093690?k=6&m=1072093690&s=612x612&w=0&h=Eyk67XBt4sr3Bk1MubM6dHpvEVNICX4L7FumWhcTwuY=" alt='view' id="image_2" class="images" />

how to make drawable on dynamic canvas

I have display canvas dynamically based on records in db. Currently I have
two records in db and it shows two canvas in page.Now i should able to draw
on both cannvas however I can only draw on last canvas not on the both canvas.
Please check the image https://ibb.co/n7rvdk5 for more.
I am getting id 609 and 610.It can be 1,2 etc. This id are passed on canvas id to make it unique.
<div class="snap-field col-sm-12" style="height: 450px;">
loop here
<canvas data-fieldid="{{$draw->id}}"
id="image-canvas-{{$draw->id}}"
width="400" height="200"
class="image-canvas"
style="position:absolute;">
</canvas>
</div>
This is my js part and within document.ready function i have loaded the canvas . initEditableImageCanvas takes unique id. for example in this case it takes 609 and 610.I can draw on canvas with id 610 but not on 609.Maybe I need to make some changes here and I am not sure what should I do
<script>
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "red",
y = 2;
function initEditableImageCanvas(fieldId) {
canvas = document.getElementById('image-canvas-' + fieldId);
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();
}
}
}
$(document).ready(function() {
$(".image-canvas").each(function(canvas) {
//get id
initEditableImageCanvas($(this).data("fieldid"));
});
});
</script>
I am looking for help to fix it. I want draw in all canvas.
Any help? Thanks
In order to draw on a canvas, you can store it in a variable so that you are able to apply your logic.
let canvas = document.getElementById('canvasId');
let ctx = canvas.getContext('2d')
/*
Logic
*/
However, in your case, it turns out that since canvas and ctx are global variables, they get reassigned each time initEditableImageCanvas() is called within jQuery's each().
So even though the function findxy() is called whenever one event (i.e. mousemove) happens, it's not sufficient to draw on the right places. You
have to check if it is pointing to the right canvas.
This said, to prevent unexpected behaviors, prefer using local variables defined with let statement instead of global ones when working with multiple drawable canvas. One solution follows:
Change var -> let
Add a third parameter (c) to findxy()
Add an parameter (ctx) to draw()
// get rid of global canvas and ctx
var flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "red",
y = 2;
function initEditableImageCanvas(fieldId) {
// use let
let canvas = document.getElementById('editable-image-canvas-' + fieldId);
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
/*
Attach this to each findxy
*/
canvas.addEventListener("mousemove", function(e) {
findxy('move', e, this)
}, false);
canvas.addEventListener("mousedown", function(e) {
findxy('down', e, this)
}, false);
canvas.addEventListener("mouseup", function(e) {
findxy('up', e, this)
}, false);
canvas.addEventListener("mouseout", function(e) {
findxy('out', e, this)
}, false);
}
function draw(ctx) {
// added parameter ctx
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function findxy(res, e, c) {
// added parameter c and local ctx
let ctx = c.getContext('2d')
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - c.getBoundingClientRect().left;
currY = e.clientY - c.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 - c.getBoundingClientRect().left;
currY = e.clientY - c.getBoundingClientRect().top;
draw(ctx); // added argument
}
}
}
$(document).ready(function() {
$(".editable-image-canvas").each(function(canvas) {
// alert($(this).data("fieldid")) //give id 609 and 610
initEditableImageCanvas($(this).data("fieldid"));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="snap-field col-sm-12" style="height: 450px;"> <div style="display:grid;"> <span>609</span> <canvas data-fieldid="609" id="editable-image-canvas-609" width="200" height="150" class="editable-image-canvas" style="position:relative;top:10%;border:1px dotted; margin-bottom:30px;"> </canvas> <span>610</span> <canvas data-fieldid="610" id="editable-image-canvas-610" width="200" height="150" class="editable-image-canvas" style="position:relative;top:10%;border:1px dotted;"> </canvas> </div><input type="hidden" name="field_{{$draw->id}}" id="editable-image-hidden-{{$draw->id}}"></div>

unable to draw on multiple canvas

How to load multiple canvas and enable drawing on it. Currently, It shows two canvas on my page but I can only draw in one canvas.
I have two records in database. foreach loop below make two canvas but I can only draw in only one canvas not on the both canvas. I should able to draw on both canvas and that is the things I want. I am looking for any help or any tips on how should I do so that I can draw on all canvas generated dynamically.
<body onload="init()">
<canvas id="can_{{$draw->id}}" width="1200" height="400"
style="position:absolute;top:10%;left:10%;border:2px solid;">
</canvas>
</body>
Below is the js code that allows user to draw on image of canvas
<script type="text/javascript">
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "red",
y = 2;
function init() {
for(let i=1;i<3;i++){
canvas = document.getElementById('can_'+i);
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);
}//end of for
}
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();
}
}
}
</script>
Try something similar to this. Add the context to an array and see if you can draw to both. Not exactly sure the context thing is your problem but I think it is.
let canvas1 = document.getElementById("c1");
let canvas2 = document.getElementById("c2");
let ctx1 = canvas1.getContext("2d");
let ctx2 = canvas2.getContext("2d");
let ctx = [ctx1, ctx2];
function draw() {
ctx.forEach((ctx, i) => {
ctx.fillStyle = "lightblue";
ctx.fillRect(10, 10, 100, 100)
});
}
draw()
<canvas id='c1'></canvas>
<canvas id='c2'></canvas>
Adding what #Kaiido said for performance
let canvas1 = document.getElementById("c1");
let canvas2 = document.getElementById("c2");
let ctx1 = canvas1.getContext("2d");
let ctx2 = canvas2.getContext("2d");
ctx1.fillStyle = "lightblue";
ctx1.fillRect(50, 50, 100, 100)
ctx2.drawImage(canvas1, 0, 0)
<canvas id='c1'></canvas>
<canvas id='c2'></canvas>
Here's a solution that makes use of the fact we know which canvas generated a mouse event. Since we know that, we can use it to get the context of the correct canvas.
I show a message for mousemove and mousedown, indicating which canvas triggered the event.
<!doctype html>
<html>
<head>
<script>
"use strict";
var canvas, ctx, flag = false,
prevx = 0,
curx = 0,
prevy = 0,
cury = 0,
dot_flag = false;
var x = "red",
y = 2;
window.addEventListener('load', onLoaded, false);
function onLoaded(evt)
{
let canvasElems = document.querySelectorAll('canvas');
canvasElems.forEach(
can => {
can.addEventListener('mousemove', function(evt){ findxy('move', evt, this);}, false);
can.addEventListener('mousedown', function(evt){ findxy('down', evt, this);}, false);
can.addEventListener('mouseup', function(evt){ findxy('up', evt, this);}, false);
can.addEventListener('mouseout', function(evt){ findxy('out', evt, this);}, false);
} );
}
function findxy(reason, evt, elem)
{
if (reason=='up' || reason=='out')
flag = false;
if (reason == 'down')
{
document.querySelector('#output').textContent = elem.getAttribute('name') + ' was clicked';
prevx = curx;
prevy = cury;
curx = evt.clientX - elem.getBoundingClientRect().left;
cury = evt.clientY - elem.getBoundingClientRect().top;
flag = true;
dot_flag = true;
//if (dot_flag)
//{
let ctx = elem.getContext('2d');
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(curx, cury, 2, 2);
ctx.closePath();
dot_flag = false;
//}
}
else if (reason == 'move')
{
document.querySelector('#output').textContent = elem.getAttribute('name') + ' was moved over';
if (flag)
{
prevx = curx;
prevy = cury;
curx = evt.clientX - elem.getBoundingClientRect().left;
cury = evt.clientY - elem.getBoundingClientRect().top;
draw(elem);
}
}
}
function draw(tgtCanvas)
{
let ctx = tgtCanvas.getContext('2d');
ctx.beginPath();
ctx.moveTo(prevx, prevy);
ctx.lineTo(curx, cury);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
</script>
<style>
canvas
{
margin: 4px;
border: solid 1px #333;
}
</style>
</head>
<body>
<canvas name='canvas1'></canvas><canvas name='canvas2'></canvas>
</br>
<span id='output'></span>
</body>
</html>

html canvas drew far from actual drew point

I have a image inside canvas. When I paint it draw the line far from the actual point. I can't figure out why this is happening and how to fix it.
This is the script and it is taken from here. When I click in one point it draw in another point.
Draw on HTML5 Canvas using a mouse
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);
base_image = new Image();
base_image.src = document.getElementById("editable_image_path").src
base_image.onload = function() {
ctx.drawImage(base_image, 0, 0, 800, 400);
};
}
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();
}
}
}
<div class="snap-field col-sm-12" style="height: 800px;">
<body onload="init()">
<canvas id="can" width="1000" height="500"
style="border:1px solid;position:absolute;">
</canvas>
</body>
</div>
Instead of using canvas.offsetX and canvas.offsetY in the findXY function, use canvas.getBoundingClientRect().left and canvas.getBoundingClientRect().top. It will give you more reliable absolute coordinates for the canvas as the reference point for drawing.

Offset all Canvas Lines

I have the following canvas code:
<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 "blue":
x = "blue";
break;
case "red":
x = "red";
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>
However because of CSS having margin/padding/width/height on my parent elements, the canvas is returning an offset to the left and bottom, is there any way to forcefully apply a negative offset back to the mouse location or is it possible to just get the MOUSE location instead.
Use .getBoundingClientRect which accounts for CSS styling & repositioning:
var BB=canvas.getBoundingClientRect();
var BBoffsetX=BB.left;
var BBoffsetY=BB.top;
var mouseX=parseInt(e.clientX-BBoffsetX);
var mouseY=parseInt(e.clientY-BBoffsetY);

Categories