Я работаю над приложением для удаления фона, используя html5 canvas и angularJS. Я укладываю два холста и удаляю пиксели из верхнего с помощью пользовательского курсора, который соответствует размеру ластика. У меня действительно странная ошибка, которая позволяет мне удалять передний план только в том случае, если я быстро перемещаю мышь, одиночные щелчки и медленное движение мыши не влияют на холст. Я подозреваю, что есть проблема с угловыми даже прослушивателями, так как та же версия кода, которую я запускал, используя liveServer в vscode и стандартных слушателях событий JS canvas.addEventListener('mousemove', erase);
, работала нормально. Буду признателен за любую помощь в этом.
Я работаю над кодом, чтобы лучше проиллюстрировать проблему.
Разметка:
<div class="cursor" ng-mousemove="erase($event)"
ng-mousedown="startPosition($event)"
ng-mouseup="finishedPosition($event)"><!-- -->
<!--ng-click="cursorMove($event)"-->
<span class="innerCursor"></span>
</div>
<div class="canvas-container" ng-init="init();">
<canvas id="canvas" style="z-index: 2;" ng-mousemove="erase($event);"
ng-mousedown="startPosition($event)"
ng-mouseup="finishedPosition($event)"></canvas>
<canvas id="bgCanvas" style="z-index: 1;"></canvas>
</div>
JS:
//Gets real mouse position in canvas
function getMousePos(canvas, e) {
var rect = canvas.getBoundingClientRect(), // abs. size of element
scaleX = canvas.width / rect.width, // relationship bitmap vs. element for X
scaleY = canvas.height / rect.height; // relationship bitmap vs. element for Y
return {
x: (e.clientX - rect.left) * scaleX, // scale mouse coordinates after they have
y: (e.clientY - rect.top) * scaleY // been adjusted to be relative to element
}
}
//Controls the movement of the custom cursor
$scope.cursorMove = function (x, y) {
var cursor = document.querySelector('.cursor');
cursor.setAttribute('style', 'width: ' + $scope.options.brushSize + 'px; height: ' + $scope.options.brushSize + 'px; top: ' + y + 'px; left: ' + x + 'px; transform : translate(-' + 50 + '%, -' + 50 + '%)' + ';');
}
$scope.init = function () {
//Foreground
$scope.canvas = document.querySelector('#canvas');
$scope.ctx = canvas.getContext('2d');
//Background
$scope.bgCanvas = document.querySelector('#bgCanvas');
$scope.ctxBg = bgCanvas.getContext('2d');
$scope.ctx.canvas.height = 600;
$scope.ctx.canvas.width = 900;
$scope.drawAll();
}
//Display all elements
$scope.drawAll = function () {
$scope.drawForeground();
$scope.drawBackground();
}
$scope.drawForeground = function () {
console.log('foreground');
var url = $scope.personalisationOptions.noBackgroundImage;
//var url = 'img link';
var img1 = new Image();
img1.src = url + '?' + new Date().getTime();
img1.setAttribute('crossOrigin', '');
img1.onload = function () {
$scope.ctx.drawImage(img1, 0, 0, $scope.ctx.canvas.clientWidth, $scope.ctx.canvas.clientHeight);
}
}
$scope.drawBackground = function () {
console.log('background');
var img2 = new Image();
img2.src = 'img link';
img2.onload = function () {
$scope.ctxBg.drawImage(img2, 0, 0, $scope.ctx.canvas.clientWidth, $scope.ctx.canvas.clientHeight);
}
}
//Erasing functionality
$scope.erasing = false;
$scope.erase = function (e) {
var pos = getMousePos(canvas, e);
$scope.cursorMove(pos.x, pos.y);
if (!$scope.erasing) return;
if (!$scope.pendingSnapshot) {
$scope.pendingSnapshot = $scope.ctx.getImageData(0, 0, window.innerWidth, window.innerHeight);
}
if ($scope.options.isCircle) {
console.log('B');
// circular eraser
$scope.ctx.save();
$scope.ctx.beginPath();
$scope.ctx.arc(e.offsetX, e.offsetY, $scope.options.brushSize / 2, 0, 2 * Math.PI, true);
$scope.ctx.clip();
//eraser with new coordinates pos.x / pos.y
$scope.ctx.clearRect(pos.x - $scope.options.brushSize, pos.y - $scope.options.brushSize, $scope.options.brushSize * 2, $scope.options.brushSize * 2);
console.log(pos.x, pos.y - $scope.options.brushSize);
$scope.ctx.restore();
} else {
// square eraser
$scope.ctx.beginPath();
$scope.ctx.clearRect(e.offsetX, e.offsetY, $scope.options.brushSize, $scope.options.brushSize);
}
}
$scope.startPosition = function (e) {
$scope.erasing = true;
$scope.erase(e);
console.log('mouse down');
}
$scope.finishedPosition = function () {
$scope.erasing = false;
console.log('mouse up');
$scope.ctx.beginPath();
$scope.imageSnapshot = $scope.pendingSnapshot;
//limit clickHistory to 5
if ($scope.clickHistory.length > 4) {
$scope.clickHistory.shift();
}
$scope.clickHistory.push($scope.pendingSnapshot);
$scope.pendingSnapshot = null;
}