After experimenting with an ionic capacitor project, I discovered a setup that works well. In this configuration, I have integrated a base64 image as the background and included drawing tools on a separate layer.
html
<ion-card>
<ion-card-content>
<ion-row>
<ion-col *ngFor="let color of colors" [style.background]="color" class="color-block" tappable
(click)="selectColor(color)"></ion-col>
</ion-row>
<ion-radio-group [(ngModel)]="selectedColor">
<ion-row>
<ion-col *ngFor="let color of colors" class="ion-text-center">
<ion-radio [value]="color"></ion-radio>
</ion-col>
</ion-row>
</ion-radio-group>
<ion-range min="2" max="20" color="primary" [(ngModel)]="lineWidth">
<ion-icon size="small" slot="start" name="brush"></ion-icon>
<ion-icon slot="end" name="brush"></ion-icon>
</ion-range>
<canvas #imageCanvas (touchstart)="startDrawing($event)" (touchmove)="moved($event)" (touchend)="endDrawing()"> </canvas>
</ion-card-content>
</ion-card>
scss
canvas {
border: 1px solid rgb(187, 178, 178);
}
.color-block {
height: 40px;
}
ts
export class QuestionPhotosPage {
@ViewChild('imageCanvas', { static: false }) canvas: any;
canvasElement: any;
saveX: number;
saveY: number;
selectedColor = '#9e2956';
colors = [ '#9e2956', '#c2281d', '#de722f', '#edbf4c', '#5db37e', '#459cde', '#4250ad', '#802fa3' ];
drawing = false;
lineWidth = 5;
constructor(private platform: Platform) {}
// used for changing color of brush
selectColor(color) { this.selectedColor = color }
// used to load the background photo and prepare canvas
drawOnPhoto(file: { data: any; }) {
this.file = file.data; // Using a base64 jpeg here
setTimeout(() => { // Added timeout to allow photo to finish loading
// Set the Canvas Element and its size
this.canvasElement = this.canvas.nativeElement;
this.canvasElement.width = this.platform.width() + '';
this.canvasElement.height = 200;
var background = new Image();
background.src = this.file; // Background image to be used
let ctx = this.canvasElement.getContext('2d');
background.onload = () => { ctx.drawImage(background,0,0, this.canvasElement.width, this.canvasElement.height); }
}, 250);
}
// sets initial drawing point
startDrawing(ev) {
this.drawing = true;
let canvasPosition = this.canvasElement.getBoundingClientRect();
this.saveX = ev.touches[0].pageX - canvasPosition.x;
this.saveY = ev.touches[0].pageY - canvasPosition.y;
}
// listens for movement and adds points and joins
moved(ev) {
console.log("this.lineWidth", this.lineWidth)
if (!this.drawing) return;
var canvasPosition = this.canvasElement.getBoundingClientRect();
let ctx = this.canvasElement.getContext('2d');
let currentX = ev.touches[0].pageX - canvasPosition.x;
let currentY = ev.touches[0].pageY - canvasPosition.y;
ctx.lineJoin = 'round';
ctx.strokeStyle = this.selectedColor;
ctx.lineWidth = this.lineWidth;
ctx.beginPath();
ctx.moveTo(this.saveX, this.saveY);
ctx.lineTo(currentX, currentY);
ctx.closePath();
ctx.stroke();
this.saveX = currentX;
this.saveY = currentY;
}
// when finger removed stops the drawing
endDrawing() { this.drawing = false }