UNPKG

@syncfusion/ej2-inputs

Version:

A package of Essential JS 2 input components such as Textbox, Color-picker, Masked-textbox, Numeric-textbox, Slider, Upload, and Form-validator that is used to get input from the users.

1,005 lines (1,004 loc) 41.5 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); import { Component, removeClass } from '@syncfusion/ej2-base'; import { EventHandler, isNullOrUndefined } from '@syncfusion/ej2-base'; var SignatureBase = /** @class */ (function (_super) { __extends(SignatureBase, _super); function SignatureBase() { var _this = _super !== null && _super.apply(this, arguments) || this; /* minDistance(distance between the two point) was calaculated for smoothness.*/ _this.minDistance = 5; _this.previous = 0; /* interval handles for the smoothness in the mouse move event.*/ _this.interval = 30; _this.timeout = null; _this.isSignatureEmpty = true; _this.backgroundLoaded = null; _this.isBlazor = false; _this.isResponsive = false; _this.signPointsColl = []; _this.signRatioPointsColl = []; _this.canRedraw = true; return _this; } /** * To Initialize the component rendering * * @private * @param {HTMLCanvasElement} element - Specifies the canvas element. * @param {BlazorDotnetObject} dotnetRef - Specifies for blazor client to server communication. * @returns {void} */ SignatureBase.prototype.initialize = function (element, dotnetRef) { this.clearArray = []; this.element = element; this.canvasContext = this.element.getContext('2d'); this.canvasContext.canvas.tabIndex = -1; if (dotnetRef) { this.dotnetRef = dotnetRef; this.isBlazor = true; if (this.signatureValue) { this.loadPersistedSignature(); } } this.setHTMLProperties(); if (isNullOrUndefined(this.signatureValue)) { this.updateSnapCollection(true); } this.wireEvents(); if (!this.isBlazor) { this.trigger('created', null); } }; SignatureBase.prototype.wireEvents = function () { if (isNullOrUndefined(this.pointColl) && !this.isReadOnly && !this.disabled) { EventHandler.add(this.canvasContext.canvas, 'mousedown touchstart', this.mouseDownHandler, this); EventHandler.add(this.canvasContext.canvas, 'keydown', this.keyboardHandler, this); window.addEventListener('resize', this.resizeHandler.bind(this)); } else if (this.pointColl) { EventHandler.add(this.canvasContext.canvas, 'mousemove touchmove', this.mouseMoveHandler, this); EventHandler.add(this.canvasContext.canvas, 'mouseup touchend', this.mouseUpHandler, this); EventHandler.add(document, 'mouseup', this.mouseUpHandler, this); } }; SignatureBase.prototype.unwireEvents = function (type) { if (type === 'mouseup' || type === 'touchend') { if (this.canvasContext) { EventHandler.remove(this.canvasContext.canvas, 'mousemove touchmove', this.mouseMoveHandler); EventHandler.remove(this.canvasContext.canvas, 'mouseup touchend', this.mouseUpHandler); } EventHandler.remove(document, 'mouseup', this.mouseUpHandler); } else { if (this.canvasContext) { EventHandler.remove(this.canvasContext.canvas, 'mousedown touchstart', this.mouseDownHandler); EventHandler.remove(this.canvasContext.canvas, 'keydown', this.keyboardHandler); } window.removeEventListener('resize', this.resizeHandler); } }; SignatureBase.prototype.setHTMLProperties = function () { // eslint-disable-next-line max-len if (this.element.height === 150 && this.element.width === 300 && this.element.offsetHeight !== 0 && this.element.offsetWidth !== 0) { this.element.height = this.element.offsetHeight; this.element.width = this.element.offsetWidth; this.isResponsive = true; } else if ((this.element.height !== this.element.offsetHeight - 1 || this.element.width !== this.element.offsetWidth - 1) && this.element.offsetHeight !== 0 && this.element.offsetWidth !== 0) { this.element.height = this.element.offsetHeight; this.element.width = this.element.offsetWidth; } this.canvasContext.fillStyle = this.strokeColor; this.tempCanvas = this.createElement('canvas', { className: 'e-' + this.getModuleName() + '-temp' }); this.tempContext = this.tempCanvas.getContext('2d'); this.tempCanvas.width = this.element.width; this.tempCanvas.height = this.element.height; if (this.backgroundImage) { this.canvasContext.canvas.style.backgroundImage = 'url(' + this.backgroundImage + ')'; this.canvasContext.canvas.style.backgroundRepeat = 'no-repeat'; if (this.saveWithBackground) { this.setBackgroundImage(this.backgroundImage, 'temp'); } } else if (this.backgroundColor) { this.canvasContext.canvas.style.backgroundColor = this.backgroundColor; } }; SignatureBase.prototype.mouseDownHandler = function (e) { if (e.buttons === 1 || e.buttons === 2 || e.type === 'touchstart') { if (e.type === 'touchstart') { e.preventDefault(); e.stopPropagation(); } this.beginStroke(e); this.wireEvents(); } }; SignatureBase.prototype.mouseMoveHandler = function (e) { if (e.buttons === 1 || e.buttons === 2 || e.type === 'touchmove') { if (e.type === 'touchmove') { e.preventDefault(); e.stopPropagation(); } if (this.interval) { this.updateStrokeWithThrottle(e); } else { this.updateStroke(e); } } }; SignatureBase.prototype.mouseUpHandler = function (e) { var args = { actionName: 'strokeUpdate' }; if (e.type === 'touchstart') { e.preventDefault(); e.stopPropagation(); } this.endDraw(); this.updateSnapCollection(); this.unwireEvents(e.type); if (!this.isBlazor) { this.trigger('change', args); } else { this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'mouseUp'); } this.signatureValue = this.snapColl[this.incStep]; for (var i = 0; i < this.signPointsColl.length; i++) { this.signRatioPointsColl.push({ x: (this.signPointsColl[i].x / this.canvasContext.canvas.width), y: (this.signPointsColl[i].y / this.canvasContext.canvas.height) }); } this.signPointsColl = []; }; SignatureBase.prototype.keyboardHandler = function (e) { var _this = this; var args = { fileName: 'Signature', type: 'Png', cancel: false }; switch (e.key) { case 'Delete': this.clear(); break; case (e.ctrlKey && 's'): if (!this.isBlazor) { this.trigger('beforeSave', args, function (observableSaveArgs) { if (!args.cancel) { _this.save(observableSaveArgs.type, observableSaveArgs.fileName); } }); } else { this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'beforeSave'); } e.preventDefault(); e.stopImmediatePropagation(); break; case (e.ctrlKey && 'z'): this.undo(); break; case (e.ctrlKey && 'y'): this.redo(); break; } }; SignatureBase.prototype.resizeHandler = function () { // eslint-disable-next-line @typescript-eslint/no-this-alias var proxy = this; if (this.isResponsive && this.canRedraw && this.canvasContext && this.element) { this.canvasContext.canvas.width = this.element.offsetWidth; this.canvasContext.canvas.height = this.element.offsetHeight; this.canvasContext.scale(1, 1); this.canvasContext.fillStyle = this.strokeColor; var pointSize = (this.minStrokeWidth + this.maxStrokeWidth) / 2; for (var i = 0; i < this.signRatioPointsColl.length; i++) { this.arcDraw((this.signRatioPointsColl[i].x * this.canvasContext.canvas.width), (this.signRatioPointsColl[i].y * this.canvasContext.canvas.height), pointSize); } this.signPointsColl = []; this.canvasContext.closePath(); this.canvasContext.fill(); } else if (this.canvasContext && this.element) { var restoreImg_1 = new Image(); restoreImg_1.src = this.snapColl[this.incStep]; restoreImg_1.onload = function () { proxy.canvasContext.clearRect(0, 0, proxy.element.width, proxy.element.height); proxy.canvasContext.drawImage(restoreImg_1, 0, 0, proxy.element.width, proxy.element.height); }; } }; SignatureBase.prototype.beginStroke = function (e) { this.internalRefresh(); this.updateStroke(e); }; SignatureBase.prototype.updateStroke = function (e) { var point = this.createPoint(e); this.addPoint(point); }; SignatureBase.prototype.updateStrokeWithThrottle = function (args) { var now = Date.now(); var remaining = this.interval - (now - this.previous); this.storedArgs = args; if (remaining <= 0 || remaining > this.interval) { if (this.timeout) { clearTimeout(this.timeout); this.timeout = null; } this.previous = now; this.updateStroke(this.storedArgs); if (!this.timeout) { this.storedArgs = null; } } else if (!this.timeout) { this.timeout = window.setTimeout(this.delay.bind(this), remaining); } }; SignatureBase.prototype.delay = function () { this.previous = Date.now(); this.timeout = null; this.updateStroke(this.storedArgs); if (!this.timeout) { this.storedArgs = null; } }; SignatureBase.prototype.createPoint = function (e) { var rect = this.canvasContext.canvas.getBoundingClientRect(); if (e.type === 'mousedown' || e.type === 'mousemove') { return this.point(e.clientX - rect.left, e.clientY - rect.top, new Date().getTime()); } else { return this.point(e.touches[0].clientX - rect.left, e.touches[0].clientY - rect.top, new Date().getTime()); } }; /* Returns the current point corrdinates(x, y) and time.*/ SignatureBase.prototype.point = function (pointX, pointY, time) { this.pointX = pointX; this.pointY = pointY; this.time = time || new Date().getTime(); return { x: this.pointX, y: this.pointY, time: this.time }; }; SignatureBase.prototype.addPoint = function (point) { var points = this.pointColl; var controlPoint1; var controlPoint2; var lastPoint = points.length > 0 && points[points.length - 1]; var isLastPointTooClose = lastPoint ? this.distanceTo(lastPoint) <= this.minDistance : false; if (!lastPoint || !(lastPoint && isLastPointTooClose)) { points.push(point); if (points.length > 2) { if (points.length === 3) { points.unshift(points[0]); } controlPoint1 = (this.calculateCurveControlPoints(points[0], points[1], points[2])).controlPoint2; controlPoint2 = (this.calculateCurveControlPoints(points[1], points[2], points[3])).controlPoint1; this.startPoint = points[1]; this.controlPoint1 = controlPoint1; this.controlPoint2 = controlPoint2; this.endPoint = points[2]; this.startDraw(); points.shift(); } } }; SignatureBase.prototype.startDraw = function () { var velocity; velocity = this.pointVelocityCalc(this.startPoint); velocity = this.velocity * velocity + (1 - this.velocity) * this.lastVelocity; var newWidth = Math.max(this.maxStrokeWidth / (velocity + 1), this.minStrokeWidth); this.curveDraw(this.lastWidth, newWidth); this.lastVelocity = velocity; this.lastWidth = newWidth; }; SignatureBase.prototype.endDraw = function () { if (isNullOrUndefined(this.pointColl)) { return; } var canDrawCurve = this.pointColl.length > 2; var point = this.pointColl[0]; if (!canDrawCurve && point) { this.strokeDraw(point); } }; /* Calculate the Bezier (x, y) coordinate of the curve. */ SignatureBase.prototype.curveDraw = function (startWidth, endWidth) { var context = this.canvasContext; var width; var i; var t1; var t2; var t3; var u1; var u2; var u3; var x; var y; var widthValue = endWidth - startWidth; var bezierLength = this.bezierLengthCalc(); var drawSteps = Math.ceil(bezierLength) * 2; context.beginPath(); for (i = 0; i < drawSteps; i++) { t1 = i / drawSteps; t2 = t1 * t1; t3 = t2 * t1; u1 = 1 - t1; u2 = u1 * u1; u3 = u2 * u1; x = u3 * this.startPoint.x; x += 3 * u2 * t1 * this.controlPoint1.x; x += 3 * u1 * t2 * this.controlPoint2.x; x += t3 * this.endPoint.x; y = u3 * this.startPoint.y; y += 3 * u2 * t1 * this.controlPoint1.y; y += 3 * u1 * t2 * this.controlPoint2.y; y += t3 * this.endPoint.y; width = Math.min(startWidth + t3 * widthValue, this.maxStrokeWidth); this.arcDraw(x, y, width); } context.closePath(); context.fill(); this.isSignatureEmpty = false; }; SignatureBase.prototype.strokeDraw = function (point) { var context = this.canvasContext; var pointSize = (this.minStrokeWidth + this.maxStrokeWidth) / 2; context.beginPath(); this.arcDraw(point.x, point.y, pointSize); context.closePath(); context.fill(); this.isSignatureEmpty = false; }; SignatureBase.prototype.arcDraw = function (x, y, size) { this.signPointsColl.push({ x: x, y: y }); var context = this.canvasContext; context.moveTo(x, y); context.arc(x, y, size, 0, 2 * Math.PI, false); }; /* Utility functions for Bezier algorithm*/ SignatureBase.prototype.calculateCurveControlPoints = function (p1, p2, p3) { var dx1 = p1.x - p2.x; var dy1 = p1.y - p2.y; var dx2 = p2.x - p3.x; var dy2 = p2.y - p3.y; var m1 = { x: (p1.x + p2.x) / 2.0, y: (p1.y + p2.y) / 2.0 }; var m2 = { x: (p2.x + p3.x) / 2.0, y: (p2.y + p3.y) / 2.0 }; var l1 = Math.sqrt(dx1 * dx1 + dy1 * dy1); var l2 = Math.sqrt(dx2 * dx2 + dy2 * dy2); var dxm = (m1.x - m2.x); var dym = (m1.y - m2.y); var k = l2 / (l1 + l2); var cm = { x: m2.x + dxm * k, y: m2.y + dym * k }; var tx = p2.x - cm.x; var ty = p2.y - cm.y; return { controlPoint1: this.point(m1.x + tx, m1.y + ty, 0), controlPoint2: this.point(m2.x + tx, m2.y + ty, 0) }; }; /* Returns approximated bezier length of the curuve.*/ SignatureBase.prototype.bezierLengthCalc = function () { var steps = 10; var length = 0; var i; var t; var pointx1; var pointy1; var pointx2; var pointy2; var pointx3; var pointy3; for (i = 0; i <= steps; i++) { t = i / steps; pointx1 = this.bezierPointCalc(t, this.startPoint.x, this.controlPoint1.x, this.controlPoint2.x, this.endPoint.x); pointy1 = this.bezierPointCalc(t, this.startPoint.y, this.controlPoint1.y, this.controlPoint2.y, this.endPoint.y); if (i > 0) { pointx3 = pointx1 - pointx2; pointy3 = pointy1 - pointy2; length += Math.sqrt(pointx3 * pointx3 + pointy3 * pointy3); } pointx2 = pointx1; pointy2 = pointy1; } return length; }; /* Calculate parametric value of x or y given t and the four point(startpoint, controlpoint1, controlpoint2, endpoint) coordinates of a cubic bezier curve.*/ SignatureBase.prototype.bezierPointCalc = function (t, startpoint, cp1, cp2, endpoint) { return startpoint * (1.0 - t) * (1.0 - t) * (1.0 - t) + 3.0 * cp1 * (1.0 - t) * (1.0 - t) * t + 3.0 * cp2 * (1.0 - t) * t * t + endpoint * t * t * t; }; /* Velocity between the current point and last point.*/ SignatureBase.prototype.pointVelocityCalc = function (startPoint) { return (this.time !== startPoint.time) ? this.distanceTo(startPoint) / (this.time - startPoint.time) : 0; }; /* Distance between the current point and last point.*/ SignatureBase.prototype.distanceTo = function (start) { return Math.sqrt(Math.pow(this.pointX - start.x, 2) + Math.pow(this.pointY - start.y, 2)); }; SignatureBase.prototype.isRead = function (isRead) { if (isRead) { EventHandler.remove(this.canvasContext.canvas, 'mousedown touchstart', this.mouseDownHandler); } else if (!this.disabled) { EventHandler.add(this.canvasContext.canvas, 'mousedown touchstart', this.mouseDownHandler, this); } }; SignatureBase.prototype.enableOrDisable = function (isDisable) { this.disabled = isDisable; if (isDisable) { this.canvasContext.canvas.style.filter = 'opacity(0.5)'; this.isRead(true); } else { this.canvasContext.canvas.style.filter = ''; this.isRead(false); } }; SignatureBase.prototype.updateSnapCollection = function (isClear) { if (isNullOrUndefined(this.incStep)) { this.incStep = -1; this.incStep++; this.snapColl = []; this.clearArray = []; } else { this.incStep++; } if (this.incStep < this.snapColl.length) { this.snapColl.length = this.incStep; } if (this.incStep > 0) { var canvasNew = this.createElement('canvas', { className: 'e-' + this.getModuleName() + '-wrapper' }); var canvasContextNew = canvasNew.getContext('2d'); if (this.canvasContext) { canvasNew.width = this.canvasContext.canvas.width; canvasNew.height = this.canvasContext.canvas.height; canvasContextNew.drawImage(this.canvasContext.canvas, 0, 0, canvasNew.width, canvasNew.height); this.snapColl.push(canvasNew.toDataURL()); } } else { this.snapColl.push(this.canvasContext.canvas.toDataURL()); } if (isClear) { this.clearArray.push(this.incStep); } }; SignatureBase.prototype.setBackgroundImage = function (imageSrc, type) { // eslint-disable-next-line @typescript-eslint/no-this-alias var proxy = this; var imageObj = new Image(); imageObj.crossOrigin = 'anonymous'; imageObj.src = imageSrc; if (type === 'temp') { imageObj.onload = function () { proxy.tempContext.globalCompositeOperation = 'source-over'; proxy.tempContext.drawImage(imageObj, 0, 0, proxy.element.width, proxy.element.height); }; } else { imageObj.onload = function () { proxy.canvasContext.globalCompositeOperation = 'source-over'; proxy.canvasContext.drawImage(imageObj, 0, 0, proxy.element.width, proxy.element.height); proxy.updateSnapCollection(); proxy.saveBackground(true); }; this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height); } }; SignatureBase.prototype.setBackgroundColor = function (color) { var canvasEle = this.canvasContext; canvasEle.strokeStyle = color; var i; var j; for (i = 1; i <= canvasEle.canvas.width; i++) { for (j = 1; j <= canvasEle.canvas.height; j++) { canvasEle.strokeRect(0, 0, i, j); } } this.updateSnapCollection(); }; SignatureBase.prototype.loadPersistedSignature = function () { if (isNullOrUndefined(this.signatureValue)) { return; } // eslint-disable-next-line @typescript-eslint/no-this-alias var proxy = this; var lastImage = new Image(); lastImage.src = this.signatureValue; lastImage.onload = function () { proxy.canvasContext.clearRect(0, 0, proxy.element.width, proxy.element.height); proxy.canvasContext.drawImage(lastImage, 0, 0); proxy.updateSnapCollection(); }; this.isSignatureEmpty = false; }; /** * To get the signature as Blob. * * @param {string} url - specify the url/base 64 string to get blob of the signature. * @returns {Blob}. */ SignatureBase.prototype.getBlob = function (url) { var arr = url.split(','); var type = arr[0].match(/:(.*?);/)[1]; var bstr = atob(arr[1]); var n = bstr.length; var u8arr = new Uint8Array(n); while (n--) { u8arr[n] = bstr.charCodeAt(n); } return new Blob([u8arr], { type: type }); }; SignatureBase.prototype.download = function (blob, fileName) { var blobUrl = URL.createObjectURL(blob); var a = document.createElement('a'); a.href = blobUrl; a.target = '_parent'; a.download = fileName; (document.body || document.documentElement).appendChild(a); a.click(); a.parentNode.removeChild(a); }; SignatureBase.prototype.internalRefresh = function () { this.pointColl = []; this.lastVelocity = 0; this.lastWidth = (this.minStrokeWidth + this.maxStrokeWidth) / 2; }; /** * To refresh the signature. * * @returns {void}. */ SignatureBase.prototype.refresh = function () { this.isResponsive = false; this.setHTMLProperties(); this.resizeHandler(); this.internalRefresh(); }; /** * Erases all the signature strokes signed by user. * * @returns {void}. */ SignatureBase.prototype.clear = function () { var args = { actionName: 'clear' }; this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height); this.tempContext.clearRect(0, 0, this.tempContext.canvas.width, this.tempContext.canvas.height); if (this.saveWithBackground && this.backgroundImage) { this.setBackgroundImage(this.backgroundImage, 'temp'); } this.internalRefresh(); this.signRatioPointsColl = []; this.updateSnapCollection(true); this.isSignatureEmpty = this.canRedraw = true; if (!this.isBlazor) { this.trigger('change', args); } else { this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'Clear'); } }; /** * Undo the last user action. * * @returns {void}. */ SignatureBase.prototype.undo = function () { var args = { actionName: 'undo' }; // eslint-disable-next-line @typescript-eslint/no-this-alias var proxy = this; if (this.incStep > 0) { this.incStep--; var undoImg_1 = new Image(); undoImg_1.src = this.snapColl[this.incStep]; undoImg_1.onload = function () { proxy.canvasContext.clearRect(0, 0, proxy.element.width, proxy.element.height); proxy.canvasContext.drawImage(undoImg_1, 0, 0, proxy.element.width, proxy.element.height); }; } this.isClear(); if (!this.isBlazor) { this.trigger('change', args); } else { this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'Undo'); } }; /** * Redo the last user action. * * @returns {void}. */ SignatureBase.prototype.redo = function () { var args = { actionName: 'redo' }; // eslint-disable-next-line @typescript-eslint/no-this-alias var proxy = this; if (this.incStep < this.snapColl.length - 1) { this.incStep++; var redoImg_1 = new Image(); redoImg_1.src = this.snapColl[this.incStep]; redoImg_1.onload = function () { proxy.canvasContext.clearRect(0, 0, proxy.element.width, proxy.element.height); proxy.canvasContext.drawImage(redoImg_1, 0, 0, proxy.element.width, proxy.element.height); }; } this.isClear(); if (!this.isBlazor) { this.trigger('change', args); } else { this.dotnetRef.invokeMethodAsync('TriggerEventAsync', 'Redo'); } }; SignatureBase.prototype.isClear = function () { if (this.clearArray) { var empty = false; for (var i = 0; i < this.clearArray.length; i++) { if (this.clearArray[i] === this.incStep) { this.isSignatureEmpty = true; empty = true; } } if (!empty) { this.isSignatureEmpty = false; } } }; /** * To check whether the signature is empty or not. * * @returns {boolean}. */ SignatureBase.prototype.isEmpty = function () { return this.isSignatureEmpty; }; /** * To check whether the undo collection is empty or not. * * @returns {boolean}. */ SignatureBase.prototype.canUndo = function () { return this.incStep > 0; }; /** * To check whether the redo collection is empty or not. * * @returns {boolean}. */ SignatureBase.prototype.canRedo = function () { return this.incStep < this.snapColl.length - 1; }; /** * To draw the signature based on the given text, with the font family and font size. * * @param {string} text - specify text to be drawn as signature. * @param {string} fontFamily - specify font family of a signature. * @param {number} fontSize - specify font size of a signature. * @param {number} x- Specifies the x-coordinate to start the text of a signature. Default to the center point of the image if it not specified. * @param {number} y - Specifies the y-coordinate to start the text of a signature. Default to the center point of the image if it not specified. * * @returns {void}. */ SignatureBase.prototype.draw = function (text, fontFamily, fontSize, x, y) { var args = { actionName: 'draw-text' }; this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height); fontFamily = fontFamily || 'Arial'; fontSize = fontSize || 30; this.canvasContext.font = fontSize + 'px ' + fontFamily; var startX = this.element.width / 2; var startY = this.element.height / 2; if (isNullOrUndefined(x) && isNullOrUndefined(y)) { this.canvasContext.textAlign = 'center'; this.canvasContext.textBaseline = 'middle'; } else { startX = isNullOrUndefined(x) ? startX : x; startY = isNullOrUndefined(y) ? startY + fontSize / 2 : (y + fontSize / 2); } this.canvasContext.fillText(text, startX, startY); this.updateSnapCollection(); this.isSignatureEmpty = false; this.trigger('change', args); }; /** * To load the signature with the given base 64 string, height and width. * * @param {string} signature - specify the url/base 64 string to be drawn as signature. * @param {number} width - specify the width of the loaded signature image. * @param {number} height - specify the height of the loaded signature image. * @returns {void}. */ SignatureBase.prototype.load = function (signature, width, height) { height = height || this.element.height; width = width || this.element.width; this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height); // eslint-disable-next-line @typescript-eslint/no-this-alias var proxy = this; var bitmapImage = new Image(); bitmapImage.src = signature; if (signature.slice(0, 4) !== 'data') { bitmapImage.crossOrigin = 'anonymous'; } bitmapImage.onload = function () { Promise.all([ createImageBitmap(bitmapImage, 0, 0, width, height) ]).then(function (results) { var tempCanvas = document.createElement('canvas'); tempCanvas.width = width; tempCanvas.height = height; tempCanvas.getContext('2d').drawImage(results[0], 0, 0); if (signature.slice(0, 4) !== 'data') { proxy.canvasContext.globalCompositeOperation = 'source-over'; } proxy.canvasContext.drawImage(tempCanvas, 0, 0, width, height, 0, 0, proxy.element.width, proxy.element.height); proxy.updateSnapCollection(); }); }; this.isSignatureEmpty = this.canRedraw = false; }; SignatureBase.prototype.saveBackground = function (savebg) { var imageSrc; if (savebg && this.backgroundImage) { imageSrc = this.snapColl[this.incStep - 1]; } else { imageSrc = this.snapColl[this.incStep]; } if (!savebg) { this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height); if (this.backgroundImage) { this.setBackgroundImage(this.backgroundImage); } else if (this.backgroundColor) { this.setBackgroundColor(this.backgroundColor); savebg = true; } } if (savebg) { // eslint-disable-next-line @typescript-eslint/no-this-alias var proxy_1 = this; var imageObj_1 = new Image(); imageObj_1.crossOrigin = 'anonymous'; imageObj_1.src = imageSrc; imageObj_1.onload = function () { proxy_1.backgroundLoaded = true; proxy_1.canvasContext.globalCompositeOperation = 'source-over'; proxy_1.canvasContext.drawImage(imageObj_1, 0, 0, proxy_1.element.width, proxy_1.element.height); proxy_1.save(proxy_1.fileType, proxy_1.fileName); }; } }; /** * To save the signature with the given file type and file name. * * @param {SignatureFileType} type - specify type of the file to be saved a signature. * @param {string} fileName - specify name of the file to be saved a signature. * * @returns {void}. */ SignatureBase.prototype.save = function (type, fileName) { if (this.saveWithBackground && this.backgroundLoaded == null && (this.backgroundImage || this.backgroundColor)) { this.backgroundLoaded = false; this.fileType = type; this.fileName = fileName; this.saveBackground(false); } else if (type === 'Svg') { fileName = fileName || 'Signature'; this.toSVG(fileName); } else if (type === 'Jpeg') { fileName = fileName || 'Signature'; if (!this.saveWithBackground || this.saveWithBackground && !(this.backgroundImage || this.backgroundColor)) { this.toJPEG(fileName); } else { var dataURL = this.canvasContext.canvas.toDataURL('image/jpeg'); this.download(this.getBlob(dataURL), fileName + '.' + 'jpeg'); } } else { fileName = fileName || 'Signature'; var dataURL = this.canvasContext.canvas.toDataURL('image/png'); this.download(this.getBlob(dataURL), fileName + '.' + 'png'); } if (this.saveWithBackground && this.backgroundLoaded) { this.resetSnap(); } }; SignatureBase.prototype.resetSnap = function () { this.canvasContext.clearRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height); // eslint-disable-next-line @typescript-eslint/no-this-alias var proxy = this; var restoreObj = new Image(); restoreObj.src = this.snapColl[this.incStep - 1]; restoreObj.onload = function () { proxy.canvasContext.drawImage(restoreObj, 0, 0, proxy.element.width, proxy.element.height); proxy.updateSnapCollection(); }; this.backgroundLoaded = null; this.snapColl.pop(); this.incStep--; this.snapColl.pop(); this.incStep--; }; SignatureBase.prototype.toJPEG = function (fileName) { var _this = this; var imageSrc = this.snapColl[this.incStep]; this.setBackgroundColor('#ffffff'); // eslint-disable-next-line @typescript-eslint/no-this-alias var proxy = this; var imageObj = new Image(); imageObj.crossOrigin = 'anonymous'; imageObj.src = imageSrc; imageObj.onload = function () { proxy.canvasContext.globalCompositeOperation = 'source-over'; proxy.canvasContext.drawImage(imageObj, 0, 0, proxy.element.width, proxy.element.height); var dataURL = proxy.canvasContext.canvas.toDataURL('image/jpeg'); proxy.download(proxy.getBlob(dataURL), fileName + '.' + 'jpeg'); proxy.canvasContext.clearRect(0, 0, proxy.canvasContext.canvas.width, proxy.canvasContext.canvas.height); _this.resizeHandler(); }; this.snapColl.pop(); this.incStep--; }; SignatureBase.prototype.toSVG = function (fileName, dataUrl) { var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); svg.setAttribute('width', this.canvasContext.canvas.width.toString()); svg.setAttribute('height', this.canvasContext.canvas.height.toString()); var XLinkNS = 'http://www.w3.org/1999/xlink'; var img = document.createElementNS('http://www.w3.org/2000/svg', 'image'); img.setAttributeNS(null, 'height', this.canvasContext.canvas.height.toString()); img.setAttributeNS(null, 'width', this.canvasContext.canvas.width.toString()); img.setAttributeNS(XLinkNS, 'xlink:href', dataUrl); svg.appendChild(img); var prefix = 'data:image/svg+xml;base64,'; var header = '<svg' + ' xmlns="http://www.w3.org/2000/svg"' + ' xmlns:xlink="http://www.w3.org/1999/xlink"' + (" width=\"" + this.canvasContext.canvas.width + "\"") + (" height=\"" + this.canvasContext.canvas.height + "\"") + '>'; var footer = '</svg>'; var body = svg.innerHTML; var data = header + body + footer; var svgDataUrl = prefix + btoa(data); if (fileName == null) { return svgDataUrl; } else { this.download(this.getBlob(svgDataUrl), fileName + '.' + 'svg'); return null; } }; /** * To save the signature as Blob. * * @returns {Blob}. */ SignatureBase.prototype.saveAsBlob = function () { return this.getBlob(this.canvasContext.canvas.toDataURL('image/png')); }; /** * Gets the signature as a Base 64 string. * * This method is used to retrieve the current signature on the canvas as a Base 64-encoded string, in the specified image format. * * @param {SignatureFileType} [type] - Specifies the type of the image format. * Can be one of 'Png', 'Jpeg', or 'Svg'. If not specified, the default is 'Png'. * @returns {string} - Returns the Base 64 string of the signature in the specified format. */ SignatureBase.prototype.getSignature = function (type) { if (this.saveWithBackground && this.backgroundColor && !this.backgroundImage) { this.tempContext.fillStyle = this.backgroundColor; this.tempContext.fillRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height); } else if (!this.backgroundColor && !this.backgroundImage && type === 'Jpeg') { this.tempContext.fillStyle = '#fff'; this.tempContext.fillRect(0, 0, this.canvasContext.canvas.width, this.canvasContext.canvas.height); } this.tempContext.drawImage(this.element, 0, 0); if (type === 'Jpeg') { return this.tempCanvas.toDataURL('image/jpeg'); } else if (type === 'Svg') { return this.toSVG(null, this.tempCanvas.toDataURL('image/png')); } else { return this.tempCanvas.toDataURL('image/png'); } }; /** * Get component name. * * @returns {string} - Module Name * @private */ SignatureBase.prototype.getModuleName = function () { return 'signature'; }; /** * To get the properties to be maintained in the persisted state. * * @returns {string} - Persist data */ SignatureBase.prototype.getPersistData = function () { this.signatureValue = this.snapColl[this.incStep]; return this.addOnPersist(['signatureValue']); }; /** * Removes the component from the DOM and detaches all its related event handlers. * Also it maintains the initial input element from the DOM. * * @method destroy * @returns {void} */ SignatureBase.prototype.destroy = function () { if (this.getModuleName() !== 'image-editor') { this.unwireEvents(null); removeClass([this.element], 'e-' + this.getModuleName()); this.element.removeAttribute('tabindex'); this.pointColl = null; this.tempContext = null; this.tempCanvas = null; this.canvasContext = null; } _super.prototype.destroy.call(this); this.element = null; }; /** * Modified onPropertyChanged method for both blazor and EJ2 signature component. * * @private * @param {string} key - Specifies the property, which changed. * @param {string} value - Specifies the property value changed. * @returns {void} */ SignatureBase.prototype.propertyChanged = function (key, value) { var canvasNew = this.canvasContext; switch (key) { case 'backgroundColor': canvasNew.canvas.style.backgroundColor = value; this.backgroundColor = value; break; case 'backgroundImage': canvasNew.canvas.style.backgroundImage = 'url(' + value + ')'; this.backgroundImage = value; if (this.saveWithBackground) { this.setBackgroundImage(this.backgroundImage, 'temp'); } break; case 'strokeColor': canvasNew.fillStyle = value; this.strokeColor = value; break; case 'saveWithBackground': this.saveWithBackground = value; break; case 'maxStrokeWidth': this.maxStrokeWidth = value; break; case 'minStrokeWidth': this.minStrokeWidth = value; break; case 'velocity': this.velocity = value; break; case 'isReadOnly': this.isRead(value); break; case 'disabled': this.enableOrDisable(value); break; } }; return SignatureBase; }(Component)); export { SignatureBase };