Холст - Ластик, рисующий черные линии по холсту после холста, сохраненного как изображение - PullRequest
0 голосов
/ 24 августа 2018

Рисование на холсте работает отлично. Даже ластик тоже работает отлично. Проблема в том, что при сохранении холста в качестве изображения вместо ластика рисуются черные линии.

Для лучшего понимания я добавил скриншоты и код.

1. Стирая ничью -

а. Исходный код -

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;

}

б. Выход -

enter image description here

2. Холст сохранен как изображение -

а. Код -

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 -** 

enter image description here

Я не понимаю, почему движущиеся элементы ластика заменяются черным цветом при сохранении холста как изображения.

Ответы [ 2 ]

0 голосов
/ 30 августа 2018

Наконец-то я решил проблему.Я сделал ниже изменения.

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;
          }
0 голосов
/ 27 августа 2018

Итак, вы перерисовываете свой холст, используя список отмен, верно?И после этого вы выводите изображение с помощью 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
});

, если this.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 и т. д. фактическими свойствами, которыми вы обладаете в этом объекте.Таким образом, вы создаете новый объект (копируете его) вместо того, чтобы передавать ссылку на свой старый.

Вы можете сделать его более изящным, но вот так вы сможете лучше рассуждать.

...