Beatriz Sgavioli
Beatriz Sgavioli

Reputation: 31

IONIC 4 - Canvas - drawing on the wrong position of the touch

I'm doing an app which needs a box to the clients assign their names.

I followed this tutorial: https://devdactic.com/ionic-canvas-drawing-files/

My .html:

<ion-content padding>
    <ion-grid>
        <div class="w-100">
            <ion-item class="no-border" no-padding>
                <ion-label position="stacked">Assinatura</ion-label>
                    <canvas #imageCanvas (touchstart)="startDrawing($event)" (touchmove)="moved($event)">
                    </canvas>
                </ion-item>
            </div>
        </ion-row>
    </ion-grid>
</ion-content>

My .ts:

import { Component, ViewChild } from '@angular/core';
import { Content, Platform, normalizeURL } from 'ionic-angular';

@Component({
    selector: 'app-home',
    templateUrl: 'home.page.html',
    styleUrls: ['home.page.scss'],
})

export class HomePage {

    selectedColor = "#000";

    @ViewChild('imageCanvas') canvas: any;
    canvasElement: any;

    saveX: number;
    saveY: number;

    @ViewChild(Content) content: Content;

    constructor(private plt: Platform){

    }

    ionViewDidEnter () {
        this.canvasElement = this.canvas.nativeElement;
    }

    startDrawing(ev) {
        var canvasPosition = this.canvasElement.getBoundingClientRect();
        this.saveX = ev.touches[0].pageX - canvasPosition.x;
        this.saveY = ev.touches[0].pageY - canvasPosition.y
    }

    moved(ev) {
        var canvasPosition = this.canvasElement.getBoundingClientRect();
        let currentX = ev.touches[0].pageX - canvasPosition.x;
        let currentY = ev.touches[0].pageY - canvasPosition.y;

        let ctx = this.canvasElement.getContext("2d");

        ctx.lineJoin = "round";
        ctx.strokeStyle = this.selectedColor;
        ctx.lineWidth = 2;

        ctx.beginPath();
        ctx.moveTo(this.saveX, this.saveY);
        ctx.lineTo(currentX, currentY);
        ctx.closePath();

        ctx.stroke();

        this.saveX = currentX;
        this.saveY = currentY;

    }

}

So when I test it on the browser, I can see the draw, but the line doesn't appear exactly on the position that I click with the mouse, it appears some pixels to the right and to the bottom. And when I tested it on my phone, I have the same problem.

Upvotes: 0

Views: 2621

Answers (1)

Ramon Schmitt
Ramon Schmitt

Reputation: 116

You're calling getBoundingClientRect twice.

This would solve your issue:

import { Component, ViewChild, ElementRef } from '@angular/core';
import { Content, Platform, normalizeURL } from 'ionic-angular';

@Component({
    selector: 'app-home',
    templateUrl: 'home.page.html',
    styleUrls: ['home.page.scss'],
})

export class HomePage {

    selectedColor = "#000";

    @ViewChild('imageCanvas') canvas: ElementRef;
    private ctx: CanvasRenderingContext2D;
    private position: DOMRect;

    saveX: number;
    saveY: number;

    @ViewChild(Content) content: Content;

    constructor(private plt: Platform){

    }

    ionViewDidEnter () {
        this.ctx = this.canvas.nativeElement.getContext('2d');
        this.position = this.canvas.nativeElement.getBoundingClientRect();
    }

    startDrawing(ev) {
        this.saveX = ev.touches[0].pageX - this.position.x;
        this.saveY = ev.touches[0].pageY - this.position.y
    }

    moved(ev) {
        const currentX = ev.touches[0].pageX - this.position.x;
        const currentY = ev.touches[0].pageY - this.position.y;

        this.ctx.lineJoin = "round";
        this.ctx.strokeStyle = this.selectedColor;
        this.ctx.lineWidth = 2;

        this.ctx.beginPath();
        this.ctx.moveTo(this.saveX, this.saveY);
        this.ctx.lineTo(currentX, currentY);
        this.ctx.closePath();

        this.ctx.stroke();

        this.saveX = currentX;
        this.saveY = currentY;
    }
}

Upvotes: 1

Related Questions