I am trying to paint over an image in a canvas and getting issue when the canvas css is different than the Canvas width/height:
The issue is that the brush doesn't start painting from the expected mouse click/touch, It starts painting far away from the cursor.
I could solve the issue by making the canvas bigger which will fit the defined sizes in
canvas2.width=960; canvas2.height=540;
, but i need to keep the size of the canvas small and the quality of the image high.
How can i keep the canvas small but the image resolution high?
// CANVAS
//__________________________
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
context.rect(0, 0, 284, 120);
context.lineWidth = 4;
context.strokeStyle = 'black';
context.stroke();
var canvas2 = document.getElementById('myCanvas2');
canvas2.width=960;
canvas2.height=540;
var context2 = canvas2.getContext('2d');
context2.beginPath();
context2.rect(0, 0, 960, 540);
context2.lineWidth = 4;
context2.strokeStyle = 'black';
context2.stroke();
var img=document.getElementById("dove");
context2.drawImage(img,0,0, canvas2.width, canvas2.height);
context.drawImage(img,0,0, canvas.width, canvas.height);
// BRUSH PAINT OVER IMAGE 2
//__________________________
// Brush colour and size
const colour = "#3d34a5";
const strokeWidth = 25;
// Drawing state
let latestPoint;
let drawing = false;
// Set up our drawing context
//const canvas = document.getElementById("canvas");
//const context = canvas.getContext("2d");
let brush;
// Drawing functions
const continueStroke = newPoint => {
context2.beginPath();
context2.moveTo(latestPoint[0], latestPoint[1]);
context2.strokeStyle = colour;
context2.lineWidth = strokeWidth;
context2.lineCap = "round";
context2.lineJoin = "round";
context2.lineTo(newPoint[0], newPoint[1]);
context2.stroke();
latestPoint = newPoint;
};
// Event helpers
const startStroke = point => {
drawing = true;
latestPoint = point;
};
const getTouchPoint = evt => {
if (!evt.currentTarget) {
return [0, 0];
}
const rect = evt.currentTarget.getBoundingClientRect();
const touch = evt.targetTouches[0];
return [touch.clientX - rect.left, touch.clientY - rect.top];
};
const BUTTON = 0b01;
const mouseButtonIsDown = buttons => (BUTTON & buttons) === BUTTON;
// Event handlers
const mouseMove = evt => {
if (!drawing) {
return;
}
continueStroke([evt.offsetX, evt.offsetY]);
};
const mouseDown = evt => {
if (drawing) {
return;
}
evt.preventDefault();
canvas2.addEventListener("mousemove", mouseMove, false);
startStroke([evt.offsetX, evt.offsetY]);
};
const mouseEnter = evt => {
if (!mouseButtonIsDown(evt.buttons) || drawing) {
return;
}
mouseDown(evt);
};
const endStroke = evt => {
if (!drawing) {
return;
}
drawing = false;
evt.currentTarget.removeEventListener("mousemove", mouseMove, false);
};
const touchStart = evt => {
if (drawing) {
return;
}
evt.preventDefault();
startStroke(getTouchPoint(evt));
};
const touchMove = evt => {
if (!drawing) {
return;
}
continueStroke(getTouchPoint(evt));
};
const touchEnd = evt => {
drawing = false;
};
// Register event handlers
canvas2.addEventListener("touchstart", touchStart, false);
canvas2.addEventListener("touchend", touchEnd, false);
canvas2.addEventListener("touchcancel", touchEnd, false);
canvas2.addEventListener("touchmove", touchMove, false);
canvas2.addEventListener("mousedown", mouseDown, false);
canvas2.addEventListener("mouseup", endStroke, false);
canvas2.addEventListener("mouseout", endStroke, false);
canvas2.addEventListener("mouseenter", mouseEnter, false);
.canv-wrapper {
max-width: 49%;
display:inline-block;
}
<div class="canv-wrapper">
<canvas id="myCanvas" width="284px" height="120px">hello</canvas>
<p>1 image 284px x 120px</p>
</div>
<div class="canv-wrapper">
<canvas id="myCanvas2" style="width:284px;height:120px;"></canvas>
<p>2 image 960px x 540px - Paint over image</p>
</div>
<img style="display:none;" src="https://wallpapercave.com/wp/wp4712331.jpg" id="dove">