UNPKG

@almothafar/angular-signature-pad

Version:

Angular Component wrapper for szimek/signature_pad

256 lines (250 loc) 10.2 kB
import * as i0 from '@angular/core'; import { EventEmitter, Component, Input, Output, NgModule } from '@angular/core'; import SignaturePad from 'signature_pad'; class SignaturePadComponent { constructor(_elementRef) { this._elementRef = _elementRef; this.options = this.options || {}; this.drawStart = new EventEmitter(); this.drawBeforeUpdate = new EventEmitter(); this.drawAfterUpdate = new EventEmitter(); this.drawEnd = new EventEmitter(); } ngAfterContentInit() { const canvas = this.initCanvas(this.options); this.initSignaturePad(canvas, this.options); this.redrawCanvas(); } ngOnDestroy() { const canvas = this.getCanvas(); canvas.width = 0; canvas.height = 0; } // noinspection JSUnusedGlobalSymbols getSignaturePad() { return this.signaturePad; } getCanvas() { return this._elementRef.nativeElement.querySelector('canvas'); } // noinspection JSUnusedGlobalSymbols /** * Redraw or Resize canvas, note this will clear data. */ redrawCanvas() { const canvas = this.getCanvas(); // when zoomed out to less than 100%, for some very strange reason, // some browsers report devicePixelRatio as less than 1, and only part of the canvas is cleared then. const ratio = Math.max(window.devicePixelRatio || 1, 1); canvas.width = this._getWidthFix(canvas) * ratio; canvas.height = this._getHeightFix(canvas) * ratio; canvas.getContext('2d').scale(ratio, ratio); this.changeBackgroundColor(this.signaturePad.backgroundColor); } // noinspection JSUnusedGlobalSymbols /** * Change the color of the background dynamically. */ changeBackgroundColor(color) { this.signaturePad.backgroundColor = color; const data = this.signaturePad.toData(); this.signaturePad.clear(); this.signaturePad.fromData(data); } // noinspection JSUnusedGlobalSymbols /** * Returns signature image as an array of point groups */ toData() { if (this.signaturePad) { return this.signaturePad.toData(); } else { return []; } } // noinspection JSUnusedGlobalSymbols /** * Draws signature image from an array of point groups */ fromData(points) { this.signaturePad.fromData(points); } // noinspection JSUnusedGlobalSymbols /** * Returns signature image as data URL (see https://mdn.io/todataurl for the list of possible parameters) */ toDataURL(imageType, quality) { return this.signaturePad.toDataURL(imageType, quality); // save image as data URL } // noinspection JSUnusedGlobalSymbols /** * Draws signature image from data URL */ fromDataURL(dataURL, options = {}) { // set default height and width on read data from URL if (!options.hasOwnProperty('height') && this.options.canvasHeight) { options.height = this.options.canvasHeight; } if (!options.hasOwnProperty('width') && this.options.canvasWidth) { options.width = this.options.canvasWidth; } return this.signaturePad.fromDataURL(dataURL, options); } // noinspection JSUnusedGlobalSymbols /** * Clears the canvas */ clear(redraw = true) { if (redraw) { this.signaturePad.clear(); this.redrawCanvas(); } else { this.signaturePad.clear(); } this.endStroke(null); } // noinspection JSUnusedGlobalSymbols /** * Returns true if canvas is empty, otherwise returns false */ isEmpty() { return this.signaturePad.isEmpty(); } // noinspection JSUnusedGlobalSymbols /** * Unbinds all event handlers */ off() { this.signaturePad.off(); } /** * Rebinds all event handlers */ on() { this.signaturePad.on(); } /** * set an option on the signaturePad - e.g. set('minWidth', 50); * @param option one of SignaturePad to set with value, properties of NgSignaturePadOptions * @param value the value of option */ set(option, value) { if (option === 'canvasHeight' || option === 'canvasWidth') { const canvas = this.getCanvas(); const canvasOption = option.replace('canvas', '').toLowerCase(); if (canvas[canvasOption] === value) { // Same value, no need to change and redraw return; } canvas[canvasOption] = value - this.extraWidth; this.clear(); } else { if (this.signaturePad[option] === value) { // Same value, no need to change and redraw return; } this.signaturePad[option] = value; } } /** * notify subscribers on signature begin */ beginStroke(event) { this.drawStart.emit(event); } beforeUpdateStroke(event) { this.drawBeforeUpdate.emit(event); } afterUpdateStroke(event) { this.drawAfterUpdate.emit(event); } /** * notify subscribers on signature end */ endStroke(event) { this.drawEnd.emit(event); } initCanvas(options) { const canvas = this.getCanvas(); if (this.options.canvasHeight) { canvas.height = options.canvasHeight - 2; } if (this.options.canvasWidth) { canvas.width = options.canvasWidth - 2; } if (this.options.canvasBackground) { canvas.style.background = options.canvasBackground; } return canvas; } initSignaturePad(canvas, options) { this.signaturePad = new SignaturePad(canvas, options); this.signaturePad.addEventListener('beginStroke', (event) => this.beginStroke(event.detail)); this.signaturePad.addEventListener('beforeUpdateStroke', (event) => this.beforeUpdateStroke(event.detail)); this.signaturePad.addEventListener('afterUpdateStroke', (event) => this.afterUpdateStroke(event.detail)); this.signaturePad.addEventListener('endStroke', (event) => this.endStroke(event.detail)); } /** * To prevent the growing effect when the redrawCanvas is called for the width * @param canvas * @private */ _getWidthFix(canvas) { const computedStyle = getComputedStyle(canvas); const extraPadding = parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight); const extraBorder = parseFloat(computedStyle.borderLeftWidth) + parseFloat(computedStyle.borderRightWidth); this.extraWidth = extraPadding + extraBorder; return canvas.offsetWidth - (extraPadding + extraBorder); } /** * To prevent the growing effect when the redrawCanvas is called for the height * @param canvas * @private */ _getHeightFix(canvas) { const computedStyle = getComputedStyle(canvas); const extraPadding = parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom); const extraBorder = parseFloat(computedStyle.borderTopWidth) + parseFloat(computedStyle.borderBottomWidth); return canvas.offsetHeight - (extraPadding + extraBorder); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.10", ngImport: i0, type: SignaturePadComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.10", type: SignaturePadComponent, selector: "signature-pad", inputs: { options: "options" }, outputs: { drawStart: "drawStart", drawBeforeUpdate: "drawBeforeUpdate", drawAfterUpdate: "drawAfterUpdate", drawEnd: "drawEnd" }, ngImport: i0, template: '<canvas class="signature-pad-canvas"></canvas>', isInline: true, styles: [":host{background:#faebd7;display:flex;align-items:center;justify-content:center}:host .signature-pad-canvas{border:1px solid gray}\n"] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.10", ngImport: i0, type: SignaturePadComponent, decorators: [{ type: Component, args: [{ template: '<canvas class="signature-pad-canvas"></canvas>', selector: 'signature-pad', styles: [":host{background:#faebd7;display:flex;align-items:center;justify-content:center}:host .signature-pad-canvas{border:1px solid gray}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { options: [{ type: Input }], drawStart: [{ type: Output }], drawBeforeUpdate: [{ type: Output }], drawAfterUpdate: [{ type: Output }], drawEnd: [{ type: Output }] } }); class AngularSignaturePadModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.10", ngImport: i0, type: AngularSignaturePadModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.10", ngImport: i0, type: AngularSignaturePadModule, declarations: [SignaturePadComponent], exports: [SignaturePadComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.10", ngImport: i0, type: AngularSignaturePadModule }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.10", ngImport: i0, type: AngularSignaturePadModule, decorators: [{ type: NgModule, args: [{ declarations: [SignaturePadComponent], imports: [], exports: [SignaturePadComponent], }] }] }); /* * Public API Surface of angular-signature-pad */ /** * Generated bundle index. Do not edit. */ export { AngularSignaturePadModule, SignaturePadComponent }; //# sourceMappingURL=almothafar-angular-signature-pad.mjs.map