signature_pad
Advanced tools
Comparing version 4.2.0 to 5.0.0-beta.1
/*! | ||
* Signature Pad v4.2.0 | https://github.com/szimek/signature_pad | ||
* Signature Pad v5.0.0-beta.1 | https://github.com/szimek/signature_pad | ||
* (c) 2024 Szymon Nowak | Released under the MIT license | ||
@@ -163,52 +163,73 @@ */ | ||
this._handleMouseDown = (event) => { | ||
if (event.buttons === 1) { | ||
this._strokeBegin(event); | ||
if (!this._isLeftButtonPressed(event, true) || this._drawingStroke) { | ||
return; | ||
} | ||
this._strokeBegin(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handleMouseMove = (event) => { | ||
this._strokeMoveUpdate(event); | ||
if (!this._isLeftButtonPressed(event, true) || !this._drawingStroke) { | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event), false); | ||
return; | ||
} | ||
this._strokeMoveUpdate(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handleMouseUp = (event) => { | ||
if (event.buttons === 1) { | ||
this._strokeEnd(event); | ||
if (this._isLeftButtonPressed(event)) { | ||
return; | ||
} | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handleTouchStart = (event) => { | ||
if (event.targetTouches.length !== 1 || this._drawingStroke) { | ||
return; | ||
} | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
if (event.targetTouches.length === 1) { | ||
const touch = event.changedTouches[0]; | ||
this._strokeBegin(touch); | ||
} | ||
this._strokeBegin(this._touchEventToSignatureEvent(event)); | ||
}; | ||
this._handleTouchMove = (event) => { | ||
if (event.targetTouches.length !== 1) { | ||
return; | ||
} | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
const touch = event.targetTouches[0]; | ||
this._strokeMoveUpdate(touch); | ||
if (!this._drawingStroke) { | ||
this._strokeEnd(this._touchEventToSignatureEvent(event), false); | ||
return; | ||
} | ||
this._strokeMoveUpdate(this._touchEventToSignatureEvent(event)); | ||
}; | ||
this._handleTouchEnd = (event) => { | ||
const wasCanvasTouched = event.target === this.canvas; | ||
if (wasCanvasTouched) { | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
const touch = event.changedTouches[0]; | ||
this._strokeEnd(touch); | ||
if (event.targetTouches.length !== 0) { | ||
return; | ||
} | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
this.canvas.removeEventListener('touchmove', this._handleTouchMove); | ||
this._strokeEnd(this._touchEventToSignatureEvent(event)); | ||
}; | ||
this._handlePointerStart = (event) => { | ||
this._handlePointerDown = (event) => { | ||
if (!this._isLeftButtonPressed(event) || this._drawingStroke) { | ||
return; | ||
} | ||
event.preventDefault(); | ||
this._strokeBegin(event); | ||
this._strokeBegin(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handlePointerMove = (event) => { | ||
this._strokeMoveUpdate(event); | ||
if (!this._isLeftButtonPressed(event, true) || !this._drawingStroke) { | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event), false); | ||
return; | ||
} | ||
event.preventDefault(); | ||
this._strokeMoveUpdate(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handlePointerEnd = (event) => { | ||
if (this._drawingStroke) { | ||
event.preventDefault(); | ||
this._strokeEnd(event); | ||
this._handlePointerUp = (event) => { | ||
if (this._isLeftButtonPressed(event)) { | ||
return; | ||
} | ||
event.preventDefault(); | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
@@ -295,12 +316,26 @@ this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.canvas.style.userSelect = 'auto'; | ||
this.canvas.removeEventListener('pointerdown', this._handlePointerStart); | ||
this.canvas.removeEventListener('pointermove', this._handlePointerMove); | ||
this.canvas.ownerDocument.removeEventListener('pointerup', this._handlePointerEnd); | ||
this.canvas.removeEventListener('pointerdown', this._handlePointerDown); | ||
this.canvas.removeEventListener('mousedown', this._handleMouseDown); | ||
this.canvas.removeEventListener('mousemove', this._handleMouseMove); | ||
this.canvas.ownerDocument.removeEventListener('mouseup', this._handleMouseUp); | ||
this.canvas.removeEventListener('touchstart', this._handleTouchStart); | ||
this.canvas.removeEventListener('touchmove', this._handleTouchMove); | ||
this.canvas.removeEventListener('touchend', this._handleTouchEnd); | ||
this._removeMoveUpEventListeners(); | ||
} | ||
_getListenerFunctions() { | ||
var _a; | ||
const canvasWindow = window.document === this.canvas.ownerDocument | ||
? window | ||
: (_a = this.canvas.ownerDocument.defaultView) !== null && _a !== void 0 ? _a : this.canvas.ownerDocument; | ||
return { | ||
addEventListener: canvasWindow.addEventListener.bind(canvasWindow), | ||
removeEventListener: canvasWindow.removeEventListener.bind(canvasWindow), | ||
}; | ||
} | ||
_removeMoveUpEventListeners() { | ||
const { removeEventListener } = this._getListenerFunctions(); | ||
removeEventListener('pointermove', this._handlePointerMove); | ||
removeEventListener('pointerup', this._handlePointerUp); | ||
removeEventListener('mousemove', this._handleMouseMove); | ||
removeEventListener('mouseup', this._handleMouseUp); | ||
removeEventListener('touchmove', this._handleTouchMove); | ||
removeEventListener('touchend', this._handleTouchEnd); | ||
} | ||
isEmpty() { | ||
@@ -319,2 +354,27 @@ return this._isEmpty; | ||
} | ||
_isLeftButtonPressed(event, only) { | ||
if (only) { | ||
return event.buttons === 1; | ||
} | ||
return (event.buttons & 1) === 1; | ||
} | ||
_pointerEventToSignatureEvent(event) { | ||
return { | ||
event: event, | ||
type: event.type, | ||
x: event.clientX, | ||
y: event.clientY, | ||
pressure: 'pressure' in event ? event.pressure : 0, | ||
}; | ||
} | ||
_touchEventToSignatureEvent(event) { | ||
const touch = event.changedTouches[0]; | ||
return { | ||
event: event, | ||
type: event.type, | ||
x: touch.clientX, | ||
y: touch.clientY, | ||
pressure: touch.force, | ||
}; | ||
} | ||
_getPointGroupOptions(group) { | ||
@@ -339,2 +399,17 @@ return { | ||
} | ||
const { addEventListener } = this._getListenerFunctions(); | ||
switch (event.event.type) { | ||
case 'mousedown': | ||
addEventListener('mousemove', this._handleMouseMove); | ||
addEventListener('mouseup', this._handleMouseUp); | ||
break; | ||
case 'touchstart': | ||
addEventListener('touchmove', this._handleTouchMove); | ||
addEventListener('touchend', this._handleTouchEnd); | ||
break; | ||
case 'pointerdown': | ||
addEventListener('pointermove', this._handlePointerMove); | ||
addEventListener('pointerup', this._handlePointerUp); | ||
break; | ||
} | ||
this._drawingStroke = true; | ||
@@ -356,10 +431,3 @@ const pointGroupOptions = this._getPointGroupOptions(); | ||
this.dispatchEvent(new CustomEvent('beforeUpdateStroke', { detail: event })); | ||
const x = event.clientX; | ||
const y = event.clientY; | ||
const pressure = event.pressure !== undefined | ||
? event.pressure | ||
: event.force !== undefined | ||
? event.force | ||
: 0; | ||
const point = this._createPoint(x, y, pressure); | ||
const point = this._createPoint(event.x, event.y, event.pressure); | ||
const lastPointGroup = this._data[this._data.length - 1]; | ||
@@ -389,7 +457,10 @@ const lastPoints = lastPointGroup.points; | ||
} | ||
_strokeEnd(event) { | ||
_strokeEnd(event, shouldUpdate = true) { | ||
this._removeMoveUpEventListeners(); | ||
if (!this._drawingStroke) { | ||
return; | ||
} | ||
this._strokeUpdate(event); | ||
if (shouldUpdate) { | ||
this._strokeUpdate(event); | ||
} | ||
this._drawingStroke = false; | ||
@@ -400,5 +471,3 @@ this.dispatchEvent(new CustomEvent('endStroke', { detail: event })); | ||
this._drawingStroke = false; | ||
this.canvas.addEventListener('pointerdown', this._handlePointerStart); | ||
this.canvas.addEventListener('pointermove', this._handlePointerMove); | ||
this.canvas.ownerDocument.addEventListener('pointerup', this._handlePointerEnd); | ||
this.canvas.addEventListener('pointerdown', this._handlePointerDown); | ||
} | ||
@@ -408,9 +477,5 @@ _handleMouseEvents() { | ||
this.canvas.addEventListener('mousedown', this._handleMouseDown); | ||
this.canvas.addEventListener('mousemove', this._handleMouseMove); | ||
this.canvas.ownerDocument.addEventListener('mouseup', this._handleMouseUp); | ||
} | ||
_handleTouchEvents() { | ||
this.canvas.addEventListener('touchstart', this._handleTouchStart); | ||
this.canvas.addEventListener('touchmove', this._handleTouchMove); | ||
this.canvas.addEventListener('touchend', this._handleTouchEnd); | ||
} | ||
@@ -417,0 +482,0 @@ _reset(options) { |
/*! | ||
* Signature Pad v4.2.0 | https://github.com/szimek/signature_pad | ||
* Signature Pad v5.0.0-beta.1 | https://github.com/szimek/signature_pad | ||
* (c) 2024 Szymon Nowak | Released under the MIT license | ||
*/ | ||
class t{constructor(t,e,i,s){if(isNaN(t)||isNaN(e))throw new Error(`Point is invalid: (${t}, ${e})`);this.x=+t,this.y=+e,this.pressure=i||0,this.time=s||Date.now()}distanceTo(t){return Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))}equals(t){return this.x===t.x&&this.y===t.y&&this.pressure===t.pressure&&this.time===t.time}velocityFrom(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0}}class e{static fromPoints(t,i){const s=this.calculateControlPoints(t[0],t[1],t[2]).c2,n=this.calculateControlPoints(t[1],t[2],t[3]).c1;return new e(t[1],s,n,t[2],i.start,i.end)}static calculateControlPoints(e,i,s){const n=e.x-i.x,o=e.y-i.y,h=i.x-s.x,r=i.y-s.y,a=(e.x+i.x)/2,c=(e.y+i.y)/2,d=(i.x+s.x)/2,l=(i.y+s.y)/2,u=Math.sqrt(n*n+o*o),v=Math.sqrt(h*h+r*r),_=v/(u+v),p=d+(a-d)*_,m=l+(c-l)*_,g=i.x-p,x=i.y-m;return{c1:new t(a+g,c+x),c2:new t(d+g,l+x)}}constructor(t,e,i,s,n,o){this.startPoint=t,this.control2=e,this.control1=i,this.endPoint=s,this.startWidth=n,this.endWidth=o}length(){let t,e,i=0;for(let s=0;s<=10;s+=1){const n=s/10,o=this.point(n,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),h=this.point(n,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(s>0){const s=o-t,n=h-e;i+=Math.sqrt(s*s+n*n)}t=o,e=h}return i}point(t,e,i,s,n){return e*(1-t)*(1-t)*(1-t)+3*i*(1-t)*(1-t)*t+3*s*(1-t)*t*t+n*t*t*t}}class i{constructor(){try{this._et=new EventTarget}catch(t){this._et=document}}addEventListener(t,e,i){this._et.addEventListener(t,e,i)}dispatchEvent(t){return this._et.dispatchEvent(t)}removeEventListener(t,e,i){this._et.removeEventListener(t,e,i)}}class s extends i{constructor(t,e={}){super(),this.canvas=t,this._drawingStroke=!1,this._isEmpty=!0,this._lastPoints=[],this._data=[],this._lastVelocity=0,this._lastWidth=0,this._handleMouseDown=t=>{1===t.buttons&&this._strokeBegin(t)},this._handleMouseMove=t=>{this._strokeMoveUpdate(t)},this._handleMouseUp=t=>{1===t.buttons&&this._strokeEnd(t)},this._handleTouchStart=t=>{if(t.cancelable&&t.preventDefault(),1===t.targetTouches.length){const e=t.changedTouches[0];this._strokeBegin(e)}},this._handleTouchMove=t=>{t.cancelable&&t.preventDefault();const e=t.targetTouches[0];this._strokeMoveUpdate(e)},this._handleTouchEnd=t=>{if(t.target===this.canvas){t.cancelable&&t.preventDefault();const e=t.changedTouches[0];this._strokeEnd(e)}},this._handlePointerStart=t=>{t.preventDefault(),this._strokeBegin(t)},this._handlePointerMove=t=>{this._strokeMoveUpdate(t)},this._handlePointerEnd=t=>{this._drawingStroke&&(t.preventDefault(),this._strokeEnd(t))},this.velocityFilterWeight=e.velocityFilterWeight||.7,this.minWidth=e.minWidth||.5,this.maxWidth=e.maxWidth||2.5,this.throttle="throttle"in e?e.throttle:16,this.minDistance="minDistance"in e?e.minDistance:5,this.dotSize=e.dotSize||0,this.penColor=e.penColor||"black",this.backgroundColor=e.backgroundColor||"rgba(0,0,0,0)",this.compositeOperation=e.compositeOperation||"source-over",this.canvasContextOptions="canvasContextOptions"in e?e.canvasContextOptions:{},this._strokeMoveUpdate=this.throttle?function(t,e=250){let i,s,n,o=0,h=null;const r=()=>{o=Date.now(),h=null,i=t.apply(s,n),h||(s=null,n=[])};return function(...a){const c=Date.now(),d=e-(c-o);return s=this,n=a,d<=0||d>e?(h&&(clearTimeout(h),h=null),o=c,i=t.apply(s,n),h||(s=null,n=[])):h||(h=window.setTimeout(r,d)),i}}(s.prototype._strokeUpdate,this.throttle):s.prototype._strokeUpdate,this._ctx=t.getContext("2d",this.canvasContextOptions),this.clear(),this.on()}clear(){const{_ctx:t,canvas:e}=this;t.fillStyle=this.backgroundColor,t.clearRect(0,0,e.width,e.height),t.fillRect(0,0,e.width,e.height),this._data=[],this._reset(this._getPointGroupOptions()),this._isEmpty=!0}fromDataURL(t,e={}){return new Promise(((i,s)=>{const n=new Image,o=e.ratio||window.devicePixelRatio||1,h=e.width||this.canvas.width/o,r=e.height||this.canvas.height/o,a=e.xOffset||0,c=e.yOffset||0;this._reset(this._getPointGroupOptions()),n.onload=()=>{this._ctx.drawImage(n,a,c,h,r),i()},n.onerror=t=>{s(t)},n.crossOrigin="anonymous",n.src=t,this._isEmpty=!1}))}toDataURL(t="image/png",e){return"image/svg+xml"===t?("object"!=typeof e&&(e=void 0),`data:image/svg+xml;base64,${btoa(this.toSVG(e))}`):("number"!=typeof e&&(e=void 0),this.canvas.toDataURL(t,e))}on(){this.canvas.style.touchAction="none",this.canvas.style.msTouchAction="none",this.canvas.style.userSelect="none";const t=/Macintosh/.test(navigator.userAgent)&&"ontouchstart"in document;window.PointerEvent&&!t?this._handlePointerEvents():(this._handleMouseEvents(),"ontouchstart"in window&&this._handleTouchEvents())}off(){this.canvas.style.touchAction="auto",this.canvas.style.msTouchAction="auto",this.canvas.style.userSelect="auto",this.canvas.removeEventListener("pointerdown",this._handlePointerStart),this.canvas.removeEventListener("pointermove",this._handlePointerMove),this.canvas.ownerDocument.removeEventListener("pointerup",this._handlePointerEnd),this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("mousemove",this._handleMouseMove),this.canvas.ownerDocument.removeEventListener("mouseup",this._handleMouseUp),this.canvas.removeEventListener("touchstart",this._handleTouchStart),this.canvas.removeEventListener("touchmove",this._handleTouchMove),this.canvas.removeEventListener("touchend",this._handleTouchEnd)}isEmpty(){return this._isEmpty}fromData(t,{clear:e=!0}={}){e&&this.clear(),this._fromData(t,this._drawCurve.bind(this),this._drawDot.bind(this)),this._data=this._data.concat(t)}toData(){return this._data}_getPointGroupOptions(t){return{penColor:t&&"penColor"in t?t.penColor:this.penColor,dotSize:t&&"dotSize"in t?t.dotSize:this.dotSize,minWidth:t&&"minWidth"in t?t.minWidth:this.minWidth,maxWidth:t&&"maxWidth"in t?t.maxWidth:this.maxWidth,velocityFilterWeight:t&&"velocityFilterWeight"in t?t.velocityFilterWeight:this.velocityFilterWeight,compositeOperation:t&&"compositeOperation"in t?t.compositeOperation:this.compositeOperation}}_strokeBegin(t){if(!this.dispatchEvent(new CustomEvent("beginStroke",{detail:t,cancelable:!0})))return;this._drawingStroke=!0;const e=this._getPointGroupOptions(),i=Object.assign(Object.assign({},e),{points:[]});this._data.push(i),this._reset(e),this._strokeUpdate(t)}_strokeUpdate(t){if(!this._drawingStroke)return;if(0===this._data.length)return void this._strokeBegin(t);this.dispatchEvent(new CustomEvent("beforeUpdateStroke",{detail:t}));const e=t.clientX,i=t.clientY,s=void 0!==t.pressure?t.pressure:void 0!==t.force?t.force:0,n=this._createPoint(e,i,s),o=this._data[this._data.length-1],h=o.points,r=h.length>0&&h[h.length-1],a=!!r&&n.distanceTo(r)<=this.minDistance,c=this._getPointGroupOptions(o);if(!r||!r||!a){const t=this._addPoint(n,c);r?t&&this._drawCurve(t,c):this._drawDot(n,c),h.push({time:n.time,x:n.x,y:n.y,pressure:n.pressure})}this.dispatchEvent(new CustomEvent("afterUpdateStroke",{detail:t}))}_strokeEnd(t){this._drawingStroke&&(this._strokeUpdate(t),this._drawingStroke=!1,this.dispatchEvent(new CustomEvent("endStroke",{detail:t})))}_handlePointerEvents(){this._drawingStroke=!1,this.canvas.addEventListener("pointerdown",this._handlePointerStart),this.canvas.addEventListener("pointermove",this._handlePointerMove),this.canvas.ownerDocument.addEventListener("pointerup",this._handlePointerEnd)}_handleMouseEvents(){this._drawingStroke=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown),this.canvas.addEventListener("mousemove",this._handleMouseMove),this.canvas.ownerDocument.addEventListener("mouseup",this._handleMouseUp)}_handleTouchEvents(){this.canvas.addEventListener("touchstart",this._handleTouchStart),this.canvas.addEventListener("touchmove",this._handleTouchMove),this.canvas.addEventListener("touchend",this._handleTouchEnd)}_reset(t){this._lastPoints=[],this._lastVelocity=0,this._lastWidth=(t.minWidth+t.maxWidth)/2,this._ctx.fillStyle=t.penColor,this._ctx.globalCompositeOperation=t.compositeOperation}_createPoint(e,i,s){const n=this.canvas.getBoundingClientRect();return new t(e-n.left,i-n.top,s,(new Date).getTime())}_addPoint(t,i){const{_lastPoints:s}=this;if(s.push(t),s.length>2){3===s.length&&s.unshift(s[0]);const t=this._calculateCurveWidths(s[1],s[2],i),n=e.fromPoints(s,t);return s.shift(),n}return null}_calculateCurveWidths(t,e,i){const s=i.velocityFilterWeight*e.velocityFrom(t)+(1-i.velocityFilterWeight)*this._lastVelocity,n=this._strokeWidth(s,i),o={end:n,start:this._lastWidth};return this._lastVelocity=s,this._lastWidth=n,o}_strokeWidth(t,e){return Math.max(e.maxWidth/(t+1),e.minWidth)}_drawCurveSegment(t,e,i){const s=this._ctx;s.moveTo(t,e),s.arc(t,e,i,0,2*Math.PI,!1),this._isEmpty=!1}_drawCurve(t,e){const i=this._ctx,s=t.endWidth-t.startWidth,n=2*Math.ceil(t.length());i.beginPath(),i.fillStyle=e.penColor;for(let i=0;i<n;i+=1){const o=i/n,h=o*o,r=h*o,a=1-o,c=a*a,d=c*a;let l=d*t.startPoint.x;l+=3*c*o*t.control1.x,l+=3*a*h*t.control2.x,l+=r*t.endPoint.x;let u=d*t.startPoint.y;u+=3*c*o*t.control1.y,u+=3*a*h*t.control2.y,u+=r*t.endPoint.y;const v=Math.min(t.startWidth+r*s,e.maxWidth);this._drawCurveSegment(l,u,v)}i.closePath(),i.fill()}_drawDot(t,e){const i=this._ctx,s=e.dotSize>0?e.dotSize:(e.minWidth+e.maxWidth)/2;i.beginPath(),this._drawCurveSegment(t.x,t.y,s),i.closePath(),i.fillStyle=e.penColor,i.fill()}_fromData(e,i,s){for(const n of e){const{points:e}=n,o=this._getPointGroupOptions(n);if(e.length>1)for(let s=0;s<e.length;s+=1){const n=e[s],h=new t(n.x,n.y,n.pressure,n.time);0===s&&this._reset(o);const r=this._addPoint(h,o);r&&i(r,o)}else this._reset(o),s(e[0],o)}}toSVG({includeBackgroundColor:t=!1}={}){const e=this._data,i=Math.max(window.devicePixelRatio||1,1),s=this.canvas.width/i,n=this.canvas.height/i,o=document.createElementNS("http://www.w3.org/2000/svg","svg");if(o.setAttribute("xmlns","http://www.w3.org/2000/svg"),o.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),o.setAttribute("viewBox",`0 0 ${s} ${n}`),o.setAttribute("width",s.toString()),o.setAttribute("height",n.toString()),t&&this.backgroundColor){const t=document.createElement("rect");t.setAttribute("width","100%"),t.setAttribute("height","100%"),t.setAttribute("fill",this.backgroundColor),o.appendChild(t)}return this._fromData(e,((t,{penColor:e})=>{const i=document.createElement("path");if(!(isNaN(t.control1.x)||isNaN(t.control1.y)||isNaN(t.control2.x)||isNaN(t.control2.y))){const s=`M ${t.startPoint.x.toFixed(3)},${t.startPoint.y.toFixed(3)} C ${t.control1.x.toFixed(3)},${t.control1.y.toFixed(3)} ${t.control2.x.toFixed(3)},${t.control2.y.toFixed(3)} ${t.endPoint.x.toFixed(3)},${t.endPoint.y.toFixed(3)}`;i.setAttribute("d",s),i.setAttribute("stroke-width",(2.25*t.endWidth).toFixed(3)),i.setAttribute("stroke",e),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),o.appendChild(i)}}),((t,{penColor:e,dotSize:i,minWidth:s,maxWidth:n})=>{const h=document.createElement("circle"),r=i>0?i:(s+n)/2;h.setAttribute("r",r.toString()),h.setAttribute("cx",t.x.toString()),h.setAttribute("cy",t.y.toString()),h.setAttribute("fill",e),o.appendChild(h)})),o.outerHTML}}export{s as default}; | ||
class t{constructor(t,e,i,n){if(isNaN(t)||isNaN(e))throw new Error(`Point is invalid: (${t}, ${e})`);this.x=+t,this.y=+e,this.pressure=i||0,this.time=n||Date.now()}distanceTo(t){return Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))}equals(t){return this.x===t.x&&this.y===t.y&&this.pressure===t.pressure&&this.time===t.time}velocityFrom(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0}}class e{static fromPoints(t,i){const n=this.calculateControlPoints(t[0],t[1],t[2]).c2,s=this.calculateControlPoints(t[1],t[2],t[3]).c1;return new e(t[1],n,s,t[2],i.start,i.end)}static calculateControlPoints(e,i,n){const s=e.x-i.x,o=e.y-i.y,r=i.x-n.x,h=i.y-n.y,a=(e.x+i.x)/2,c=(e.y+i.y)/2,d=(i.x+n.x)/2,l=(i.y+n.y)/2,u=Math.sqrt(s*s+o*o),v=Math.sqrt(r*r+h*h),_=v/(u+v),p=d+(a-d)*_,m=l+(c-l)*_,g=i.x-p,w=i.y-m;return{c1:new t(a+g,c+w),c2:new t(d+g,l+w)}}constructor(t,e,i,n,s,o){this.startPoint=t,this.control2=e,this.control1=i,this.endPoint=n,this.startWidth=s,this.endWidth=o}length(){let t,e,i=0;for(let n=0;n<=10;n+=1){const s=n/10,o=this.point(s,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),r=this.point(s,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(n>0){const n=o-t,s=r-e;i+=Math.sqrt(n*n+s*s)}t=o,e=r}return i}point(t,e,i,n,s){return e*(1-t)*(1-t)*(1-t)+3*i*(1-t)*(1-t)*t+3*n*(1-t)*t*t+s*t*t*t}}class i{constructor(){try{this._et=new EventTarget}catch(t){this._et=document}}addEventListener(t,e,i){this._et.addEventListener(t,e,i)}dispatchEvent(t){return this._et.dispatchEvent(t)}removeEventListener(t,e,i){this._et.removeEventListener(t,e,i)}}class n extends i{constructor(t,e={}){super(),this.canvas=t,this._drawingStroke=!1,this._isEmpty=!0,this._lastPoints=[],this._data=[],this._lastVelocity=0,this._lastWidth=0,this._handleMouseDown=t=>{this._isLeftButtonPressed(t,!0)&&!this._drawingStroke&&this._strokeBegin(this._pointerEventToSignatureEvent(t))},this._handleMouseMove=t=>{this._isLeftButtonPressed(t,!0)&&this._drawingStroke?this._strokeMoveUpdate(this._pointerEventToSignatureEvent(t)):this._strokeEnd(this._pointerEventToSignatureEvent(t),!1)},this._handleMouseUp=t=>{this._isLeftButtonPressed(t)||this._strokeEnd(this._pointerEventToSignatureEvent(t))},this._handleTouchStart=t=>{1!==t.targetTouches.length||this._drawingStroke||(t.cancelable&&t.preventDefault(),this._strokeBegin(this._touchEventToSignatureEvent(t)))},this._handleTouchMove=t=>{1===t.targetTouches.length&&(t.cancelable&&t.preventDefault(),this._drawingStroke?this._strokeMoveUpdate(this._touchEventToSignatureEvent(t)):this._strokeEnd(this._touchEventToSignatureEvent(t),!1))},this._handleTouchEnd=t=>{0===t.targetTouches.length&&(t.cancelable&&t.preventDefault(),this.canvas.removeEventListener("touchmove",this._handleTouchMove),this._strokeEnd(this._touchEventToSignatureEvent(t)))},this._handlePointerDown=t=>{this._isLeftButtonPressed(t)&&!this._drawingStroke&&(t.preventDefault(),this._strokeBegin(this._pointerEventToSignatureEvent(t)))},this._handlePointerMove=t=>{this._isLeftButtonPressed(t,!0)&&this._drawingStroke?(t.preventDefault(),this._strokeMoveUpdate(this._pointerEventToSignatureEvent(t))):this._strokeEnd(this._pointerEventToSignatureEvent(t),!1)},this._handlePointerUp=t=>{this._isLeftButtonPressed(t)||(t.preventDefault(),this._strokeEnd(this._pointerEventToSignatureEvent(t)))},this.velocityFilterWeight=e.velocityFilterWeight||.7,this.minWidth=e.minWidth||.5,this.maxWidth=e.maxWidth||2.5,this.throttle="throttle"in e?e.throttle:16,this.minDistance="minDistance"in e?e.minDistance:5,this.dotSize=e.dotSize||0,this.penColor=e.penColor||"black",this.backgroundColor=e.backgroundColor||"rgba(0,0,0,0)",this.compositeOperation=e.compositeOperation||"source-over",this.canvasContextOptions="canvasContextOptions"in e?e.canvasContextOptions:{},this._strokeMoveUpdate=this.throttle?function(t,e=250){let i,n,s,o=0,r=null;const h=()=>{o=Date.now(),r=null,i=t.apply(n,s),r||(n=null,s=[])};return function(...a){const c=Date.now(),d=e-(c-o);return n=this,s=a,d<=0||d>e?(r&&(clearTimeout(r),r=null),o=c,i=t.apply(n,s),r||(n=null,s=[])):r||(r=window.setTimeout(h,d)),i}}(n.prototype._strokeUpdate,this.throttle):n.prototype._strokeUpdate,this._ctx=t.getContext("2d",this.canvasContextOptions),this.clear(),this.on()}clear(){const{_ctx:t,canvas:e}=this;t.fillStyle=this.backgroundColor,t.clearRect(0,0,e.width,e.height),t.fillRect(0,0,e.width,e.height),this._data=[],this._reset(this._getPointGroupOptions()),this._isEmpty=!0}fromDataURL(t,e={}){return new Promise(((i,n)=>{const s=new Image,o=e.ratio||window.devicePixelRatio||1,r=e.width||this.canvas.width/o,h=e.height||this.canvas.height/o,a=e.xOffset||0,c=e.yOffset||0;this._reset(this._getPointGroupOptions()),s.onload=()=>{this._ctx.drawImage(s,a,c,r,h),i()},s.onerror=t=>{n(t)},s.crossOrigin="anonymous",s.src=t,this._isEmpty=!1}))}toDataURL(t="image/png",e){return"image/svg+xml"===t?("object"!=typeof e&&(e=void 0),`data:image/svg+xml;base64,${btoa(this.toSVG(e))}`):("number"!=typeof e&&(e=void 0),this.canvas.toDataURL(t,e))}on(){this.canvas.style.touchAction="none",this.canvas.style.msTouchAction="none",this.canvas.style.userSelect="none";const t=/Macintosh/.test(navigator.userAgent)&&"ontouchstart"in document;window.PointerEvent&&!t?this._handlePointerEvents():(this._handleMouseEvents(),"ontouchstart"in window&&this._handleTouchEvents())}off(){this.canvas.style.touchAction="auto",this.canvas.style.msTouchAction="auto",this.canvas.style.userSelect="auto",this.canvas.removeEventListener("pointerdown",this._handlePointerDown),this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("touchstart",this._handleTouchStart),this._removeMoveUpEventListeners()}_getListenerFunctions(){var t;const e=window.document===this.canvas.ownerDocument?window:null!==(t=this.canvas.ownerDocument.defaultView)&&void 0!==t?t:this.canvas.ownerDocument;return{addEventListener:e.addEventListener.bind(e),removeEventListener:e.removeEventListener.bind(e)}}_removeMoveUpEventListeners(){const{removeEventListener:t}=this._getListenerFunctions();t("pointermove",this._handlePointerMove),t("pointerup",this._handlePointerUp),t("mousemove",this._handleMouseMove),t("mouseup",this._handleMouseUp),t("touchmove",this._handleTouchMove),t("touchend",this._handleTouchEnd)}isEmpty(){return this._isEmpty}fromData(t,{clear:e=!0}={}){e&&this.clear(),this._fromData(t,this._drawCurve.bind(this),this._drawDot.bind(this)),this._data=this._data.concat(t)}toData(){return this._data}_isLeftButtonPressed(t,e){return e?1===t.buttons:!(1&~t.buttons)}_pointerEventToSignatureEvent(t){return{event:t,type:t.type,x:t.clientX,y:t.clientY,pressure:"pressure"in t?t.pressure:0}}_touchEventToSignatureEvent(t){const e=t.changedTouches[0];return{event:t,type:t.type,x:e.clientX,y:e.clientY,pressure:e.force}}_getPointGroupOptions(t){return{penColor:t&&"penColor"in t?t.penColor:this.penColor,dotSize:t&&"dotSize"in t?t.dotSize:this.dotSize,minWidth:t&&"minWidth"in t?t.minWidth:this.minWidth,maxWidth:t&&"maxWidth"in t?t.maxWidth:this.maxWidth,velocityFilterWeight:t&&"velocityFilterWeight"in t?t.velocityFilterWeight:this.velocityFilterWeight,compositeOperation:t&&"compositeOperation"in t?t.compositeOperation:this.compositeOperation}}_strokeBegin(t){if(!this.dispatchEvent(new CustomEvent("beginStroke",{detail:t,cancelable:!0})))return;const{addEventListener:e}=this._getListenerFunctions();switch(t.event.type){case"mousedown":e("mousemove",this._handleMouseMove),e("mouseup",this._handleMouseUp);break;case"touchstart":e("touchmove",this._handleTouchMove),e("touchend",this._handleTouchEnd);break;case"pointerdown":e("pointermove",this._handlePointerMove),e("pointerup",this._handlePointerUp)}this._drawingStroke=!0;const i=this._getPointGroupOptions(),n=Object.assign(Object.assign({},i),{points:[]});this._data.push(n),this._reset(i),this._strokeUpdate(t)}_strokeUpdate(t){if(!this._drawingStroke)return;if(0===this._data.length)return void this._strokeBegin(t);this.dispatchEvent(new CustomEvent("beforeUpdateStroke",{detail:t}));const e=this._createPoint(t.x,t.y,t.pressure),i=this._data[this._data.length-1],n=i.points,s=n.length>0&&n[n.length-1],o=!!s&&e.distanceTo(s)<=this.minDistance,r=this._getPointGroupOptions(i);if(!s||!s||!o){const t=this._addPoint(e,r);s?t&&this._drawCurve(t,r):this._drawDot(e,r),n.push({time:e.time,x:e.x,y:e.y,pressure:e.pressure})}this.dispatchEvent(new CustomEvent("afterUpdateStroke",{detail:t}))}_strokeEnd(t,e=!0){this._removeMoveUpEventListeners(),this._drawingStroke&&(e&&this._strokeUpdate(t),this._drawingStroke=!1,this.dispatchEvent(new CustomEvent("endStroke",{detail:t})))}_handlePointerEvents(){this._drawingStroke=!1,this.canvas.addEventListener("pointerdown",this._handlePointerDown)}_handleMouseEvents(){this._drawingStroke=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown)}_handleTouchEvents(){this.canvas.addEventListener("touchstart",this._handleTouchStart)}_reset(t){this._lastPoints=[],this._lastVelocity=0,this._lastWidth=(t.minWidth+t.maxWidth)/2,this._ctx.fillStyle=t.penColor,this._ctx.globalCompositeOperation=t.compositeOperation}_createPoint(e,i,n){const s=this.canvas.getBoundingClientRect();return new t(e-s.left,i-s.top,n,(new Date).getTime())}_addPoint(t,i){const{_lastPoints:n}=this;if(n.push(t),n.length>2){3===n.length&&n.unshift(n[0]);const t=this._calculateCurveWidths(n[1],n[2],i),s=e.fromPoints(n,t);return n.shift(),s}return null}_calculateCurveWidths(t,e,i){const n=i.velocityFilterWeight*e.velocityFrom(t)+(1-i.velocityFilterWeight)*this._lastVelocity,s=this._strokeWidth(n,i),o={end:s,start:this._lastWidth};return this._lastVelocity=n,this._lastWidth=s,o}_strokeWidth(t,e){return Math.max(e.maxWidth/(t+1),e.minWidth)}_drawCurveSegment(t,e,i){const n=this._ctx;n.moveTo(t,e),n.arc(t,e,i,0,2*Math.PI,!1),this._isEmpty=!1}_drawCurve(t,e){const i=this._ctx,n=t.endWidth-t.startWidth,s=2*Math.ceil(t.length());i.beginPath(),i.fillStyle=e.penColor;for(let i=0;i<s;i+=1){const o=i/s,r=o*o,h=r*o,a=1-o,c=a*a,d=c*a;let l=d*t.startPoint.x;l+=3*c*o*t.control1.x,l+=3*a*r*t.control2.x,l+=h*t.endPoint.x;let u=d*t.startPoint.y;u+=3*c*o*t.control1.y,u+=3*a*r*t.control2.y,u+=h*t.endPoint.y;const v=Math.min(t.startWidth+h*n,e.maxWidth);this._drawCurveSegment(l,u,v)}i.closePath(),i.fill()}_drawDot(t,e){const i=this._ctx,n=e.dotSize>0?e.dotSize:(e.minWidth+e.maxWidth)/2;i.beginPath(),this._drawCurveSegment(t.x,t.y,n),i.closePath(),i.fillStyle=e.penColor,i.fill()}_fromData(e,i,n){for(const s of e){const{points:e}=s,o=this._getPointGroupOptions(s);if(e.length>1)for(let n=0;n<e.length;n+=1){const s=e[n],r=new t(s.x,s.y,s.pressure,s.time);0===n&&this._reset(o);const h=this._addPoint(r,o);h&&i(h,o)}else this._reset(o),n(e[0],o)}}toSVG({includeBackgroundColor:t=!1}={}){const e=this._data,i=Math.max(window.devicePixelRatio||1,1),n=this.canvas.width/i,s=this.canvas.height/i,o=document.createElementNS("http://www.w3.org/2000/svg","svg");if(o.setAttribute("xmlns","http://www.w3.org/2000/svg"),o.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),o.setAttribute("viewBox",`0 0 ${n} ${s}`),o.setAttribute("width",n.toString()),o.setAttribute("height",s.toString()),t&&this.backgroundColor){const t=document.createElement("rect");t.setAttribute("width","100%"),t.setAttribute("height","100%"),t.setAttribute("fill",this.backgroundColor),o.appendChild(t)}return this._fromData(e,((t,{penColor:e})=>{const i=document.createElement("path");if(!(isNaN(t.control1.x)||isNaN(t.control1.y)||isNaN(t.control2.x)||isNaN(t.control2.y))){const n=`M ${t.startPoint.x.toFixed(3)},${t.startPoint.y.toFixed(3)} C ${t.control1.x.toFixed(3)},${t.control1.y.toFixed(3)} ${t.control2.x.toFixed(3)},${t.control2.y.toFixed(3)} ${t.endPoint.x.toFixed(3)},${t.endPoint.y.toFixed(3)}`;i.setAttribute("d",n),i.setAttribute("stroke-width",(2.25*t.endWidth).toFixed(3)),i.setAttribute("stroke",e),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),o.appendChild(i)}}),((t,{penColor:e,dotSize:i,minWidth:n,maxWidth:s})=>{const r=document.createElement("circle"),h=i>0?i:(n+s)/2;r.setAttribute("r",h.toString()),r.setAttribute("cx",t.x.toString()),r.setAttribute("cy",t.y.toString()),r.setAttribute("fill",e),o.appendChild(r)})),o.outerHTML}}export{n as default}; | ||
//# sourceMappingURL=signature_pad.min.js.map |
/*! | ||
* Signature Pad v4.2.0 | https://github.com/szimek/signature_pad | ||
* Signature Pad v5.0.0-beta.1 | https://github.com/szimek/signature_pad | ||
* (c) 2024 Szymon Nowak | Released under the MIT license | ||
@@ -169,52 +169,73 @@ */ | ||
this._handleMouseDown = (event) => { | ||
if (event.buttons === 1) { | ||
this._strokeBegin(event); | ||
if (!this._isLeftButtonPressed(event, true) || this._drawingStroke) { | ||
return; | ||
} | ||
this._strokeBegin(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handleMouseMove = (event) => { | ||
this._strokeMoveUpdate(event); | ||
if (!this._isLeftButtonPressed(event, true) || !this._drawingStroke) { | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event), false); | ||
return; | ||
} | ||
this._strokeMoveUpdate(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handleMouseUp = (event) => { | ||
if (event.buttons === 1) { | ||
this._strokeEnd(event); | ||
if (this._isLeftButtonPressed(event)) { | ||
return; | ||
} | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handleTouchStart = (event) => { | ||
if (event.targetTouches.length !== 1 || this._drawingStroke) { | ||
return; | ||
} | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
if (event.targetTouches.length === 1) { | ||
const touch = event.changedTouches[0]; | ||
this._strokeBegin(touch); | ||
} | ||
this._strokeBegin(this._touchEventToSignatureEvent(event)); | ||
}; | ||
this._handleTouchMove = (event) => { | ||
if (event.targetTouches.length !== 1) { | ||
return; | ||
} | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
const touch = event.targetTouches[0]; | ||
this._strokeMoveUpdate(touch); | ||
if (!this._drawingStroke) { | ||
this._strokeEnd(this._touchEventToSignatureEvent(event), false); | ||
return; | ||
} | ||
this._strokeMoveUpdate(this._touchEventToSignatureEvent(event)); | ||
}; | ||
this._handleTouchEnd = (event) => { | ||
const wasCanvasTouched = event.target === this.canvas; | ||
if (wasCanvasTouched) { | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
const touch = event.changedTouches[0]; | ||
this._strokeEnd(touch); | ||
if (event.targetTouches.length !== 0) { | ||
return; | ||
} | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
this.canvas.removeEventListener('touchmove', this._handleTouchMove); | ||
this._strokeEnd(this._touchEventToSignatureEvent(event)); | ||
}; | ||
this._handlePointerStart = (event) => { | ||
this._handlePointerDown = (event) => { | ||
if (!this._isLeftButtonPressed(event) || this._drawingStroke) { | ||
return; | ||
} | ||
event.preventDefault(); | ||
this._strokeBegin(event); | ||
this._strokeBegin(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handlePointerMove = (event) => { | ||
this._strokeMoveUpdate(event); | ||
if (!this._isLeftButtonPressed(event, true) || !this._drawingStroke) { | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event), false); | ||
return; | ||
} | ||
event.preventDefault(); | ||
this._strokeMoveUpdate(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
this._handlePointerEnd = (event) => { | ||
if (this._drawingStroke) { | ||
event.preventDefault(); | ||
this._strokeEnd(event); | ||
this._handlePointerUp = (event) => { | ||
if (this._isLeftButtonPressed(event)) { | ||
return; | ||
} | ||
event.preventDefault(); | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
@@ -301,12 +322,26 @@ this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.canvas.style.userSelect = 'auto'; | ||
this.canvas.removeEventListener('pointerdown', this._handlePointerStart); | ||
this.canvas.removeEventListener('pointermove', this._handlePointerMove); | ||
this.canvas.ownerDocument.removeEventListener('pointerup', this._handlePointerEnd); | ||
this.canvas.removeEventListener('pointerdown', this._handlePointerDown); | ||
this.canvas.removeEventListener('mousedown', this._handleMouseDown); | ||
this.canvas.removeEventListener('mousemove', this._handleMouseMove); | ||
this.canvas.ownerDocument.removeEventListener('mouseup', this._handleMouseUp); | ||
this.canvas.removeEventListener('touchstart', this._handleTouchStart); | ||
this.canvas.removeEventListener('touchmove', this._handleTouchMove); | ||
this.canvas.removeEventListener('touchend', this._handleTouchEnd); | ||
this._removeMoveUpEventListeners(); | ||
} | ||
_getListenerFunctions() { | ||
var _a; | ||
const canvasWindow = window.document === this.canvas.ownerDocument | ||
? window | ||
: (_a = this.canvas.ownerDocument.defaultView) !== null && _a !== void 0 ? _a : this.canvas.ownerDocument; | ||
return { | ||
addEventListener: canvasWindow.addEventListener.bind(canvasWindow), | ||
removeEventListener: canvasWindow.removeEventListener.bind(canvasWindow), | ||
}; | ||
} | ||
_removeMoveUpEventListeners() { | ||
const { removeEventListener } = this._getListenerFunctions(); | ||
removeEventListener('pointermove', this._handlePointerMove); | ||
removeEventListener('pointerup', this._handlePointerUp); | ||
removeEventListener('mousemove', this._handleMouseMove); | ||
removeEventListener('mouseup', this._handleMouseUp); | ||
removeEventListener('touchmove', this._handleTouchMove); | ||
removeEventListener('touchend', this._handleTouchEnd); | ||
} | ||
isEmpty() { | ||
@@ -325,2 +360,27 @@ return this._isEmpty; | ||
} | ||
_isLeftButtonPressed(event, only) { | ||
if (only) { | ||
return event.buttons === 1; | ||
} | ||
return (event.buttons & 1) === 1; | ||
} | ||
_pointerEventToSignatureEvent(event) { | ||
return { | ||
event: event, | ||
type: event.type, | ||
x: event.clientX, | ||
y: event.clientY, | ||
pressure: 'pressure' in event ? event.pressure : 0, | ||
}; | ||
} | ||
_touchEventToSignatureEvent(event) { | ||
const touch = event.changedTouches[0]; | ||
return { | ||
event: event, | ||
type: event.type, | ||
x: touch.clientX, | ||
y: touch.clientY, | ||
pressure: touch.force, | ||
}; | ||
} | ||
_getPointGroupOptions(group) { | ||
@@ -345,2 +405,17 @@ return { | ||
} | ||
const { addEventListener } = this._getListenerFunctions(); | ||
switch (event.event.type) { | ||
case 'mousedown': | ||
addEventListener('mousemove', this._handleMouseMove); | ||
addEventListener('mouseup', this._handleMouseUp); | ||
break; | ||
case 'touchstart': | ||
addEventListener('touchmove', this._handleTouchMove); | ||
addEventListener('touchend', this._handleTouchEnd); | ||
break; | ||
case 'pointerdown': | ||
addEventListener('pointermove', this._handlePointerMove); | ||
addEventListener('pointerup', this._handlePointerUp); | ||
break; | ||
} | ||
this._drawingStroke = true; | ||
@@ -362,10 +437,3 @@ const pointGroupOptions = this._getPointGroupOptions(); | ||
this.dispatchEvent(new CustomEvent('beforeUpdateStroke', { detail: event })); | ||
const x = event.clientX; | ||
const y = event.clientY; | ||
const pressure = event.pressure !== undefined | ||
? event.pressure | ||
: event.force !== undefined | ||
? event.force | ||
: 0; | ||
const point = this._createPoint(x, y, pressure); | ||
const point = this._createPoint(event.x, event.y, event.pressure); | ||
const lastPointGroup = this._data[this._data.length - 1]; | ||
@@ -395,7 +463,10 @@ const lastPoints = lastPointGroup.points; | ||
} | ||
_strokeEnd(event) { | ||
_strokeEnd(event, shouldUpdate = true) { | ||
this._removeMoveUpEventListeners(); | ||
if (!this._drawingStroke) { | ||
return; | ||
} | ||
this._strokeUpdate(event); | ||
if (shouldUpdate) { | ||
this._strokeUpdate(event); | ||
} | ||
this._drawingStroke = false; | ||
@@ -406,5 +477,3 @@ this.dispatchEvent(new CustomEvent('endStroke', { detail: event })); | ||
this._drawingStroke = false; | ||
this.canvas.addEventListener('pointerdown', this._handlePointerStart); | ||
this.canvas.addEventListener('pointermove', this._handlePointerMove); | ||
this.canvas.ownerDocument.addEventListener('pointerup', this._handlePointerEnd); | ||
this.canvas.addEventListener('pointerdown', this._handlePointerDown); | ||
} | ||
@@ -414,9 +483,5 @@ _handleMouseEvents() { | ||
this.canvas.addEventListener('mousedown', this._handleMouseDown); | ||
this.canvas.addEventListener('mousemove', this._handleMouseMove); | ||
this.canvas.ownerDocument.addEventListener('mouseup', this._handleMouseUp); | ||
} | ||
_handleTouchEvents() { | ||
this.canvas.addEventListener('touchstart', this._handleTouchStart); | ||
this.canvas.addEventListener('touchmove', this._handleTouchMove); | ||
this.canvas.addEventListener('touchend', this._handleTouchEnd); | ||
} | ||
@@ -423,0 +488,0 @@ _reset(options) { |
/*! | ||
* Signature Pad v4.2.0 | https://github.com/szimek/signature_pad | ||
* Signature Pad v5.0.0-beta.1 | https://github.com/szimek/signature_pad | ||
* (c) 2024 Szymon Nowak | Released under the MIT license | ||
*/ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).SignaturePad=e()}(this,(function(){"use strict";class t{constructor(t,e,i,s){if(isNaN(t)||isNaN(e))throw new Error(`Point is invalid: (${t}, ${e})`);this.x=+t,this.y=+e,this.pressure=i||0,this.time=s||Date.now()}distanceTo(t){return Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))}equals(t){return this.x===t.x&&this.y===t.y&&this.pressure===t.pressure&&this.time===t.time}velocityFrom(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0}}class e{static fromPoints(t,i){const s=this.calculateControlPoints(t[0],t[1],t[2]).c2,n=this.calculateControlPoints(t[1],t[2],t[3]).c1;return new e(t[1],s,n,t[2],i.start,i.end)}static calculateControlPoints(e,i,s){const n=e.x-i.x,o=e.y-i.y,h=i.x-s.x,r=i.y-s.y,a=(e.x+i.x)/2,c=(e.y+i.y)/2,d=(i.x+s.x)/2,l=(i.y+s.y)/2,u=Math.sqrt(n*n+o*o),v=Math.sqrt(h*h+r*r),p=v/(u+v),_=d+(a-d)*p,m=l+(c-l)*p,g=i.x-_,x=i.y-m;return{c1:new t(a+g,c+x),c2:new t(d+g,l+x)}}constructor(t,e,i,s,n,o){this.startPoint=t,this.control2=e,this.control1=i,this.endPoint=s,this.startWidth=n,this.endWidth=o}length(){let t,e,i=0;for(let s=0;s<=10;s+=1){const n=s/10,o=this.point(n,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),h=this.point(n,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(s>0){const s=o-t,n=h-e;i+=Math.sqrt(s*s+n*n)}t=o,e=h}return i}point(t,e,i,s,n){return e*(1-t)*(1-t)*(1-t)+3*i*(1-t)*(1-t)*t+3*s*(1-t)*t*t+n*t*t*t}}class i{constructor(){try{this._et=new EventTarget}catch(t){this._et=document}}addEventListener(t,e,i){this._et.addEventListener(t,e,i)}dispatchEvent(t){return this._et.dispatchEvent(t)}removeEventListener(t,e,i){this._et.removeEventListener(t,e,i)}}class s extends i{constructor(t,e={}){super(),this.canvas=t,this._drawingStroke=!1,this._isEmpty=!0,this._lastPoints=[],this._data=[],this._lastVelocity=0,this._lastWidth=0,this._handleMouseDown=t=>{1===t.buttons&&this._strokeBegin(t)},this._handleMouseMove=t=>{this._strokeMoveUpdate(t)},this._handleMouseUp=t=>{1===t.buttons&&this._strokeEnd(t)},this._handleTouchStart=t=>{if(t.cancelable&&t.preventDefault(),1===t.targetTouches.length){const e=t.changedTouches[0];this._strokeBegin(e)}},this._handleTouchMove=t=>{t.cancelable&&t.preventDefault();const e=t.targetTouches[0];this._strokeMoveUpdate(e)},this._handleTouchEnd=t=>{if(t.target===this.canvas){t.cancelable&&t.preventDefault();const e=t.changedTouches[0];this._strokeEnd(e)}},this._handlePointerStart=t=>{t.preventDefault(),this._strokeBegin(t)},this._handlePointerMove=t=>{this._strokeMoveUpdate(t)},this._handlePointerEnd=t=>{this._drawingStroke&&(t.preventDefault(),this._strokeEnd(t))},this.velocityFilterWeight=e.velocityFilterWeight||.7,this.minWidth=e.minWidth||.5,this.maxWidth=e.maxWidth||2.5,this.throttle="throttle"in e?e.throttle:16,this.minDistance="minDistance"in e?e.minDistance:5,this.dotSize=e.dotSize||0,this.penColor=e.penColor||"black",this.backgroundColor=e.backgroundColor||"rgba(0,0,0,0)",this.compositeOperation=e.compositeOperation||"source-over",this.canvasContextOptions="canvasContextOptions"in e?e.canvasContextOptions:{},this._strokeMoveUpdate=this.throttle?function(t,e=250){let i,s,n,o=0,h=null;const r=()=>{o=Date.now(),h=null,i=t.apply(s,n),h||(s=null,n=[])};return function(...a){const c=Date.now(),d=e-(c-o);return s=this,n=a,d<=0||d>e?(h&&(clearTimeout(h),h=null),o=c,i=t.apply(s,n),h||(s=null,n=[])):h||(h=window.setTimeout(r,d)),i}}(s.prototype._strokeUpdate,this.throttle):s.prototype._strokeUpdate,this._ctx=t.getContext("2d",this.canvasContextOptions),this.clear(),this.on()}clear(){const{_ctx:t,canvas:e}=this;t.fillStyle=this.backgroundColor,t.clearRect(0,0,e.width,e.height),t.fillRect(0,0,e.width,e.height),this._data=[],this._reset(this._getPointGroupOptions()),this._isEmpty=!0}fromDataURL(t,e={}){return new Promise(((i,s)=>{const n=new Image,o=e.ratio||window.devicePixelRatio||1,h=e.width||this.canvas.width/o,r=e.height||this.canvas.height/o,a=e.xOffset||0,c=e.yOffset||0;this._reset(this._getPointGroupOptions()),n.onload=()=>{this._ctx.drawImage(n,a,c,h,r),i()},n.onerror=t=>{s(t)},n.crossOrigin="anonymous",n.src=t,this._isEmpty=!1}))}toDataURL(t="image/png",e){return"image/svg+xml"===t?("object"!=typeof e&&(e=void 0),`data:image/svg+xml;base64,${btoa(this.toSVG(e))}`):("number"!=typeof e&&(e=void 0),this.canvas.toDataURL(t,e))}on(){this.canvas.style.touchAction="none",this.canvas.style.msTouchAction="none",this.canvas.style.userSelect="none";const t=/Macintosh/.test(navigator.userAgent)&&"ontouchstart"in document;window.PointerEvent&&!t?this._handlePointerEvents():(this._handleMouseEvents(),"ontouchstart"in window&&this._handleTouchEvents())}off(){this.canvas.style.touchAction="auto",this.canvas.style.msTouchAction="auto",this.canvas.style.userSelect="auto",this.canvas.removeEventListener("pointerdown",this._handlePointerStart),this.canvas.removeEventListener("pointermove",this._handlePointerMove),this.canvas.ownerDocument.removeEventListener("pointerup",this._handlePointerEnd),this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("mousemove",this._handleMouseMove),this.canvas.ownerDocument.removeEventListener("mouseup",this._handleMouseUp),this.canvas.removeEventListener("touchstart",this._handleTouchStart),this.canvas.removeEventListener("touchmove",this._handleTouchMove),this.canvas.removeEventListener("touchend",this._handleTouchEnd)}isEmpty(){return this._isEmpty}fromData(t,{clear:e=!0}={}){e&&this.clear(),this._fromData(t,this._drawCurve.bind(this),this._drawDot.bind(this)),this._data=this._data.concat(t)}toData(){return this._data}_getPointGroupOptions(t){return{penColor:t&&"penColor"in t?t.penColor:this.penColor,dotSize:t&&"dotSize"in t?t.dotSize:this.dotSize,minWidth:t&&"minWidth"in t?t.minWidth:this.minWidth,maxWidth:t&&"maxWidth"in t?t.maxWidth:this.maxWidth,velocityFilterWeight:t&&"velocityFilterWeight"in t?t.velocityFilterWeight:this.velocityFilterWeight,compositeOperation:t&&"compositeOperation"in t?t.compositeOperation:this.compositeOperation}}_strokeBegin(t){if(!this.dispatchEvent(new CustomEvent("beginStroke",{detail:t,cancelable:!0})))return;this._drawingStroke=!0;const e=this._getPointGroupOptions(),i=Object.assign(Object.assign({},e),{points:[]});this._data.push(i),this._reset(e),this._strokeUpdate(t)}_strokeUpdate(t){if(!this._drawingStroke)return;if(0===this._data.length)return void this._strokeBegin(t);this.dispatchEvent(new CustomEvent("beforeUpdateStroke",{detail:t}));const e=t.clientX,i=t.clientY,s=void 0!==t.pressure?t.pressure:void 0!==t.force?t.force:0,n=this._createPoint(e,i,s),o=this._data[this._data.length-1],h=o.points,r=h.length>0&&h[h.length-1],a=!!r&&n.distanceTo(r)<=this.minDistance,c=this._getPointGroupOptions(o);if(!r||!r||!a){const t=this._addPoint(n,c);r?t&&this._drawCurve(t,c):this._drawDot(n,c),h.push({time:n.time,x:n.x,y:n.y,pressure:n.pressure})}this.dispatchEvent(new CustomEvent("afterUpdateStroke",{detail:t}))}_strokeEnd(t){this._drawingStroke&&(this._strokeUpdate(t),this._drawingStroke=!1,this.dispatchEvent(new CustomEvent("endStroke",{detail:t})))}_handlePointerEvents(){this._drawingStroke=!1,this.canvas.addEventListener("pointerdown",this._handlePointerStart),this.canvas.addEventListener("pointermove",this._handlePointerMove),this.canvas.ownerDocument.addEventListener("pointerup",this._handlePointerEnd)}_handleMouseEvents(){this._drawingStroke=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown),this.canvas.addEventListener("mousemove",this._handleMouseMove),this.canvas.ownerDocument.addEventListener("mouseup",this._handleMouseUp)}_handleTouchEvents(){this.canvas.addEventListener("touchstart",this._handleTouchStart),this.canvas.addEventListener("touchmove",this._handleTouchMove),this.canvas.addEventListener("touchend",this._handleTouchEnd)}_reset(t){this._lastPoints=[],this._lastVelocity=0,this._lastWidth=(t.minWidth+t.maxWidth)/2,this._ctx.fillStyle=t.penColor,this._ctx.globalCompositeOperation=t.compositeOperation}_createPoint(e,i,s){const n=this.canvas.getBoundingClientRect();return new t(e-n.left,i-n.top,s,(new Date).getTime())}_addPoint(t,i){const{_lastPoints:s}=this;if(s.push(t),s.length>2){3===s.length&&s.unshift(s[0]);const t=this._calculateCurveWidths(s[1],s[2],i),n=e.fromPoints(s,t);return s.shift(),n}return null}_calculateCurveWidths(t,e,i){const s=i.velocityFilterWeight*e.velocityFrom(t)+(1-i.velocityFilterWeight)*this._lastVelocity,n=this._strokeWidth(s,i),o={end:n,start:this._lastWidth};return this._lastVelocity=s,this._lastWidth=n,o}_strokeWidth(t,e){return Math.max(e.maxWidth/(t+1),e.minWidth)}_drawCurveSegment(t,e,i){const s=this._ctx;s.moveTo(t,e),s.arc(t,e,i,0,2*Math.PI,!1),this._isEmpty=!1}_drawCurve(t,e){const i=this._ctx,s=t.endWidth-t.startWidth,n=2*Math.ceil(t.length());i.beginPath(),i.fillStyle=e.penColor;for(let i=0;i<n;i+=1){const o=i/n,h=o*o,r=h*o,a=1-o,c=a*a,d=c*a;let l=d*t.startPoint.x;l+=3*c*o*t.control1.x,l+=3*a*h*t.control2.x,l+=r*t.endPoint.x;let u=d*t.startPoint.y;u+=3*c*o*t.control1.y,u+=3*a*h*t.control2.y,u+=r*t.endPoint.y;const v=Math.min(t.startWidth+r*s,e.maxWidth);this._drawCurveSegment(l,u,v)}i.closePath(),i.fill()}_drawDot(t,e){const i=this._ctx,s=e.dotSize>0?e.dotSize:(e.minWidth+e.maxWidth)/2;i.beginPath(),this._drawCurveSegment(t.x,t.y,s),i.closePath(),i.fillStyle=e.penColor,i.fill()}_fromData(e,i,s){for(const n of e){const{points:e}=n,o=this._getPointGroupOptions(n);if(e.length>1)for(let s=0;s<e.length;s+=1){const n=e[s],h=new t(n.x,n.y,n.pressure,n.time);0===s&&this._reset(o);const r=this._addPoint(h,o);r&&i(r,o)}else this._reset(o),s(e[0],o)}}toSVG({includeBackgroundColor:t=!1}={}){const e=this._data,i=Math.max(window.devicePixelRatio||1,1),s=this.canvas.width/i,n=this.canvas.height/i,o=document.createElementNS("http://www.w3.org/2000/svg","svg");if(o.setAttribute("xmlns","http://www.w3.org/2000/svg"),o.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),o.setAttribute("viewBox",`0 0 ${s} ${n}`),o.setAttribute("width",s.toString()),o.setAttribute("height",n.toString()),t&&this.backgroundColor){const t=document.createElement("rect");t.setAttribute("width","100%"),t.setAttribute("height","100%"),t.setAttribute("fill",this.backgroundColor),o.appendChild(t)}return this._fromData(e,((t,{penColor:e})=>{const i=document.createElement("path");if(!(isNaN(t.control1.x)||isNaN(t.control1.y)||isNaN(t.control2.x)||isNaN(t.control2.y))){const s=`M ${t.startPoint.x.toFixed(3)},${t.startPoint.y.toFixed(3)} C ${t.control1.x.toFixed(3)},${t.control1.y.toFixed(3)} ${t.control2.x.toFixed(3)},${t.control2.y.toFixed(3)} ${t.endPoint.x.toFixed(3)},${t.endPoint.y.toFixed(3)}`;i.setAttribute("d",s),i.setAttribute("stroke-width",(2.25*t.endWidth).toFixed(3)),i.setAttribute("stroke",e),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),o.appendChild(i)}}),((t,{penColor:e,dotSize:i,minWidth:s,maxWidth:n})=>{const h=document.createElement("circle"),r=i>0?i:(s+n)/2;h.setAttribute("r",r.toString()),h.setAttribute("cx",t.x.toString()),h.setAttribute("cy",t.y.toString()),h.setAttribute("fill",e),o.appendChild(h)})),o.outerHTML}}return s})); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).SignaturePad=e()}(this,(function(){"use strict";class t{constructor(t,e,i,n){if(isNaN(t)||isNaN(e))throw new Error(`Point is invalid: (${t}, ${e})`);this.x=+t,this.y=+e,this.pressure=i||0,this.time=n||Date.now()}distanceTo(t){return Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))}equals(t){return this.x===t.x&&this.y===t.y&&this.pressure===t.pressure&&this.time===t.time}velocityFrom(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0}}class e{static fromPoints(t,i){const n=this.calculateControlPoints(t[0],t[1],t[2]).c2,s=this.calculateControlPoints(t[1],t[2],t[3]).c1;return new e(t[1],n,s,t[2],i.start,i.end)}static calculateControlPoints(e,i,n){const s=e.x-i.x,o=e.y-i.y,r=i.x-n.x,h=i.y-n.y,a=(e.x+i.x)/2,c=(e.y+i.y)/2,d=(i.x+n.x)/2,l=(i.y+n.y)/2,u=Math.sqrt(s*s+o*o),v=Math.sqrt(r*r+h*h),_=v/(u+v),p=d+(a-d)*_,m=l+(c-l)*_,g=i.x-p,w=i.y-m;return{c1:new t(a+g,c+w),c2:new t(d+g,l+w)}}constructor(t,e,i,n,s,o){this.startPoint=t,this.control2=e,this.control1=i,this.endPoint=n,this.startWidth=s,this.endWidth=o}length(){let t,e,i=0;for(let n=0;n<=10;n+=1){const s=n/10,o=this.point(s,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),r=this.point(s,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(n>0){const n=o-t,s=r-e;i+=Math.sqrt(n*n+s*s)}t=o,e=r}return i}point(t,e,i,n,s){return e*(1-t)*(1-t)*(1-t)+3*i*(1-t)*(1-t)*t+3*n*(1-t)*t*t+s*t*t*t}}class i{constructor(){try{this._et=new EventTarget}catch(t){this._et=document}}addEventListener(t,e,i){this._et.addEventListener(t,e,i)}dispatchEvent(t){return this._et.dispatchEvent(t)}removeEventListener(t,e,i){this._et.removeEventListener(t,e,i)}}class n extends i{constructor(t,e={}){super(),this.canvas=t,this._drawingStroke=!1,this._isEmpty=!0,this._lastPoints=[],this._data=[],this._lastVelocity=0,this._lastWidth=0,this._handleMouseDown=t=>{this._isLeftButtonPressed(t,!0)&&!this._drawingStroke&&this._strokeBegin(this._pointerEventToSignatureEvent(t))},this._handleMouseMove=t=>{this._isLeftButtonPressed(t,!0)&&this._drawingStroke?this._strokeMoveUpdate(this._pointerEventToSignatureEvent(t)):this._strokeEnd(this._pointerEventToSignatureEvent(t),!1)},this._handleMouseUp=t=>{this._isLeftButtonPressed(t)||this._strokeEnd(this._pointerEventToSignatureEvent(t))},this._handleTouchStart=t=>{1!==t.targetTouches.length||this._drawingStroke||(t.cancelable&&t.preventDefault(),this._strokeBegin(this._touchEventToSignatureEvent(t)))},this._handleTouchMove=t=>{1===t.targetTouches.length&&(t.cancelable&&t.preventDefault(),this._drawingStroke?this._strokeMoveUpdate(this._touchEventToSignatureEvent(t)):this._strokeEnd(this._touchEventToSignatureEvent(t),!1))},this._handleTouchEnd=t=>{0===t.targetTouches.length&&(t.cancelable&&t.preventDefault(),this.canvas.removeEventListener("touchmove",this._handleTouchMove),this._strokeEnd(this._touchEventToSignatureEvent(t)))},this._handlePointerDown=t=>{this._isLeftButtonPressed(t)&&!this._drawingStroke&&(t.preventDefault(),this._strokeBegin(this._pointerEventToSignatureEvent(t)))},this._handlePointerMove=t=>{this._isLeftButtonPressed(t,!0)&&this._drawingStroke?(t.preventDefault(),this._strokeMoveUpdate(this._pointerEventToSignatureEvent(t))):this._strokeEnd(this._pointerEventToSignatureEvent(t),!1)},this._handlePointerUp=t=>{this._isLeftButtonPressed(t)||(t.preventDefault(),this._strokeEnd(this._pointerEventToSignatureEvent(t)))},this.velocityFilterWeight=e.velocityFilterWeight||.7,this.minWidth=e.minWidth||.5,this.maxWidth=e.maxWidth||2.5,this.throttle="throttle"in e?e.throttle:16,this.minDistance="minDistance"in e?e.minDistance:5,this.dotSize=e.dotSize||0,this.penColor=e.penColor||"black",this.backgroundColor=e.backgroundColor||"rgba(0,0,0,0)",this.compositeOperation=e.compositeOperation||"source-over",this.canvasContextOptions="canvasContextOptions"in e?e.canvasContextOptions:{},this._strokeMoveUpdate=this.throttle?function(t,e=250){let i,n,s,o=0,r=null;const h=()=>{o=Date.now(),r=null,i=t.apply(n,s),r||(n=null,s=[])};return function(...a){const c=Date.now(),d=e-(c-o);return n=this,s=a,d<=0||d>e?(r&&(clearTimeout(r),r=null),o=c,i=t.apply(n,s),r||(n=null,s=[])):r||(r=window.setTimeout(h,d)),i}}(n.prototype._strokeUpdate,this.throttle):n.prototype._strokeUpdate,this._ctx=t.getContext("2d",this.canvasContextOptions),this.clear(),this.on()}clear(){const{_ctx:t,canvas:e}=this;t.fillStyle=this.backgroundColor,t.clearRect(0,0,e.width,e.height),t.fillRect(0,0,e.width,e.height),this._data=[],this._reset(this._getPointGroupOptions()),this._isEmpty=!0}fromDataURL(t,e={}){return new Promise(((i,n)=>{const s=new Image,o=e.ratio||window.devicePixelRatio||1,r=e.width||this.canvas.width/o,h=e.height||this.canvas.height/o,a=e.xOffset||0,c=e.yOffset||0;this._reset(this._getPointGroupOptions()),s.onload=()=>{this._ctx.drawImage(s,a,c,r,h),i()},s.onerror=t=>{n(t)},s.crossOrigin="anonymous",s.src=t,this._isEmpty=!1}))}toDataURL(t="image/png",e){return"image/svg+xml"===t?("object"!=typeof e&&(e=void 0),`data:image/svg+xml;base64,${btoa(this.toSVG(e))}`):("number"!=typeof e&&(e=void 0),this.canvas.toDataURL(t,e))}on(){this.canvas.style.touchAction="none",this.canvas.style.msTouchAction="none",this.canvas.style.userSelect="none";const t=/Macintosh/.test(navigator.userAgent)&&"ontouchstart"in document;window.PointerEvent&&!t?this._handlePointerEvents():(this._handleMouseEvents(),"ontouchstart"in window&&this._handleTouchEvents())}off(){this.canvas.style.touchAction="auto",this.canvas.style.msTouchAction="auto",this.canvas.style.userSelect="auto",this.canvas.removeEventListener("pointerdown",this._handlePointerDown),this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("touchstart",this._handleTouchStart),this._removeMoveUpEventListeners()}_getListenerFunctions(){var t;const e=window.document===this.canvas.ownerDocument?window:null!==(t=this.canvas.ownerDocument.defaultView)&&void 0!==t?t:this.canvas.ownerDocument;return{addEventListener:e.addEventListener.bind(e),removeEventListener:e.removeEventListener.bind(e)}}_removeMoveUpEventListeners(){const{removeEventListener:t}=this._getListenerFunctions();t("pointermove",this._handlePointerMove),t("pointerup",this._handlePointerUp),t("mousemove",this._handleMouseMove),t("mouseup",this._handleMouseUp),t("touchmove",this._handleTouchMove),t("touchend",this._handleTouchEnd)}isEmpty(){return this._isEmpty}fromData(t,{clear:e=!0}={}){e&&this.clear(),this._fromData(t,this._drawCurve.bind(this),this._drawDot.bind(this)),this._data=this._data.concat(t)}toData(){return this._data}_isLeftButtonPressed(t,e){return e?1===t.buttons:!(1&~t.buttons)}_pointerEventToSignatureEvent(t){return{event:t,type:t.type,x:t.clientX,y:t.clientY,pressure:"pressure"in t?t.pressure:0}}_touchEventToSignatureEvent(t){const e=t.changedTouches[0];return{event:t,type:t.type,x:e.clientX,y:e.clientY,pressure:e.force}}_getPointGroupOptions(t){return{penColor:t&&"penColor"in t?t.penColor:this.penColor,dotSize:t&&"dotSize"in t?t.dotSize:this.dotSize,minWidth:t&&"minWidth"in t?t.minWidth:this.minWidth,maxWidth:t&&"maxWidth"in t?t.maxWidth:this.maxWidth,velocityFilterWeight:t&&"velocityFilterWeight"in t?t.velocityFilterWeight:this.velocityFilterWeight,compositeOperation:t&&"compositeOperation"in t?t.compositeOperation:this.compositeOperation}}_strokeBegin(t){if(!this.dispatchEvent(new CustomEvent("beginStroke",{detail:t,cancelable:!0})))return;const{addEventListener:e}=this._getListenerFunctions();switch(t.event.type){case"mousedown":e("mousemove",this._handleMouseMove),e("mouseup",this._handleMouseUp);break;case"touchstart":e("touchmove",this._handleTouchMove),e("touchend",this._handleTouchEnd);break;case"pointerdown":e("pointermove",this._handlePointerMove),e("pointerup",this._handlePointerUp)}this._drawingStroke=!0;const i=this._getPointGroupOptions(),n=Object.assign(Object.assign({},i),{points:[]});this._data.push(n),this._reset(i),this._strokeUpdate(t)}_strokeUpdate(t){if(!this._drawingStroke)return;if(0===this._data.length)return void this._strokeBegin(t);this.dispatchEvent(new CustomEvent("beforeUpdateStroke",{detail:t}));const e=this._createPoint(t.x,t.y,t.pressure),i=this._data[this._data.length-1],n=i.points,s=n.length>0&&n[n.length-1],o=!!s&&e.distanceTo(s)<=this.minDistance,r=this._getPointGroupOptions(i);if(!s||!s||!o){const t=this._addPoint(e,r);s?t&&this._drawCurve(t,r):this._drawDot(e,r),n.push({time:e.time,x:e.x,y:e.y,pressure:e.pressure})}this.dispatchEvent(new CustomEvent("afterUpdateStroke",{detail:t}))}_strokeEnd(t,e=!0){this._removeMoveUpEventListeners(),this._drawingStroke&&(e&&this._strokeUpdate(t),this._drawingStroke=!1,this.dispatchEvent(new CustomEvent("endStroke",{detail:t})))}_handlePointerEvents(){this._drawingStroke=!1,this.canvas.addEventListener("pointerdown",this._handlePointerDown)}_handleMouseEvents(){this._drawingStroke=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown)}_handleTouchEvents(){this.canvas.addEventListener("touchstart",this._handleTouchStart)}_reset(t){this._lastPoints=[],this._lastVelocity=0,this._lastWidth=(t.minWidth+t.maxWidth)/2,this._ctx.fillStyle=t.penColor,this._ctx.globalCompositeOperation=t.compositeOperation}_createPoint(e,i,n){const s=this.canvas.getBoundingClientRect();return new t(e-s.left,i-s.top,n,(new Date).getTime())}_addPoint(t,i){const{_lastPoints:n}=this;if(n.push(t),n.length>2){3===n.length&&n.unshift(n[0]);const t=this._calculateCurveWidths(n[1],n[2],i),s=e.fromPoints(n,t);return n.shift(),s}return null}_calculateCurveWidths(t,e,i){const n=i.velocityFilterWeight*e.velocityFrom(t)+(1-i.velocityFilterWeight)*this._lastVelocity,s=this._strokeWidth(n,i),o={end:s,start:this._lastWidth};return this._lastVelocity=n,this._lastWidth=s,o}_strokeWidth(t,e){return Math.max(e.maxWidth/(t+1),e.minWidth)}_drawCurveSegment(t,e,i){const n=this._ctx;n.moveTo(t,e),n.arc(t,e,i,0,2*Math.PI,!1),this._isEmpty=!1}_drawCurve(t,e){const i=this._ctx,n=t.endWidth-t.startWidth,s=2*Math.ceil(t.length());i.beginPath(),i.fillStyle=e.penColor;for(let i=0;i<s;i+=1){const o=i/s,r=o*o,h=r*o,a=1-o,c=a*a,d=c*a;let l=d*t.startPoint.x;l+=3*c*o*t.control1.x,l+=3*a*r*t.control2.x,l+=h*t.endPoint.x;let u=d*t.startPoint.y;u+=3*c*o*t.control1.y,u+=3*a*r*t.control2.y,u+=h*t.endPoint.y;const v=Math.min(t.startWidth+h*n,e.maxWidth);this._drawCurveSegment(l,u,v)}i.closePath(),i.fill()}_drawDot(t,e){const i=this._ctx,n=e.dotSize>0?e.dotSize:(e.minWidth+e.maxWidth)/2;i.beginPath(),this._drawCurveSegment(t.x,t.y,n),i.closePath(),i.fillStyle=e.penColor,i.fill()}_fromData(e,i,n){for(const s of e){const{points:e}=s,o=this._getPointGroupOptions(s);if(e.length>1)for(let n=0;n<e.length;n+=1){const s=e[n],r=new t(s.x,s.y,s.pressure,s.time);0===n&&this._reset(o);const h=this._addPoint(r,o);h&&i(h,o)}else this._reset(o),n(e[0],o)}}toSVG({includeBackgroundColor:t=!1}={}){const e=this._data,i=Math.max(window.devicePixelRatio||1,1),n=this.canvas.width/i,s=this.canvas.height/i,o=document.createElementNS("http://www.w3.org/2000/svg","svg");if(o.setAttribute("xmlns","http://www.w3.org/2000/svg"),o.setAttribute("xmlns:xlink","http://www.w3.org/1999/xlink"),o.setAttribute("viewBox",`0 0 ${n} ${s}`),o.setAttribute("width",n.toString()),o.setAttribute("height",s.toString()),t&&this.backgroundColor){const t=document.createElement("rect");t.setAttribute("width","100%"),t.setAttribute("height","100%"),t.setAttribute("fill",this.backgroundColor),o.appendChild(t)}return this._fromData(e,((t,{penColor:e})=>{const i=document.createElement("path");if(!(isNaN(t.control1.x)||isNaN(t.control1.y)||isNaN(t.control2.x)||isNaN(t.control2.y))){const n=`M ${t.startPoint.x.toFixed(3)},${t.startPoint.y.toFixed(3)} C ${t.control1.x.toFixed(3)},${t.control1.y.toFixed(3)} ${t.control2.x.toFixed(3)},${t.control2.y.toFixed(3)} ${t.endPoint.x.toFixed(3)},${t.endPoint.y.toFixed(3)}`;i.setAttribute("d",n),i.setAttribute("stroke-width",(2.25*t.endWidth).toFixed(3)),i.setAttribute("stroke",e),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),o.appendChild(i)}}),((t,{penColor:e,dotSize:i,minWidth:n,maxWidth:s})=>{const r=document.createElement("circle"),h=i>0?i:(n+s)/2;r.setAttribute("r",h.toString()),r.setAttribute("cx",t.x.toString()),r.setAttribute("cy",t.y.toString()),r.setAttribute("fill",e),o.appendChild(r)})),o.outerHTML}}return n})); | ||
//# sourceMappingURL=signature_pad.umd.min.js.map |
@@ -18,3 +18,9 @@ /** | ||
} | ||
export type SignatureEvent = MouseEvent | Touch | PointerEvent; | ||
export interface SignatureEvent { | ||
event: MouseEvent | TouchEvent | PointerEvent; | ||
type: string; | ||
x: number; | ||
y: number; | ||
pressure: number; | ||
} | ||
export interface FromDataOptions { | ||
@@ -81,5 +87,10 @@ clear?: boolean; | ||
off(): void; | ||
private _getListenerFunctions; | ||
private _removeMoveUpEventListeners; | ||
isEmpty(): boolean; | ||
fromData(pointGroups: PointGroup[], { clear }?: FromDataOptions): void; | ||
toData(): PointGroup[]; | ||
_isLeftButtonPressed(event: MouseEvent, only?: boolean): boolean; | ||
private _pointerEventToSignatureEvent; | ||
private _touchEventToSignatureEvent; | ||
private _handleMouseDown; | ||
@@ -91,5 +102,5 @@ private _handleMouseMove; | ||
private _handleTouchEnd; | ||
private _handlePointerStart; | ||
private _handlePointerDown; | ||
private _handlePointerMove; | ||
private _handlePointerEnd; | ||
private _handlePointerUp; | ||
private _getPointGroupOptions; | ||
@@ -96,0 +107,0 @@ private _strokeBegin; |
const wrapper = document.getElementById("signature-pad"); | ||
const canvasWrapper = document.getElementById("canvas-wrapper"); | ||
const clearButton = wrapper.querySelector("[data-action=clear]"); | ||
@@ -7,2 +8,3 @@ const changeBackgroundColorButton = wrapper.querySelector("[data-action=change-background-color]"); | ||
const undoButton = wrapper.querySelector("[data-action=undo]"); | ||
const redoButton = wrapper.querySelector("[data-action=redo]"); | ||
const savePNGButton = wrapper.querySelector("[data-action=save-png]"); | ||
@@ -12,2 +14,4 @@ const saveJPGButton = wrapper.querySelector("[data-action=save-jpg]"); | ||
const saveSVGWithBackgroundButton = wrapper.querySelector("[data-action=save-svg-with-background]"); | ||
const openInWindowButton = wrapper.querySelector("[data-action=open-in-window]"); | ||
let undoData = []; | ||
const canvas = wrapper.querySelector("canvas"); | ||
@@ -27,3 +31,3 @@ const signaturePad = new SignaturePad(canvas, { | ||
// and only part of the canvas is cleared then. | ||
const ratio = Math.max(window.devicePixelRatio || 1, 1); | ||
const ratio = Math.max(window.devicePixelRatio || 1, 1); | ||
@@ -41,3 +45,3 @@ // This part causes the canvas to be cleared | ||
//signaturePad.clear(); | ||
// If you want to keep the drawing on resize instead of clearing it you can reset the data. | ||
@@ -52,2 +56,13 @@ signaturePad.fromData(signaturePad.toData()); | ||
window.addEventListener("keydown", (event) => { | ||
switch (true) { | ||
case event.key === "z" && event.ctrlKey: | ||
undoButton.click(); | ||
break; | ||
case event.key === "y" && event.ctrlKey: | ||
redoButton.click(); | ||
break; | ||
} | ||
}); | ||
function download(dataURL, filename) { | ||
@@ -85,2 +100,7 @@ const blob = dataURLToBlob(dataURL); | ||
signaturePad.addEventListener("endStroke", () => { | ||
// clear undoData when new data is added | ||
undoData = []; | ||
}); | ||
clearButton.addEventListener("click", () => { | ||
@@ -93,4 +113,6 @@ signaturePad.clear(); | ||
if (data) { | ||
data.pop(); // remove the last dot or line | ||
if (data && data.length > 0) { | ||
// remove the last dot or line | ||
const removed = data.pop(); | ||
undoData.push(removed); | ||
signaturePad.fromData(data); | ||
@@ -100,2 +122,10 @@ } | ||
redoButton.addEventListener("click", () => { | ||
if (undoData.length > 0) { | ||
const data = signaturePad.toData(); | ||
data.push(undoData.pop()); | ||
signaturePad.fromData(data); | ||
} | ||
}); | ||
changeBackgroundColorButton.addEventListener("click", () => { | ||
@@ -105,3 +135,3 @@ const r = Math.round(Math.random() * 255); | ||
const b = Math.round(Math.random() * 255); | ||
const color = "rgb(" + r + "," + g + "," + b +")"; | ||
const color = "rgb(" + r + "," + g + "," + b + ")"; | ||
@@ -118,3 +148,3 @@ signaturePad.backgroundColor = color; | ||
const b = Math.round(Math.random() * 255); | ||
const color = "rgb(" + r + "," + g + "," + b +")"; | ||
const color = "rgb(" + r + "," + g + "," + b + ")"; | ||
@@ -163,5 +193,22 @@ signaturePad.penColor = color; | ||
} else { | ||
const dataURL = signaturePad.toDataURL('image/svg+xml', {includeBackgroundColor: true}); | ||
const dataURL = signaturePad.toDataURL('image/svg+xml', { includeBackgroundColor: true }); | ||
download(dataURL, "signature.svg"); | ||
} | ||
}); | ||
openInWindowButton.addEventListener("click", () => { | ||
var externalWin = window.open('', '', `width=${canvas.width / window.devicePixelRatio},height=${canvas.height / window.devicePixelRatio}`); | ||
canvas.style.width = "100%"; | ||
canvas.style.height = "100%"; | ||
externalWin.onresize = resizeCanvas; | ||
externalWin.document.body.style.margin = '0'; | ||
externalWin.document.body.appendChild(canvas); | ||
canvasWrapper.classList.add("empty"); | ||
externalWin.onbeforeunload = () => { | ||
canvas.style.width = ""; | ||
canvas.style.height = ""; | ||
canvasWrapper.classList.remove("empty"); | ||
canvasWrapper.appendChild(canvas); | ||
resizeCanvas(); | ||
}; | ||
}) |
{ | ||
"name": "signature_pad", | ||
"description": "Library for drawing smooth signatures.", | ||
"version": "4.2.0", | ||
"version": "5.0.0-beta.1", | ||
"homepage": "https://github.com/szimek/signature_pad", | ||
@@ -26,3 +26,3 @@ "author": { | ||
"test": "jest --coverage", | ||
"update-docs": "yarn run cp-cli dist/signature_pad.umd.js docs/js/signature_pad.umd.js", | ||
"update-docs": "yarn run cpy 'dist/signature_pad.umd.min.*' docs/js", | ||
"prepare": "husky install" | ||
@@ -40,31 +40,31 @@ }, | ||
"devDependencies": { | ||
"@rollup/plugin-typescript": "^11.1.5", | ||
"@rollup/plugin-typescript": "^11.1.6", | ||
"@semantic-release/changelog": "^6.0.3", | ||
"@semantic-release/commit-analyzer": "^11.1.0", | ||
"@semantic-release/commit-analyzer": "^12.0.0", | ||
"@semantic-release/git": "^10.0.1", | ||
"@semantic-release/github": "^9.2.3", | ||
"@semantic-release/npm": "^11.0.1", | ||
"@semantic-release/release-notes-generator": "^12.1.0", | ||
"@types/jest": "^29.5.8", | ||
"@types/node": "^20.9.0", | ||
"@typescript-eslint/eslint-plugin": "^6.11.0", | ||
"@typescript-eslint/parser": "^6.11.0", | ||
"cp-cli": "^2.0.0", | ||
"@semantic-release/github": "^10.0.2", | ||
"@semantic-release/npm": "^12.0.0", | ||
"@semantic-release/release-notes-generator": "^13.0.0", | ||
"@types/jest": "^29.5.12", | ||
"@types/node": "^20.12.3", | ||
"@typescript-eslint/eslint-plugin": "^7.5.0", | ||
"@typescript-eslint/parser": "^7.5.0", | ||
"cpy-cli": "^5.0.0", | ||
"del": "^7.1.0", | ||
"del-cli": "^5.1.0", | ||
"eslint": "^8.53.0", | ||
"eslint-config-prettier": "^9.0.0", | ||
"husky": "^8.0.3", | ||
"eslint": "^8.57.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"husky": "^9.0.11", | ||
"jest": "^29.7.0", | ||
"jest-canvas-mock": "^2.5.2", | ||
"jest-environment-jsdom": "^29.7.0", | ||
"lint-staged": "^15.1.0", | ||
"prettier": "^3.1.0", | ||
"rollup": "^4.4.1", | ||
"lint-staged": "^15.2.2", | ||
"prettier": "^3.2.5", | ||
"rollup": "^4.14.0", | ||
"rollup-plugin-terser": "^7.0.2", | ||
"semantic-release": "^22.0.7", | ||
"semantic-release": "^23.0.6", | ||
"serve": "^14.2.1", | ||
"ts-jest": "^29.1.1", | ||
"ts-jest": "^29.1.2", | ||
"tslib": "^2.6.2", | ||
"typescript": "~5.2.2" | ||
"typescript": "~5.4.3" | ||
}, | ||
@@ -104,3 +104,3 @@ "lint-staged": { | ||
}, | ||
"packageManager": "yarn@3.2.1" | ||
"packageManager": "yarn@4.1.1" | ||
} |
@@ -23,3 +23,9 @@ /** | ||
export type SignatureEvent = MouseEvent | Touch | PointerEvent; | ||
export interface SignatureEvent { | ||
event: MouseEvent | TouchEvent | PointerEvent; | ||
type: string; | ||
x: number; | ||
y: number; | ||
pressure: number; | ||
} | ||
@@ -92,3 +98,3 @@ export interface FromDataOptions { | ||
this.maxWidth = options.maxWidth || 2.5; | ||
this.throttle = ('throttle' in options ? options.throttle : 16) as number; // in milisecondss | ||
this.throttle = ('throttle' in options ? options.throttle : 16) as number; // in milliseconds | ||
this.minDistance = ( | ||
@@ -200,4 +206,6 @@ 'minDistance' in options ? options.minDistance : 5 | ||
// The "Scribble" feature of iOS intercepts point events. So that we can lose some of them when tapping rapidly. | ||
// Use touch events for iOS platforms to prevent it. See https://developer.apple.com/forums/thread/664108 for more information. | ||
// The "Scribble" feature of iOS intercepts point events. So that we can | ||
// lose some of them when tapping rapidly. Use touch events for iOS | ||
// platforms to prevent it. See | ||
// https://developer.apple.com/forums/thread/664108 for more information. | ||
if (window.PointerEvent && !isIOS) { | ||
@@ -220,21 +228,37 @@ this._handlePointerEvents(); | ||
this.canvas.removeEventListener('pointerdown', this._handlePointerStart); | ||
this.canvas.removeEventListener('pointermove', this._handlePointerMove); | ||
this.canvas.ownerDocument.removeEventListener( | ||
'pointerup', | ||
this._handlePointerEnd, | ||
); | ||
this.canvas.removeEventListener('pointerdown', this._handlePointerDown); | ||
this.canvas.removeEventListener('mousedown', this._handleMouseDown); | ||
this.canvas.removeEventListener('mousemove', this._handleMouseMove); | ||
this.canvas.ownerDocument.removeEventListener( | ||
'mouseup', | ||
this._handleMouseUp, | ||
); | ||
this.canvas.removeEventListener('touchstart', this._handleTouchStart); | ||
this.canvas.removeEventListener('touchstart', this._handleTouchStart); | ||
this.canvas.removeEventListener('touchmove', this._handleTouchMove); | ||
this.canvas.removeEventListener('touchend', this._handleTouchEnd); | ||
this._removeMoveUpEventListeners(); | ||
} | ||
private _getListenerFunctions() { | ||
const canvasWindow = | ||
window.document === this.canvas.ownerDocument | ||
? window | ||
: this.canvas.ownerDocument.defaultView ?? this.canvas.ownerDocument; | ||
return { | ||
addEventListener: canvasWindow.addEventListener.bind( | ||
canvasWindow, | ||
) as typeof window.addEventListener, | ||
removeEventListener: canvasWindow.removeEventListener.bind( | ||
canvasWindow, | ||
) as typeof window.removeEventListener, | ||
}; | ||
} | ||
private _removeMoveUpEventListeners(): void { | ||
const { removeEventListener } = this._getListenerFunctions(); | ||
removeEventListener('pointermove', this._handlePointerMove); | ||
removeEventListener('pointerup', this._handlePointerUp); | ||
removeEventListener('mousemove', this._handleMouseMove); | ||
removeEventListener('mouseup', this._handleMouseUp); | ||
removeEventListener('touchmove', this._handleTouchMove); | ||
removeEventListener('touchend', this._handleTouchEnd); | ||
} | ||
public isEmpty(): boolean { | ||
@@ -265,20 +289,63 @@ return this._isEmpty; | ||
public _isLeftButtonPressed(event: MouseEvent, only?: boolean): boolean { | ||
if (only) { | ||
return event.buttons === 1; | ||
} | ||
return (event.buttons & 1) === 1; | ||
} | ||
private _pointerEventToSignatureEvent( | ||
event: MouseEvent | PointerEvent, | ||
): SignatureEvent { | ||
return { | ||
event: event, | ||
type: event.type, | ||
x: event.clientX, | ||
y: event.clientY, | ||
pressure: 'pressure' in event ? event.pressure : 0, | ||
}; | ||
} | ||
private _touchEventToSignatureEvent(event: TouchEvent): SignatureEvent { | ||
const touch = event.changedTouches[0]; | ||
return { | ||
event: event, | ||
type: event.type, | ||
x: touch.clientX, | ||
y: touch.clientY, | ||
pressure: touch.force, | ||
}; | ||
} | ||
// Event handlers | ||
private _handleMouseDown = (event: MouseEvent): void => { | ||
if (event.buttons === 1) { | ||
this._strokeBegin(event); | ||
if (!this._isLeftButtonPressed(event, true) || this._drawingStroke) { | ||
return; | ||
} | ||
this._strokeBegin(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
private _handleMouseMove = (event: MouseEvent): void => { | ||
this._strokeMoveUpdate(event); | ||
if (!this._isLeftButtonPressed(event, true) || !this._drawingStroke) { | ||
// Stop when not pressing primary button or pressing multiple buttons | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event), false); | ||
return; | ||
} | ||
this._strokeMoveUpdate(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
private _handleMouseUp = (event: MouseEvent): void => { | ||
if (event.buttons === 1) { | ||
this._strokeEnd(event); | ||
if (this._isLeftButtonPressed(event)) { | ||
return; | ||
} | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
private _handleTouchStart = (event: TouchEvent): void => { | ||
if (event.targetTouches.length !== 1 || this._drawingStroke) { | ||
return; | ||
} | ||
// Prevent scrolling. | ||
@@ -289,9 +356,10 @@ if (event.cancelable) { | ||
if (event.targetTouches.length === 1) { | ||
const touch = event.changedTouches[0]; | ||
this._strokeBegin(touch); | ||
} | ||
this._strokeBegin(this._touchEventToSignatureEvent(event)); | ||
}; | ||
private _handleTouchMove = (event: TouchEvent): void => { | ||
if (event.targetTouches.length !== 1) { | ||
return; | ||
} | ||
// Prevent scrolling. | ||
@@ -302,31 +370,52 @@ if (event.cancelable) { | ||
const touch = event.targetTouches[0]; | ||
this._strokeMoveUpdate(touch); | ||
if (!this._drawingStroke) { | ||
this._strokeEnd(this._touchEventToSignatureEvent(event), false); | ||
return; | ||
} | ||
this._strokeMoveUpdate(this._touchEventToSignatureEvent(event)); | ||
}; | ||
private _handleTouchEnd = (event: TouchEvent): void => { | ||
const wasCanvasTouched = event.target === this.canvas; | ||
if (wasCanvasTouched) { | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
const touch = event.changedTouches[0]; | ||
this._strokeEnd(touch); | ||
if (event.targetTouches.length !== 0) { | ||
return; | ||
} | ||
if (event.cancelable) { | ||
event.preventDefault(); | ||
} | ||
this.canvas.removeEventListener('touchmove', this._handleTouchMove); | ||
this._strokeEnd(this._touchEventToSignatureEvent(event)); | ||
}; | ||
private _handlePointerStart = (event: PointerEvent): void => { | ||
private _handlePointerDown = (event: PointerEvent): void => { | ||
if (!this._isLeftButtonPressed(event) || this._drawingStroke) { | ||
return; | ||
} | ||
event.preventDefault(); | ||
this._strokeBegin(event); | ||
this._strokeBegin(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
private _handlePointerMove = (event: PointerEvent): void => { | ||
this._strokeMoveUpdate(event); | ||
if (!this._isLeftButtonPressed(event, true) || !this._drawingStroke) { | ||
// Stop when primary button not pressed or multiple buttons pressed | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event), false); | ||
return; | ||
} | ||
event.preventDefault(); | ||
this._strokeMoveUpdate(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
private _handlePointerEnd = (event: PointerEvent): void => { | ||
if (this._drawingStroke) { | ||
event.preventDefault(); | ||
this._strokeEnd(event); | ||
private _handlePointerUp = (event: PointerEvent): void => { | ||
if (this._isLeftButtonPressed(event)) { | ||
return; | ||
} | ||
event.preventDefault(); | ||
this._strokeEnd(this._pointerEventToSignatureEvent(event)); | ||
}; | ||
@@ -359,2 +448,21 @@ | ||
} | ||
const { addEventListener } = this._getListenerFunctions(); | ||
switch (event.event.type) { | ||
case 'mousedown': | ||
addEventListener('mousemove', this._handleMouseMove); | ||
addEventListener('mouseup', this._handleMouseUp); | ||
break; | ||
case 'touchstart': | ||
addEventListener('touchmove', this._handleTouchMove); | ||
addEventListener('touchend', this._handleTouchEnd); | ||
break; | ||
case 'pointerdown': | ||
addEventListener('pointermove', this._handlePointerMove); | ||
addEventListener('pointerup', this._handlePointerUp); | ||
break; | ||
default: | ||
// do nothing | ||
} | ||
this._drawingStroke = true; | ||
@@ -390,12 +498,3 @@ | ||
const x = event.clientX; | ||
const y = event.clientY; | ||
const pressure = | ||
(event as PointerEvent).pressure !== undefined | ||
? (event as PointerEvent).pressure | ||
: (event as Touch).force !== undefined | ||
? (event as Touch).force | ||
: 0; | ||
const point = this._createPoint(x, y, pressure); | ||
const point = this._createPoint(event.x, event.y, event.pressure); | ||
const lastPointGroup = this._data[this._data.length - 1]; | ||
@@ -431,3 +530,5 @@ const lastPoints = lastPointGroup.points; | ||
private _strokeEnd(event: SignatureEvent): void { | ||
private _strokeEnd(event: SignatureEvent, shouldUpdate = true): void { | ||
this._removeMoveUpEventListeners(); | ||
if (!this._drawingStroke) { | ||
@@ -437,3 +538,5 @@ return; | ||
this._strokeUpdate(event); | ||
if (shouldUpdate) { | ||
this._strokeUpdate(event); | ||
} | ||
@@ -447,8 +550,3 @@ this._drawingStroke = false; | ||
this.canvas.addEventListener('pointerdown', this._handlePointerStart); | ||
this.canvas.addEventListener('pointermove', this._handlePointerMove); | ||
this.canvas.ownerDocument.addEventListener( | ||
'pointerup', | ||
this._handlePointerEnd, | ||
); | ||
this.canvas.addEventListener('pointerdown', this._handlePointerDown); | ||
} | ||
@@ -460,4 +558,2 @@ | ||
this.canvas.addEventListener('mousedown', this._handleMouseDown); | ||
this.canvas.addEventListener('mousemove', this._handleMouseMove); | ||
this.canvas.ownerDocument.addEventListener('mouseup', this._handleMouseUp); | ||
} | ||
@@ -467,4 +563,2 @@ | ||
this.canvas.addEventListener('touchstart', this._handleTouchStart); | ||
this.canvas.addEventListener('touchmove', this._handleTouchMove); | ||
this.canvas.addEventListener('touchend', this._handleTouchEnd); | ||
} | ||
@@ -471,0 +565,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
422130
27
2829
1