Я создаю приложение для рисования. Я использую два холста. Один для загрузки фонового изображения и один для рисования. Картина холста расположена над другой. Я использовал две полотна, потому что я не хочу, чтобы инструмент ластик имел эффект на изображении. В моем коде y позиция, нарисованная приложением, не всегда точна. В большинстве случаев линия рисуется выше фактического пройденного пути.
var baseCanvas,baseContext,canvasObj,context;
var lastX,lastY,mouseX,mouseY;
var isMouseDown = false;
var mode = "pen";
$(window).load(function()
{
baseCanvas = document.getElementById("imageCanvas");
baseContext = baseCanvas.getContext("2d");
baseContext.strokeStyle = 'Black';
baseContext.fillStyle = "skyBlue";
baseContext.lineWidth = 5;
baseContext.fillRect(0, 0, baseCanvas.width, baseCanvas.height);
canvasObj = document.getElementById("drawingCanvas");
context = canvasObj.getContext("2d");
context.strokeStyle = 'Black';
context.lineCap = "round";
context.lineJoin = "round";
context.lineWidth = 2;
function handleMouseDown(e) {
mouseX = parseInt(e.clientX - $('#drawingCanvas').offset().left);
mouseY = parseInt(e.clientY - $('#drawingCanvas').offset().top);
lastX = mouseX;
lastY = mouseY;
isMouseDown = true;
}
function handleMouseUp(e) {
mouseX = parseInt(e.clientX - $('#drawingCanvas').offset().left);
mouseY = parseInt(e.clientY - $('#drawingCanvas').offset().top);
isMouseDown = false;
}
function handleMouseOut(e) {
mouseX = parseInt(e.clientX - $('#drawingCanvas').offset().left);
mouseY = parseInt(e.clientY - $('#drawingCanvas').offset().top);
isMouseDown = false;
}
function handleMouseMove(e) {
mouseX = parseInt(e.clientX - $('#drawingCanvas').offset().left);
mouseY = parseInt(e.clientY - $('#drawingCanvas').offset().top);
if (isMouseDown) {
context.beginPath();
if (mode == 'pen') {
context.globalCompositeOperation = "source-over";
context.moveTo(lastX, lastY);
context.lineTo(mouseX, mouseY);
context.stroke();
} else {
context.globalCompositeOperation = "destination-out";
context.arc(lastX, lastY, 5, 0, Math.PI * 2, false);
context.fill();
}
lastX = mouseX;
lastY = mouseY;
}
}
$(document).on('mousedown',$("#drawingCanvas"),function (e) {
handleMouseDown(e);
});
$(document).on('mousemove',$("#drawingCanvas"),function (e) {
handleMouseMove(e);
});
$(document).on('mouseup',$("#drawingCanvas"),function (e) {
handleMouseUp(e);
});
$(document).on('mouseout',$("#drawingCanvas"),function (e) {
handleMouseOut(e);
});
});
function setCanvas(imageFile)
{
var base_image = new Image();
base_image.src = window.URL.createObjectURL(imageFile[0]);
baseContext.save();
baseContext.clearRect(0, 0, baseCanvas.width, baseCanvas.height);
baseContext.beginPath();
base_image.onload = function()
{
baseContext.drawImage(base_image,0,0, $('#imageCanvas').width(), $('#imageCanvas').height());
baseContext.restore();
}
}
Если вы прокрутите окно браузера, вам нужно настроить эту прокрутку.
Вот как:
var scrollAdjustment=$("html,body").scrollTop();
mouseY+=scrollAdjustment;
И если вы прокручиваете по горизонтали, вам также нужно будет настроить горизонтальную прокрутку.
BTW, поскольку смещение холста не изменяется, вы можете предварительно вычислить смещения холста один раз, а не вычислять его каждый раз в обработчиках событий.
В вашей настройке вверху:
var canvasOffset=$("#drawingCanvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
И в ваших обработчиках событий:
var scrollAdjustment=$("html,body").scrollTop();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY+scrollAdjustment);
Если вы используете свойства clientX, customerY ваших событий мыши и что вы подключили события в окне, вы должны получитьBoundingClientRect на своем холсте, чтобы узнать его верхнюю и левую позицию, а затем вычесть их.
https://developer.mozilla.org/en-US/docs/Web/API/element.getBoundingClientRect
Rq: Вы можете подумать и о подключении событий на холсте.