Reputation: 33
I'm having trouble with my HTML canvas, was working fine in its experimental stage however once I brought it into my proper development the mouse coordinates have become completely wonky, It does draw, however not in the correct position i.e. I click and drag to draw a line, that line is the draw further down within the canvas. I'm just looking to fix the coordinates in so the mouse cursor draws exactly where it should be.
Below is my code, In order to get a sense of what Im talking about be sure to resize the browser window as the website is mobile specific. Thank you any help would be much appreciated
Ive tried using getXY
functions but I already have a variable name after that but it didn't work. I also tried various styling techniques but to no avail
function init() {
// Get the specific canvas element from the HTML document
canvas = document.getElementById('c');
}
function midPointBtw(p1, p2) {
return {
x: p1.x + (p2.x - p1.x) / 2,
y: p1.y + (p2.y - p1.y) / 2
};
}
function getPattern() {
return ctx.createPattern(img, 'repeat');
}
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 15;
ctx.lineJoin = ctx.lineCap = 'round';
var img = new Image;
img.onload = function() {
ctx.strokeStyle = getPattern();
};
img.src = "https://i.postimg.cc/rF2R0GRY/dick2.png";
var isDrawing, points = [];
var getXY = function(e) {
var source = e.touches ? e.touches[0] : e;
return {
x: source.clientX,
y: source.clientY
};
};
var startDrawing = function(e) {
isDrawing = true;
points.push(getXY(e));
e.preventDefault();
};
var keepDrawing = function(e) {
if (!isDrawing) return;
points.push(getXY(e));
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
var p1 = points[0];
var p2 = points[1];
ctx.moveTo(p1.x, p1.y);
for (var i = 1, len = points.length; i < len; i++) {
var midPoint = midPointBtw(p1, p2);
ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
p1 = points[i];
p2 = points[i + 1];
}
ctx.lineTo(p1.x, p1.y);
ctx.stroke();
e.preventDefault();
};
var stopDrawing = function() {
isDrawing = false;
points = [];
};
el.addEventListener('touchstart', startDrawing);
el.addEventListener('mousedown', startDrawing);
el.addEventListener('touchmove', keepDrawing);
el.addEventListener('mousemove', keepDrawing);
el.addEventListener('touchend', stopDrawing);
el.addEventListener('mouseup', stopDrawing);
function clearCanvas(canvas, ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath()
}
init();
@font-face {
font-family: Geoma Regular Demo;
src: url(Geoma Regular Demo.otf);
}
@font-face {
font-family: Geoma Demo;
src: url(Geoma Light demo.otf);
}
@media screen and (max-width: 425px) {
html,
body {
overflow-x: hidden;
width: 100%;
margin: 0;
}
}
canvas {
border: 3px solid #0BF446;
border-radius: 15px 0px 15px 0px;
display: block;
margin: 0 auto;
margin-top: 35px;
}
#clearbutton {
background-color: #04A12B;
border-radius: 0 15px 0 15px;
padding: 20px;
margin: 0 auto;
display: block;
font-size: 14px;
color: white;
font-family: Geoma Demo;
margin-top: 35px;
}
#footer1 {
background-color: #00671A;
border-radius: 30px 30px 0px 0px;
text-align: center;
padding: 30px;
margin-top: 35px;
}
#about {
color: white;
font-size: 16px;
font-family: Geoma Demo;
}
<canvas id="c" width="350" height="500"></canvas>
<input type="submit" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">
<footer id="footer1">
<a href="" id="about">About Elemental</a>
</footer>
Upvotes: 1
Views: 1535
Reputation: 26920
You will need to localize your click event to be relative to the canvas element. You can do this by getting the top
and left
out of el.getBoundingClientRect()
and using them to adjust the x
and y
value of your click event. See below, most of the work was done in the getXY
function.
function init() {
// Get the specific canvas element from the HTML document
canvas = document.getElementById('c');
}
function midPointBtw(p1, p2) {
return {
x: p1.x + (p2.x - p1.x) / 2,
y: p1.y + (p2.y - p1.y) / 2
};
}
function getPattern() {
return ctx.createPattern(img, 'repeat');
}
var el = document.getElementById('c');
var ctx = el.getContext('2d');
ctx.lineWidth = 15;
ctx.lineJoin = ctx.lineCap = 'round';
var img = new Image;
img.onload = function() {
ctx.strokeStyle = getPattern();
};
img.src = "https://i.postimg.cc/rF2R0GRY/dick2.png";
var isDrawing, points = [];
var getXY = function(e) {
var source = e.touches ? e.touches[0] : e;
const {
clientX,
clientY
} = source;
const {
left,
top
} = el.getBoundingClientRect();
const x = clientX - left;
const y = clientY - top;
return {
x,
y
};
};
var startDrawing = function(e) {
isDrawing = true;
points.push(getXY(e));
e.preventDefault();
};
var keepDrawing = function(e) {
if (!isDrawing) return;
points.push(getXY(e));
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
var p1 = points[0];
var p2 = points[1];
ctx.moveTo(p1.x, p1.y);
for (var i = 1, len = points.length; i < len; i++) {
var midPoint = midPointBtw(p1, p2);
ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
p1 = points[i];
p2 = points[i + 1];
}
ctx.lineTo(p1.x, p1.y);
ctx.stroke();
e.preventDefault();
};
var stopDrawing = function() {
isDrawing = false;
points = [];
};
el.addEventListener('touchstart', startDrawing);
el.addEventListener('mousedown', startDrawing);
el.addEventListener('touchmove', keepDrawing);
el.addEventListener('mousemove', keepDrawing);
el.addEventListener('touchend', stopDrawing);
el.addEventListener('mouseup', stopDrawing);
function clearCanvas(canvas, ctx) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath()
}
init();
@font-face {
font-family: Geoma Regular Demo;
src: url(Geoma Regular Demo.otf);
}
@font-face {
font-family: Geoma Demo;
src: url(Geoma Light demo.otf);
}
@media screen and (max-width: 425px) {
html,
body {
overflow-x: hidden;
width: 100%;
margin: 0;
}
}
canvas {
border: 3px solid #0BF446;
border-radius: 15px 0px 15px 0px;
display: block;
margin: 0 auto;
margin-top: 35px;
}
#clearbutton {
background-color: #04A12B;
border-radius: 0 15px 0 15px;
padding: 20px;
margin: 0 auto;
display: block;
font-size: 14px;
color: white;
font-family: Geoma Demo;
margin-top: 35px;
}
#footer1 {
background-color: #00671A;
border-radius: 30px 30px 0px 0px;
text-align: center;
padding: 30px;
margin-top: 35px;
}
#about {
color: white;
font-size: 16px;
font-family: Geoma Demo;
}
<canvas id="c" width="350" height="500"></canvas>
<input type="submit" value="Clear Sketchpad" id="clearbutton" onclick="clearCanvas(canvas,ctx);">
<footer id="footer1">
<a href="" id="about">About Elemental</a>
</footer>
Upvotes: 5