离子3 - 画布绘制并不完美,因为鼠标/触摸位置

Fro*_*and 5 javascript html5-canvas ionic3 angular angular6

我创建了一个应用程序,用户可以在画布上绘制任何内容.我已将背景图像添加到画布中.我希望画布覆盖屏幕上的剩余空间.因此,我保持宽度和高度百分比.

问题 - 现在每当我在画布上画一些东西时,它都不会跟随鼠标/触摸屏的准确位置.如果我在下方绘制,它将从触摸中提取近20px.(不确定像素有多少但是我的假设)

请仔细阅读下面的代码.

1. HTML

<ion-row>
      <canvas no-bounce 
      (touchstart)='handleStart($event)' (touchmove)='handleMove($event)' (click)="removeSelectedTxt()"
      [ngStyle]="{'background': 'url(' + selectedImage + ') no-repeat center center fixed', '-webkit-background-size': 'contain',
      '-moz-background-size': 'contain',
      '-o-background-size': 'contain',
      'background-size': 'contain',
      'width': '98%',
      'height': '65%'}" #canvas ></canvas>
  </ion-row>
Run Code Online (Sandbox Code Playgroud)

2. CSS

canvas {
      display: block;
      border: 1px solid #000;
      position: fixed;
      top: 10%;
      left: 1%;
    }
Run Code Online (Sandbox Code Playgroud)

3. TS文件

    import { Component, ViewChild,  ElementRef} from '@angular/core';

     @ViewChild('canvas') public canvas: ElementRef;

    this.canvasElement = this.canvas.nativeElement;

handleStart(ev){

        this.lastX = ev.touches[0].pageX;
        this.lastY = ev.touches[0].pageY;
    }

    handleMove(ev){

      let ctx = this.canvasElement.getContext('2d');
      let currentX = ev.touches[0].pageX;
      let currentY = ev.touches[0].pageY;

      ctx.beginPath();
      ctx.lineJoin = "round";
      ctx.moveTo(this.lastX, this.lastY);
      ctx.lineTo(currentX, currentY);
      ctx.closePath();
      ctx.strokeStyle = this.currentColour;
      ctx.lineWidth = this.brushSize;
      ctx.stroke();      

      this.lastX = currentX;
      this.lastY = currentY;
    }
Run Code Online (Sandbox Code Playgroud)

需要帮助,我如何在画布上绘制准确的触摸点?

Fro*_*and 3

经过对画布绘制进行了如此多的练习和研究,我终于解决了这个问题。

我在打字稿文件中做了以下更改。计算offsetLeftoffsetTop采用ionViewDidLoad方法。

1.ionViewDidLoad()方法

this.offsetX = this.canvasElement.offsetLeft;
this.offsetY = this.canvasElement.offsetTop;
Run Code Online (Sandbox Code Playgroud)
  • 一旦用户开始在画布上绘图,意味着 touchStart 事件,我调用了 handleStart() 方法。这里我做了一些改变。

2.handleStart(event)方法

handleStart(ev){

        this.lastX = ev.touches[0].pageX - this.offsetX;
        this.lastY = ev.touches[0].pageY - this.offsetY;
    }
Run Code Online (Sandbox Code Playgroud)
  • 为了在画布上绘图,我调用了 touchMove 事件。

3.handleMove(event)方法

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;

    }
Run Code Online (Sandbox Code Playgroud)

注意 - 如果你仔细观察代码,我所做的是计算 offsetLeft 和 offsetTop。然后从handleStart 和handleMove 方法中的触摸点减去这个值。