ARTICLE AD BOX
I am attempting to use HTML canvas to collect signatures. The drawing works perfectly on mobile but I cannot seem to get the drawing to work on mobile. To be clear the canvas does appear on mobile, it just does not allow me to draw with my finger on mobile. I have ensured that scroll is disabled when touching inside the canvas and am using Safari on iPhone. I had the same issue with angular2 signature-pad which I believe also uses HTML canvas.
@ViewChild('signatureCanvas', { static: false }) signatureCanvas!: ElementRef<HTMLCanvasElement>; private ctx!: CanvasRenderingContext2D; private drawing = false; ngAfterViewInit() { const canvas = this.signatureCanvas.nativeElement; // Set CSS size canvas.style.width = '300px'; canvas.style.height = '100px'; // Set actual pixel size for high-DPI screens const ratio = window.devicePixelRatio || 1; canvas.width = 300 * ratio; canvas.height = 100 * ratio; this.ctx = canvas.getContext('2d')!; this.ctx.setTransform(1, 0, 0, 1, 0, 0); // Reset transform this.ctx.scale(ratio, ratio); this.ctx.lineWidth = 2; this.ctx.lineCap = 'round'; // Mouse events canvas.addEventListener('mousedown', this.startDraw); canvas.addEventListener('mousemove', this.draw); canvas.addEventListener('mouseup', this.endDraw); canvas.addEventListener('mouseleave', this.endDraw); // Touch events (passive: false) canvas.addEventListener('touchstart', this.startDraw, { passive: false }); canvas.addEventListener('touchmove', this.draw, { passive: false }); canvas.addEventListener('touchend', this.endDraw, { passive: false }); } startDraw = (event: MouseEvent | TouchEvent) => { event.preventDefault(); this.drawing = true; const { x, y } = this.getXY(event); this.ctx.beginPath(); this.ctx.moveTo(x, y); }; draw = (event: MouseEvent | TouchEvent) => { if (!this.drawing) return; event.preventDefault(); const { x, y } = this.getXY(event); this.ctx.lineTo(x, y); this.ctx.stroke(); }; endDraw = (event: MouseEvent | TouchEvent) => { event.preventDefault(); this.drawing = false; this.ctx.closePath(); }; getXY(event: MouseEvent | TouchEvent) { const rect = this.signatureCanvas.nativeElement.getBoundingClientRect(); let x = 0, y = 0; if (event instanceof MouseEvent) { x = event.clientX - rect.left; y = event.clientY - rect.top; } else if ('touches' in event && event.touches.length > 0) { x = event.touches[0].clientX - rect.left; y = event.touches[0].clientY - rect.top; } return { x, y }; } clearSignature() { const canvas = this.signatureCanvas.nativeElement; this.ctx.clearRect(0, 0, canvas.width, canvas.height); }