Canvas-ластик, рисующий черные линии на холсте после холста, сохраненного как изображение
рисование на холсте работает отлично. Даже ластик тоже работает отлично. Проблема в том, что в то время как холст сохраняется как изображение, он рисует черные линии вместо ластика.
для лучшего понимания я добавил снимки экранов и код.
1. При стирании розыгрыша -
a. Исходный код -
erase(){
this.ctx.globalCompositeOperation = 'destination-out';
}
handleMove(ev){
// let ctx = this.canvasElement.getContext('2d');
let currentX = ev.touches[0].pageX - this.offsetX;
let currentY = ev.touches[0].pageY - this.offsetY;
this.ctx.beginPath();
this.ctx.lineJoin = "round";
this.ctx.moveTo(this.lastX, this.lastY);
this.ctx.lineTo(currentX, currentY);
this.ctx.closePath();
this.ctx.strokeStyle = this.currentColour;
this.ctx.lineWidth = this.brushSize;
this.ctx.stroke();
this.undoList.push({
x_start: currentX,
y_start: currentY,
x_end: this.lastX,
y_end: this.lastY,
color: this.currentColour,
size: this.brushSize,
mode: this.ctx.globalCompositeOperation
});
this.lastX = currentX;
this.lastY = currentY;
}
b. Вывод -
2. Холст, сохраненный как изображение -
a. Код -
this.ctx.clearRect(0, 0, this.canvasElement.width, this.canvasElement.height);
setTimeout(() => {
// this.drawImg(this.newImg);
for(let i=0; i<this.textAreasList.length; i++){
let txt = this.textAreasList[i];
this.ctx.font = this.textAreasList[i].bold + ' ' + this.textAreasList[i].italic + ' ' + this.textAreasList[i].fontSize + ' ' + 'Comic Sans MS';
this.ctx.fillStyle = this.textAreasList[i].color;
if(this.textAreasList[i].left=="" || this.textAreasList[i].left==undefined) {
this.textAreasList[i].left = 50;
}
if(this.textAreasList[i].top=="" || this.textAreasList[i].top==undefined) {
this.textAreasList[i].top = 50;
}
this.ctx.fillText(this.textAreasList[i].value, this.textAreasList[i].left, this.textAreasList[i].top);
}
this.redrawCanvas(this.undoUseList);
let imgPath = this.canvasElement.toDataURL('image/png');
let message= "";
this.base64ToGallery.base64ToGallery(imgPath).then(
res => message = "Image saved to gallery!",
err => message = "Something went wrong!!"
);
this.spinner.hide();
let toast = this.toastCtrl.create({
message: message,
duration: 3000,
position: 'bottom',
cssClass: 'changeToast'
});
this.navCtrl.push(HomePage);
}, 5000);
}
redrawCanvas(arr){
// this.ctx.globalCompositeOperation = 'source-over';
for(let i=0; i<arr.length; i++){
for(let j=0; j< arr[i].length; j++){
let ctx = this.canvasElement.getContext('2d');
ctx.globalCompositeOperation = arr[i][j].mode;
console.log('x start', arr[i][j].x_start);
console.log('y start', arr[i][j].y_start);
console.log('x end', arr[i][j].x_end);
console.log('y end', arr[i][j].y_end);
ctx.beginPath();
ctx.lineJoin = "round";
ctx.moveTo(arr[i][j].x_start, arr[i][j].y_start);
ctx.lineTo(arr[i][j].x_end, arr[i][j].y_end);
ctx.closePath();
ctx.strokeStyle = arr[i][j].color;
ctx.lineWidth = arr[i][j].size;
ctx.stroke();
}
}
}
**b. Output -**
Я не понимаю, как ластик перемещается, заменяясь черным цветом при сохранении холста в качестве изображения.
2 ответов
Итак, вы перерисовываете свой холст, используя список отмены, верно? И после этого вы выводите изображение с помощью toDataUrl ()?
мне кажется, что вопрос лежит на
this.undoList.push({
x_start: currentX,
y_start: currentY,
x_end: this.lastX,
y_end: this.lastY,
color: this.currentColour, <== Is this an object?
size: this.brushSize,
mode: this.ctx.globalCompositeOperation
});
если это.currentColour-это объект, я предполагаю, что свойства изменяются где-то еще в коде, и к тому времени, когда вы восстанавливаете шаги, вы получаете стиль черный, не уверен, что он по умолчанию.
Так что вы можете попробовать это вместо
this.undoList.push({
x_start: currentX,
y_start: currentY,
x_end: this.lastX,
y_end: this.lastY,
color: {
prop1: this.currentColour.prop1
prop2: this.currentColour.prop2
...
}
size: this.brushSize,
mode: this.ctx.globalCompositeOperation
});
замена prop1, prop2 и т. д. по фактическим свойствам, которые у вас есть в этом объекте. Таким образом, вы создаете новый obj (копируете его) вместо передачи ссылки на старый.
Вы можете сделать его более причудливым, но так вы можете получить рассуждения лучше.
наконец я решил эту проблему. Я сделал ниже изменения.
redrawCanvas(arr){
// this.ctx.globalCompositeOperation = 'source-over';
for(let i=0; i<arr.length; i++){
for(let j=0; j< arr[i].length; j++){
let ctx = this.canvasElement.getContext('2d');
// ctx.globalCompositeOperation = arr[i][j].mode;
if(arr[i][j].mode== "destination-out"){
// ctx.globalCompositeOperation = "destionation-out";
// ctx.strokeStyle = "rgba(0,0,0,0.2)";
let cImg = new Image();
cImg.src = this.selectedImage;
let pattern = ctx.createPattern(cImg, "no-repeat");
ctx.strokeStyle = pattern;
}else{
ctx.strokeStyle = arr[i][j].color;
}
console.log('x start', arr[i][j].x_start);
console.log('y start', arr[i][j].y_start);
console.log('x end', arr[i][j].x_end);
console.log('y end', arr[i][j].y_end);
ctx.beginPath();
ctx.lineJoin = "round";
ctx.moveTo(arr[i][j].x_start, arr[i][j].y_start);
ctx.lineTo(arr[i][j].x_end, arr[i][j].y_end);
ctx.closePath();
ctx.lineWidth = arr[i][j].size;
ctx.stroke();
}
}
}
как вы можете видеть, я добавил одну проверку, чтобы проверить, является ли она кисть или ластик. Для ластика я проверяю, является ли это destination-out
или нет.
если это ластик, я создаю новое изображение, чтобы сделать strokestyle
.
таким образом, вы можете сказать, что я сделал ниже изменения только.
if(arr[i][j].mode== "destination-out"){
// ctx.globalCompositeOperation = "destionation-out";
// ctx.strokeStyle = "rgba(0,0,0,0.2)";
let cImg = new Image();
cImg.src = this.selectedImage;
let pattern = ctx.createPattern(cImg, "no-repeat");
ctx.strokeStyle = pattern;
}else{
ctx.strokeStyle = arr[i][j].color;
}