【问题标题】:Ionic 3 - Canvas draw is not perfect as per mouse/touch positionIonic 3 - 根据鼠标/触摸位置,画布绘制并不完美
【发布时间】:2019-01-13 04:55:43
【问题描述】:

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

问题 - 现在每当我在画布上绘制东西时,它都不会跟随鼠标/触摸在屏幕上的准确位置。如果我在下面画,它会从触摸开始接近 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>

2。 CSS

canvas {
      display: block;
      border: 1px solid #000;
      position: fixed;
      top: 10%;
      left: 1%;
    }

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;
    }

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

【问题讨论】:

  • 听起来你有偏移问题......通过css设置尺寸也有问题:stackoverflow.com/questions/8693693/…
  • 感谢好友的帮助。我使用了鼠标事件,但它不适用于触摸事件...即使我对触摸事件使用了相同的逻辑,但仍然是相同的问题..

标签: javascript angular html5-canvas ionic3 angular6


【解决方案1】:

在canvas draw上做了这么多的练习和研究,终于解决了这个问题。

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

1. ionViewDidLoad() 方法

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

2。 handleStart(event) 方法

handleStart(ev){

        this.lastX = ev.touches[0].pageX - this.offsetX;
        this.lastY = ev.touches[0].pageY - this.offsetY;
    }
  • 为了在画布上绘图,我调用了 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;

    }

注意 - 如果您仔细查看代码,我所做的是计算 offsetLeft 和 offsetTop。然后从 handleStart 和 handleMove 方法中的接触点减去这个。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多