signature_pad
Advanced tools
Comparing version 3.0.0-beta.1 to 3.0.0-beta.2
## Changelog | ||
### 3.0.0-beta.2 | ||
#### Bug fixes | ||
- Fix error in `touchend` event handler. | ||
- Make both params in `#toDataURL` optional to match `Canvas#toDataURL`. | ||
#### Features | ||
- Add optional callback param to `#fromDataURL`. | ||
- Add basic unit tests for SignaturePad class. | ||
### 3.0.0-beta.1 | ||
@@ -15,2 +24,3 @@ #### Breaking changes | ||
``` | ||
- Change structure of data returned from `SignaturePad#toData method. Each point group now has 2 fields: `color` and `points`. Individual points no longer have `color` field. | ||
@@ -17,0 +27,0 @@ #### Bug Fixes |
/*! | ||
* Signature Pad v3.0.0-beta.1 | https://github.com/szimek/signature_pad | ||
* Signature Pad v3.0.0-beta.2 | https://github.com/szimek/signature_pad | ||
* (c) 2018 Szymon Nowak | Released under the MIT license | ||
@@ -138,22 +138,2 @@ */ | ||
this.options = options; | ||
this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.minWidth = options.minWidth || 0.5; | ||
this.maxWidth = options.maxWidth || 2.5; | ||
this.throttle = ("throttle" in options ? options.throttle : 16); | ||
this.minDistance = ("minDistance" in options ? options.minDistance : 5); | ||
if (this.throttle) { | ||
this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle); | ||
} | ||
else { | ||
this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate; | ||
} | ||
this.dotSize = options.dotSize || function () { | ||
return (this.minWidth + this.maxWidth) / 2; | ||
}; | ||
this.penColor = options.penColor || "black"; | ||
this.backgroundColor = options.backgroundColor || "rgba(0,0,0,0)"; | ||
this.onBegin = options.onBegin; | ||
this.onEnd = options.onEnd; | ||
this._ctx = canvas.getContext("2d"); | ||
this.clear(); | ||
this._handleMouseDown = function (event) { | ||
@@ -192,6 +172,26 @@ if (event.which === 1) { | ||
event.preventDefault(); | ||
var touch = event.targetTouches[0]; | ||
var touch = event.changedTouches[0]; | ||
_this._strokeEnd(touch); | ||
} | ||
}; | ||
this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.minWidth = options.minWidth || 0.5; | ||
this.maxWidth = options.maxWidth || 2.5; | ||
this.throttle = ("throttle" in options ? options.throttle : 16); | ||
this.minDistance = ("minDistance" in options ? options.minDistance : 5); | ||
if (this.throttle) { | ||
this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle); | ||
} | ||
else { | ||
this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate; | ||
} | ||
this.dotSize = options.dotSize || function () { | ||
return (this.minWidth + this.maxWidth) / 2; | ||
}; | ||
this.penColor = options.penColor || "black"; | ||
this.backgroundColor = options.backgroundColor || "rgba(0,0,0,0)"; | ||
this.onBegin = options.onBegin; | ||
this.onEnd = options.onEnd; | ||
this._ctx = canvas.getContext("2d"); | ||
this.clear(); | ||
this.on(); | ||
@@ -209,3 +209,3 @@ } | ||
}; | ||
SignaturePad.prototype.fromDataURL = function (dataUrl, options) { | ||
SignaturePad.prototype.fromDataURL = function (dataUrl, options, callback) { | ||
var _this = this; | ||
@@ -218,9 +218,18 @@ if (options === void 0) { options = {}; } | ||
this._reset(); | ||
image.src = dataUrl; | ||
image.onload = function () { | ||
_this._ctx.drawImage(image, 0, 0, width, height); | ||
if (callback) { | ||
callback(); | ||
} | ||
}; | ||
image.onerror = function (error) { | ||
if (callback) { | ||
callback(error); | ||
} | ||
}; | ||
image.src = dataUrl; | ||
this._isEmpty = false; | ||
}; | ||
SignaturePad.prototype.toDataURL = function (type, encoderOptions) { | ||
if (type === void 0) { type = "image/png"; } | ||
switch (type) { | ||
@@ -235,3 +244,5 @@ case "image/svg+xml": | ||
this._handleMouseEvents(); | ||
this._handleTouchEvents(); | ||
if ("ontouchstart" in window) { | ||
this._handleTouchEvents(); | ||
} | ||
}; | ||
@@ -238,0 +249,0 @@ SignaturePad.prototype.off = function () { |
/*! | ||
* Signature Pad v3.0.0-beta.1 | https://github.com/szimek/signature_pad | ||
* Signature Pad v3.0.0-beta.2 | https://github.com/szimek/signature_pad | ||
* (c) 2018 Szymon Nowak | Released under the MIT license | ||
@@ -127,22 +127,2 @@ */ | ||
this.options = options; | ||
this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.minWidth = options.minWidth || 0.5; | ||
this.maxWidth = options.maxWidth || 2.5; | ||
this.throttle = ("throttle" in options ? options.throttle : 16); | ||
this.minDistance = ("minDistance" in options ? options.minDistance : 5); | ||
if (this.throttle) { | ||
this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle); | ||
} | ||
else { | ||
this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate; | ||
} | ||
this.dotSize = options.dotSize || function () { | ||
return (this.minWidth + this.maxWidth) / 2; | ||
}; | ||
this.penColor = options.penColor || "black"; | ||
this.backgroundColor = options.backgroundColor || "rgba(0,0,0,0)"; | ||
this.onBegin = options.onBegin; | ||
this.onEnd = options.onEnd; | ||
this._ctx = canvas.getContext("2d"); | ||
this.clear(); | ||
this._handleMouseDown = (event) => { | ||
@@ -181,6 +161,26 @@ if (event.which === 1) { | ||
event.preventDefault(); | ||
const touch = event.targetTouches[0]; | ||
const touch = event.changedTouches[0]; | ||
this._strokeEnd(touch); | ||
} | ||
}; | ||
this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.minWidth = options.minWidth || 0.5; | ||
this.maxWidth = options.maxWidth || 2.5; | ||
this.throttle = ("throttle" in options ? options.throttle : 16); | ||
this.minDistance = ("minDistance" in options ? options.minDistance : 5); | ||
if (this.throttle) { | ||
this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle); | ||
} | ||
else { | ||
this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate; | ||
} | ||
this.dotSize = options.dotSize || function () { | ||
return (this.minWidth + this.maxWidth) / 2; | ||
}; | ||
this.penColor = options.penColor || "black"; | ||
this.backgroundColor = options.backgroundColor || "rgba(0,0,0,0)"; | ||
this.onBegin = options.onBegin; | ||
this.onEnd = options.onEnd; | ||
this._ctx = canvas.getContext("2d"); | ||
this.clear(); | ||
this.on(); | ||
@@ -198,3 +198,3 @@ } | ||
} | ||
fromDataURL(dataUrl, options = {}) { | ||
fromDataURL(dataUrl, options = {}, callback) { | ||
const image = new Image(); | ||
@@ -205,9 +205,17 @@ const ratio = options.ratio || window.devicePixelRatio || 1; | ||
this._reset(); | ||
image.src = dataUrl; | ||
image.onload = () => { | ||
this._ctx.drawImage(image, 0, 0, width, height); | ||
if (callback) { | ||
callback(); | ||
} | ||
}; | ||
image.onerror = (error) => { | ||
if (callback) { | ||
callback(error); | ||
} | ||
}; | ||
image.src = dataUrl; | ||
this._isEmpty = false; | ||
} | ||
toDataURL(type, encoderOptions) { | ||
toDataURL(type = "image/png", encoderOptions) { | ||
switch (type) { | ||
@@ -222,3 +230,5 @@ case "image/svg+xml": | ||
this._handleMouseEvents(); | ||
this._handleTouchEvents(); | ||
if ("ontouchstart" in window) { | ||
this._handleTouchEvents(); | ||
} | ||
} | ||
@@ -225,0 +235,0 @@ off() { |
@@ -1,1 +0,1 @@ | ||
class Point{constructor(t,e,i){this.x=t,this.y=e,this.time=i||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.time===t.time}velocityFrom(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0}}class Bezier{constructor(t,e,i,o,s,n){this.startPoint=t,this.control2=e,this.control1=i,this.endPoint=o,this.startWidth=s,this.endWidth=n}static fromPoints(t,e){const i=this.calculateControlPoints(t[0],t[1],t[2]).c2,o=this.calculateControlPoints(t[1],t[2],t[3]).c1;return new Bezier(t[1],i,o,t[2],e.start,e.end)}static calculateControlPoints(t,e,i){const o=t.x-e.x,s=t.y-e.y,n=e.x-i.x,h=e.y-i.y,r=(t.x+e.x)/2,a=(t.y+e.y)/2,c=(e.x+i.x)/2,l=(e.y+i.y)/2,d=Math.sqrt(o*o+s*s),u=Math.sqrt(n*n+h*h),_=u/(d+u),v=c+(r-c)*_,m=l+(a-l)*_,p=e.x-v,g=e.y-m;return{c1:new Point(r+p,a+g),c2:new Point(c+p,l+g)}}length(){let t,e,i=0;for(let o=0;o<=10;o+=1){const s=o/10,n=this.point(s,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),h=this.point(s,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(o>0){const o=n-t,s=h-e;i+=Math.sqrt(o*o+s*s)}t=n,e=h}return i}point(t,e,i,o,s){return e*(1-t)*(1-t)*(1-t)+3*i*(1-t)*(1-t)*t+3*o*(1-t)*t*t+s*t*t*t}}function throttle(t,e=250){let i,o,s,n=0,h=null;const r=()=>{n=Date.now(),h=null,i=t.apply(o,s),h||(o=null,s=[])};return function(...a){const c=Date.now(),l=e-(c-n);return o=this,s=a,l<=0||l>e?(h&&(clearTimeout(h),h=null),n=c,i=t.apply(o,s),h||(o=null,s=[])):h||(h=setTimeout(r,l)),i}}class SignaturePad{constructor(t,e={}){this.canvas=t,this.options=e,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.throttle?this._strokeMoveUpdate=throttle(SignaturePad.prototype._strokeUpdate,this.throttle):this._strokeMoveUpdate=SignaturePad.prototype._strokeUpdate,this.dotSize=e.dotSize||function(){return(this.minWidth+this.maxWidth)/2},this.penColor=e.penColor||"black",this.backgroundColor=e.backgroundColor||"rgba(0,0,0,0)",this.onBegin=e.onBegin,this.onEnd=e.onEnd,this._ctx=t.getContext("2d"),this.clear(),this._handleMouseDown=(t=>{1===t.which&&(this._mouseButtonDown=!0,this._strokeBegin(t))}),this._handleMouseMove=(t=>{this._mouseButtonDown&&this._strokeMoveUpdate(t)}),this._handleMouseUp=(t=>{1===t.which&&this._mouseButtonDown&&(this._mouseButtonDown=!1,this._strokeEnd(t))}),this._handleTouchStart=(t=>{if(t.preventDefault(),1===t.targetTouches.length){const e=t.changedTouches[0];this._strokeBegin(e)}}),this._handleTouchMove=(t=>{t.preventDefault();const e=t.targetTouches[0];this._strokeMoveUpdate(e)}),this._handleTouchEnd=(t=>{if(t.target===this.canvas){t.preventDefault();const e=t.targetTouches[0];this._strokeEnd(e)}}),this.on()}clear(){const t=this._ctx,e=this.canvas;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._isEmpty=!0}fromDataURL(t,e={}){const i=new Image,o=e.ratio||window.devicePixelRatio||1,s=e.width||this.canvas.width/o,n=e.height||this.canvas.height/o;this._reset(),i.src=t,i.onload=(()=>{this._ctx.drawImage(i,0,0,s,n)}),this._isEmpty=!1}toDataURL(t,e){switch(t){case"image/svg+xml":return this._toSVG();default:return this.canvas.toDataURL(t,e)}}on(){this._handleMouseEvents(),this._handleTouchEvents()}off(){this.canvas.style.msTouchAction="auto",this.canvas.style.touchAction="auto",this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("mousemove",this._handleMouseMove),document.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){this.clear(),this._fromData(t,({color:t,curve:e})=>this._drawCurve({color:t,curve:e}),({color:t,point:e})=>this._drawDot({color:t,point:e})),this._data=t}toData(){return this._data}_strokeBegin(t){const e={color:this.penColor,points:[]};this._data.push(e),this._reset(),this._strokeUpdate(t),"function"==typeof this.onBegin&&this.onBegin(t)}_strokeUpdate(t){const e=t.clientX,i=t.clientY,o=this._createPoint(e,i),s=this._data[this._data.length-1],n=s.points,h=n.length>0&&n[n.length-1],r=!!h&&o.distanceTo(h)<=this.minDistance,a=s.color;if(!h||!h||!r){const t=this._addPoint(o);h?t&&this._drawCurve({color:a,curve:t}):this._drawDot({color:a,point:o}),n.push({time:o.time,x:o.x,y:o.y})}}_strokeEnd(t){this._strokeUpdate(t),"function"==typeof this.onEnd&&this.onEnd(t)}_handleMouseEvents(){this._mouseButtonDown=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown),this.canvas.addEventListener("mousemove",this._handleMouseMove),document.addEventListener("mouseup",this._handleMouseUp)}_handleTouchEvents(){this.canvas.style.msTouchAction="none",this.canvas.style.touchAction="none",this.canvas.addEventListener("touchstart",this._handleTouchStart),this.canvas.addEventListener("touchmove",this._handleTouchMove),this.canvas.addEventListener("touchend",this._handleTouchEnd)}_reset(){this._points=[],this._lastVelocity=0,this._lastWidth=(this.minWidth+this.maxWidth)/2,this._ctx.fillStyle=this.penColor}_createPoint(t,e){const i=this.canvas.getBoundingClientRect();return new Point(t-i.left,e-i.top,(new Date).getTime())}_addPoint(t){const{_points:e}=this;if(e.push(t),e.length>2){3===e.length&&e.unshift(e[0]);const t=this._calculateCurveWidths(e[1],e[2]),i=Bezier.fromPoints(e,t);return e.shift(),i}return null}_calculateCurveWidths(t,e){const i=this.velocityFilterWeight*e.velocityFrom(t)+(1-this.velocityFilterWeight)*this._lastVelocity,o=this._strokeWidth(i),s={end:o,start:this._lastWidth};return this._lastVelocity=i,this._lastWidth=o,s}_strokeWidth(t){return Math.max(this.maxWidth/(t+1),this.minWidth)}_drawCurveSegment(t,e,i){const o=this._ctx;o.moveTo(t,e),o.arc(t,e,i,0,2*Math.PI,!1),this._isEmpty=!1}_drawCurve({color:t,curve:e}){const i=this._ctx,o=e.endWidth-e.startWidth,s=2*Math.floor(e.length());i.beginPath(),i.fillStyle=t;for(let t=0;t<s;t+=1){const i=t/s,n=i*i,h=n*i,r=1-i,a=r*r,c=a*r;let l=c*e.startPoint.x;l+=3*a*i*e.control1.x,l+=3*r*n*e.control2.x,l+=h*e.endPoint.x;let d=c*e.startPoint.y;d+=3*a*i*e.control1.y,d+=3*r*n*e.control2.y,d+=h*e.endPoint.y;const u=e.startWidth+h*o;this._drawCurveSegment(l,d,u)}i.closePath(),i.fill()}_drawDot({color:t,point:e}){const i=this._ctx,o="function"==typeof this.dotSize?this.dotSize():this.dotSize;i.beginPath(),this._drawCurveSegment(e.x,e.y,o),i.closePath(),i.fillStyle=t,i.fill()}_fromData(t,e,i){for(const o of t){const{color:t,points:s}=o;if(s.length>1)for(let i=0;i<s.length;i+=1){const o=s[i],n=new Point(o.x,o.y,o.time);this.penColor=t,0===i&&this._reset();const h=this._addPoint(n);h&&e({color:t,curve:h})}else this._reset(),i({color:t,point:s[0]})}}_toSVG(){const t=this._data,e=Math.max(window.devicePixelRatio||1,1),i=this.canvas.width/e,o=this.canvas.height/e,s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width",this.canvas.width.toString()),s.setAttribute("height",this.canvas.height.toString()),this._fromData(t,({color:t,curve:e})=>{const i=document.createElement("path");if(!(isNaN(e.control1.x)||isNaN(e.control1.y)||isNaN(e.control2.x)||isNaN(e.control2.y))){const o=`M ${e.startPoint.x.toFixed(3)},${e.startPoint.y.toFixed(3)} `+`C ${e.control1.x.toFixed(3)},${e.control1.y.toFixed(3)} `+`${e.control2.x.toFixed(3)},${e.control2.y.toFixed(3)} `+`${e.endPoint.x.toFixed(3)},${e.endPoint.y.toFixed(3)}`;i.setAttribute("d",o),i.setAttribute("stroke-width",(2.25*e.endWidth).toFixed(3)),i.setAttribute("stroke",t),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),s.appendChild(i)}},({color:t,point:e})=>{const i=document.createElement("circle"),o="function"==typeof this.dotSize?this.dotSize():this.dotSize;i.setAttribute("r",o.toString()),i.setAttribute("cx",e.x.toString()),i.setAttribute("cy",e.y.toString()),i.setAttribute("fill",t),s.appendChild(i)});const n='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"'+` viewBox="0 0 ${i} ${o}"`+` width="${i}"`+` height="${o}"`+">";let h=s.innerHTML;if(void 0===h){const t=document.createElement("dummy"),e=s.childNodes;t.innerHTML="";for(let i=0;i<e.length;i+=1)t.appendChild(e[i].cloneNode(!0));h=t.innerHTML}return"data:image/svg+xml;base64,"+btoa(n+h+"</svg>")}}export default SignaturePad; | ||
class Point{constructor(t,e,i){this.x=t,this.y=e,this.time=i||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.time===t.time}velocityFrom(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0}}class Bezier{constructor(t,e,i,o,s,n){this.startPoint=t,this.control2=e,this.control1=i,this.endPoint=o,this.startWidth=s,this.endWidth=n}static fromPoints(t,e){const i=this.calculateControlPoints(t[0],t[1],t[2]).c2,o=this.calculateControlPoints(t[1],t[2],t[3]).c1;return new Bezier(t[1],i,o,t[2],e.start,e.end)}static calculateControlPoints(t,e,i){const o=t.x-e.x,s=t.y-e.y,n=e.x-i.x,h=e.y-i.y,r=(t.x+e.x)/2,a=(t.y+e.y)/2,c=(e.x+i.x)/2,l=(e.y+i.y)/2,d=Math.sqrt(o*o+s*s),u=Math.sqrt(n*n+h*h),_=u/(d+u),v=c+(r-c)*_,m=l+(a-l)*_,g=e.x-v,p=e.y-m;return{c1:new Point(r+g,a+p),c2:new Point(c+g,l+p)}}length(){let t,e,i=0;for(let o=0;o<=10;o+=1){const s=o/10,n=this.point(s,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),h=this.point(s,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(o>0){const o=n-t,s=h-e;i+=Math.sqrt(o*o+s*s)}t=n,e=h}return i}point(t,e,i,o,s){return e*(1-t)*(1-t)*(1-t)+3*i*(1-t)*(1-t)*t+3*o*(1-t)*t*t+s*t*t*t}}function throttle(t,e=250){let i,o,s,n=0,h=null;const r=()=>{n=Date.now(),h=null,i=t.apply(o,s),h||(o=null,s=[])};return function(...a){const c=Date.now(),l=e-(c-n);return o=this,s=a,l<=0||l>e?(h&&(clearTimeout(h),h=null),n=c,i=t.apply(o,s),h||(o=null,s=[])):h||(h=setTimeout(r,l)),i}}class SignaturePad{constructor(t,e={}){this.canvas=t,this.options=e,this._handleMouseDown=(t=>{1===t.which&&(this._mouseButtonDown=!0,this._strokeBegin(t))}),this._handleMouseMove=(t=>{this._mouseButtonDown&&this._strokeMoveUpdate(t)}),this._handleMouseUp=(t=>{1===t.which&&this._mouseButtonDown&&(this._mouseButtonDown=!1,this._strokeEnd(t))}),this._handleTouchStart=(t=>{if(t.preventDefault(),1===t.targetTouches.length){const e=t.changedTouches[0];this._strokeBegin(e)}}),this._handleTouchMove=(t=>{t.preventDefault();const e=t.targetTouches[0];this._strokeMoveUpdate(e)}),this._handleTouchEnd=(t=>{if(t.target===this.canvas){t.preventDefault();const e=t.changedTouches[0];this._strokeEnd(e)}}),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.throttle?this._strokeMoveUpdate=throttle(SignaturePad.prototype._strokeUpdate,this.throttle):this._strokeMoveUpdate=SignaturePad.prototype._strokeUpdate,this.dotSize=e.dotSize||function(){return(this.minWidth+this.maxWidth)/2},this.penColor=e.penColor||"black",this.backgroundColor=e.backgroundColor||"rgba(0,0,0,0)",this.onBegin=e.onBegin,this.onEnd=e.onEnd,this._ctx=t.getContext("2d"),this.clear(),this.on()}clear(){const t=this._ctx,e=this.canvas;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._isEmpty=!0}fromDataURL(t,e={},i){const o=new Image,s=e.ratio||window.devicePixelRatio||1,n=e.width||this.canvas.width/s,h=e.height||this.canvas.height/s;this._reset(),o.onload=(()=>{this._ctx.drawImage(o,0,0,n,h),i&&i()}),o.onerror=(t=>{i&&i(t)}),o.src=t,this._isEmpty=!1}toDataURL(t="image/png",e){switch(t){case"image/svg+xml":return this._toSVG();default:return this.canvas.toDataURL(t,e)}}on(){this._handleMouseEvents(),"ontouchstart"in window&&this._handleTouchEvents()}off(){this.canvas.style.msTouchAction="auto",this.canvas.style.touchAction="auto",this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("mousemove",this._handleMouseMove),document.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){this.clear(),this._fromData(t,({color:t,curve:e})=>this._drawCurve({color:t,curve:e}),({color:t,point:e})=>this._drawDot({color:t,point:e})),this._data=t}toData(){return this._data}_strokeBegin(t){const e={color:this.penColor,points:[]};this._data.push(e),this._reset(),this._strokeUpdate(t),"function"==typeof this.onBegin&&this.onBegin(t)}_strokeUpdate(t){const e=t.clientX,i=t.clientY,o=this._createPoint(e,i),s=this._data[this._data.length-1],n=s.points,h=n.length>0&&n[n.length-1],r=!!h&&o.distanceTo(h)<=this.minDistance,a=s.color;if(!h||!h||!r){const t=this._addPoint(o);h?t&&this._drawCurve({color:a,curve:t}):this._drawDot({color:a,point:o}),n.push({time:o.time,x:o.x,y:o.y})}}_strokeEnd(t){this._strokeUpdate(t),"function"==typeof this.onEnd&&this.onEnd(t)}_handleMouseEvents(){this._mouseButtonDown=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown),this.canvas.addEventListener("mousemove",this._handleMouseMove),document.addEventListener("mouseup",this._handleMouseUp)}_handleTouchEvents(){this.canvas.style.msTouchAction="none",this.canvas.style.touchAction="none",this.canvas.addEventListener("touchstart",this._handleTouchStart),this.canvas.addEventListener("touchmove",this._handleTouchMove),this.canvas.addEventListener("touchend",this._handleTouchEnd)}_reset(){this._points=[],this._lastVelocity=0,this._lastWidth=(this.minWidth+this.maxWidth)/2,this._ctx.fillStyle=this.penColor}_createPoint(t,e){const i=this.canvas.getBoundingClientRect();return new Point(t-i.left,e-i.top,(new Date).getTime())}_addPoint(t){const{_points:e}=this;if(e.push(t),e.length>2){3===e.length&&e.unshift(e[0]);const t=this._calculateCurveWidths(e[1],e[2]),i=Bezier.fromPoints(e,t);return e.shift(),i}return null}_calculateCurveWidths(t,e){const i=this.velocityFilterWeight*e.velocityFrom(t)+(1-this.velocityFilterWeight)*this._lastVelocity,o=this._strokeWidth(i),s={end:o,start:this._lastWidth};return this._lastVelocity=i,this._lastWidth=o,s}_strokeWidth(t){return Math.max(this.maxWidth/(t+1),this.minWidth)}_drawCurveSegment(t,e,i){const o=this._ctx;o.moveTo(t,e),o.arc(t,e,i,0,2*Math.PI,!1),this._isEmpty=!1}_drawCurve({color:t,curve:e}){const i=this._ctx,o=e.endWidth-e.startWidth,s=2*Math.floor(e.length());i.beginPath(),i.fillStyle=t;for(let t=0;t<s;t+=1){const i=t/s,n=i*i,h=n*i,r=1-i,a=r*r,c=a*r;let l=c*e.startPoint.x;l+=3*a*i*e.control1.x,l+=3*r*n*e.control2.x,l+=h*e.endPoint.x;let d=c*e.startPoint.y;d+=3*a*i*e.control1.y,d+=3*r*n*e.control2.y,d+=h*e.endPoint.y;const u=e.startWidth+h*o;this._drawCurveSegment(l,d,u)}i.closePath(),i.fill()}_drawDot({color:t,point:e}){const i=this._ctx,o="function"==typeof this.dotSize?this.dotSize():this.dotSize;i.beginPath(),this._drawCurveSegment(e.x,e.y,o),i.closePath(),i.fillStyle=t,i.fill()}_fromData(t,e,i){for(const o of t){const{color:t,points:s}=o;if(s.length>1)for(let i=0;i<s.length;i+=1){const o=s[i],n=new Point(o.x,o.y,o.time);this.penColor=t,0===i&&this._reset();const h=this._addPoint(n);h&&e({color:t,curve:h})}else this._reset(),i({color:t,point:s[0]})}}_toSVG(){const t=this._data,e=Math.max(window.devicePixelRatio||1,1),i=this.canvas.width/e,o=this.canvas.height/e,s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width",this.canvas.width.toString()),s.setAttribute("height",this.canvas.height.toString()),this._fromData(t,({color:t,curve:e})=>{const i=document.createElement("path");if(!(isNaN(e.control1.x)||isNaN(e.control1.y)||isNaN(e.control2.x)||isNaN(e.control2.y))){const o=`M ${e.startPoint.x.toFixed(3)},${e.startPoint.y.toFixed(3)} `+`C ${e.control1.x.toFixed(3)},${e.control1.y.toFixed(3)} `+`${e.control2.x.toFixed(3)},${e.control2.y.toFixed(3)} `+`${e.endPoint.x.toFixed(3)},${e.endPoint.y.toFixed(3)}`;i.setAttribute("d",o),i.setAttribute("stroke-width",(2.25*e.endWidth).toFixed(3)),i.setAttribute("stroke",t),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),s.appendChild(i)}},({color:t,point:e})=>{const i=document.createElement("circle"),o="function"==typeof this.dotSize?this.dotSize():this.dotSize;i.setAttribute("r",o.toString()),i.setAttribute("cx",e.x.toString()),i.setAttribute("cy",e.y.toString()),i.setAttribute("fill",t),s.appendChild(i)});const n='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"'+` viewBox="0 0 ${i} ${o}"`+` width="${i}"`+` height="${o}"`+">";let h=s.innerHTML;if(void 0===h){const t=document.createElement("dummy"),e=s.childNodes;t.innerHTML="";for(let i=0;i<e.length;i+=1)t.appendChild(e[i].cloneNode(!0));h=t.innerHTML}return"data:image/svg+xml;base64,"+btoa(n+h+"</svg>")}}export default SignaturePad; |
@@ -1,1 +0,1 @@ | ||
"use strict";var Point=function(){function t(t,e,o){this.x=t,this.y=e,this.time=o||Date.now()}return t.prototype.distanceTo=function(t){return Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))},t.prototype.equals=function(t){return this.x===t.x&&this.y===t.y&&this.time===t.time},t.prototype.velocityFrom=function(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0},t}(),Bezier=function(){function t(t,e,o,i,n,s){this.startPoint=t,this.control2=e,this.control1=o,this.endPoint=i,this.startWidth=n,this.endWidth=s}return t.fromPoints=function(e,o){var i=this.calculateControlPoints(e[0],e[1],e[2]).c2,n=this.calculateControlPoints(e[1],e[2],e[3]).c1;return new t(e[1],i,n,e[2],o.start,o.end)},t.calculateControlPoints=function(t,e,o){var i=t.x-e.x,n=t.y-e.y,s=e.x-o.x,r=e.y-o.y,h=(t.x+e.x)/2,a=(t.y+e.y)/2,c=(e.x+o.x)/2,u=(e.y+o.y)/2,l=Math.sqrt(i*i+n*n),d=Math.sqrt(s*s+r*r),v=d/(l+d),p=c+(h-c)*v,f=u+(a-u)*v,_=e.x-p,y=e.y-f;return{c1:new Point(h+_,a+y),c2:new Point(c+_,u+y)}},t.prototype.length=function(){for(var t,e,o=0,i=0;i<=10;i+=1){var n=i/10,s=this.point(n,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),r=this.point(n,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(i>0){var h=s-t,a=r-e;o+=Math.sqrt(h*h+a*a)}t=s,e=r}return o},t.prototype.point=function(t,e,o,i,n){return e*(1-t)*(1-t)*(1-t)+3*o*(1-t)*(1-t)*t+3*i*(1-t)*t*t+n*t*t*t},t}();function throttle(t,e){void 0===e&&(e=250);var o,i,n,s=0,r=null,h=function(){s=Date.now(),r=null,o=t.apply(i,n),r||(i=null,n=[])};return function(){for(var a=[],c=0;c<arguments.length;c++)a[c]=arguments[c];var u=Date.now(),l=e-(u-s);return i=this,n=a,l<=0||l>e?(r&&(clearTimeout(r),r=null),s=u,o=t.apply(i,n),r||(i=null,n=[])):r||(r=setTimeout(h,l)),o}}var SignaturePad=function(){function t(e,o){void 0===o&&(o={});var i=this;this.canvas=e,this.options=o,this.velocityFilterWeight=o.velocityFilterWeight||.7,this.minWidth=o.minWidth||.5,this.maxWidth=o.maxWidth||2.5,this.throttle="throttle"in o?o.throttle:16,this.minDistance="minDistance"in o?o.minDistance:5,this.throttle?this._strokeMoveUpdate=throttle(t.prototype._strokeUpdate,this.throttle):this._strokeMoveUpdate=t.prototype._strokeUpdate,this.dotSize=o.dotSize||function(){return(this.minWidth+this.maxWidth)/2},this.penColor=o.penColor||"black",this.backgroundColor=o.backgroundColor||"rgba(0,0,0,0)",this.onBegin=o.onBegin,this.onEnd=o.onEnd,this._ctx=e.getContext("2d"),this.clear(),this._handleMouseDown=function(t){1===t.which&&(i._mouseButtonDown=!0,i._strokeBegin(t))},this._handleMouseMove=function(t){i._mouseButtonDown&&i._strokeMoveUpdate(t)},this._handleMouseUp=function(t){1===t.which&&i._mouseButtonDown&&(i._mouseButtonDown=!1,i._strokeEnd(t))},this._handleTouchStart=function(t){if(t.preventDefault(),1===t.targetTouches.length){var e=t.changedTouches[0];i._strokeBegin(e)}},this._handleTouchMove=function(t){t.preventDefault();var e=t.targetTouches[0];i._strokeMoveUpdate(e)},this._handleTouchEnd=function(t){if(t.target===i.canvas){t.preventDefault();var e=t.targetTouches[0];i._strokeEnd(e)}},this.on()}return t.prototype.clear=function(){var t=this._ctx,e=this.canvas;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._isEmpty=!0},t.prototype.fromDataURL=function(t,e){var o=this;void 0===e&&(e={});var i=new Image,n=e.ratio||window.devicePixelRatio||1,s=e.width||this.canvas.width/n,r=e.height||this.canvas.height/n;this._reset(),i.src=t,i.onload=function(){o._ctx.drawImage(i,0,0,s,r)},this._isEmpty=!1},t.prototype.toDataURL=function(t,e){switch(t){case"image/svg+xml":return this._toSVG();default:return this.canvas.toDataURL(t,e)}},t.prototype.on=function(){this._handleMouseEvents(),this._handleTouchEvents()},t.prototype.off=function(){this.canvas.style.msTouchAction="auto",this.canvas.style.touchAction="auto",this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("mousemove",this._handleMouseMove),document.removeEventListener("mouseup",this._handleMouseUp),this.canvas.removeEventListener("touchstart",this._handleTouchStart),this.canvas.removeEventListener("touchmove",this._handleTouchMove),this.canvas.removeEventListener("touchend",this._handleTouchEnd)},t.prototype.isEmpty=function(){return this._isEmpty},t.prototype.fromData=function(t){var e=this;this.clear(),this._fromData(t,function(t){var o=t.color,i=t.curve;return e._drawCurve({color:o,curve:i})},function(t){var o=t.color,i=t.point;return e._drawDot({color:o,point:i})}),this._data=t},t.prototype.toData=function(){return this._data},t.prototype._strokeBegin=function(t){var e={color:this.penColor,points:[]};this._data.push(e),this._reset(),this._strokeUpdate(t),"function"==typeof this.onBegin&&this.onBegin(t)},t.prototype._strokeUpdate=function(t){var e=t.clientX,o=t.clientY,i=this._createPoint(e,o),n=this._data[this._data.length-1],s=n.points,r=s.length>0&&s[s.length-1],h=!!r&&i.distanceTo(r)<=this.minDistance,a=n.color;if(!r||!r||!h){var c=this._addPoint(i);r?c&&this._drawCurve({color:a,curve:c}):this._drawDot({color:a,point:i}),s.push({time:i.time,x:i.x,y:i.y})}},t.prototype._strokeEnd=function(t){this._strokeUpdate(t),"function"==typeof this.onEnd&&this.onEnd(t)},t.prototype._handleMouseEvents=function(){this._mouseButtonDown=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown),this.canvas.addEventListener("mousemove",this._handleMouseMove),document.addEventListener("mouseup",this._handleMouseUp)},t.prototype._handleTouchEvents=function(){this.canvas.style.msTouchAction="none",this.canvas.style.touchAction="none",this.canvas.addEventListener("touchstart",this._handleTouchStart),this.canvas.addEventListener("touchmove",this._handleTouchMove),this.canvas.addEventListener("touchend",this._handleTouchEnd)},t.prototype._reset=function(){this._points=[],this._lastVelocity=0,this._lastWidth=(this.minWidth+this.maxWidth)/2,this._ctx.fillStyle=this.penColor},t.prototype._createPoint=function(t,e){var o=this.canvas.getBoundingClientRect();return new Point(t-o.left,e-o.top,(new Date).getTime())},t.prototype._addPoint=function(t){var e=this._points;if(e.push(t),e.length>2){3===e.length&&e.unshift(e[0]);var o=this._calculateCurveWidths(e[1],e[2]),i=Bezier.fromPoints(e,o);return e.shift(),i}return null},t.prototype._calculateCurveWidths=function(t,e){var o=this.velocityFilterWeight*e.velocityFrom(t)+(1-this.velocityFilterWeight)*this._lastVelocity,i=this._strokeWidth(o),n={end:i,start:this._lastWidth};return this._lastVelocity=o,this._lastWidth=i,n},t.prototype._strokeWidth=function(t){return Math.max(this.maxWidth/(t+1),this.minWidth)},t.prototype._drawCurveSegment=function(t,e,o){var i=this._ctx;i.moveTo(t,e),i.arc(t,e,o,0,2*Math.PI,!1),this._isEmpty=!1},t.prototype._drawCurve=function(t){var e=t.color,o=t.curve,i=this._ctx,n=o.endWidth-o.startWidth,s=2*Math.floor(o.length());i.beginPath(),i.fillStyle=e;for(var r=0;r<s;r+=1){var h=r/s,a=h*h,c=a*h,u=1-h,l=u*u,d=l*u,v=d*o.startPoint.x;v+=3*l*h*o.control1.x,v+=3*u*a*o.control2.x,v+=c*o.endPoint.x;var p=d*o.startPoint.y;p+=3*l*h*o.control1.y,p+=3*u*a*o.control2.y,p+=c*o.endPoint.y;var f=o.startWidth+c*n;this._drawCurveSegment(v,p,f)}i.closePath(),i.fill()},t.prototype._drawDot=function(t){var e=t.color,o=t.point,i=this._ctx,n="function"==typeof this.dotSize?this.dotSize():this.dotSize;i.beginPath(),this._drawCurveSegment(o.x,o.y,n),i.closePath(),i.fillStyle=e,i.fill()},t.prototype._fromData=function(t,e,o){for(var i=0,n=t;i<n.length;i++){var s=n[i],r=s.color,h=s.points;if(h.length>1)for(var a=0;a<h.length;a+=1){var c=h[a],u=new Point(c.x,c.y,c.time);this.penColor=r,0===a&&this._reset();var l=this._addPoint(u);l&&e({color:r,curve:l})}else this._reset(),o({color:r,point:h[0]})}},t.prototype._toSVG=function(){var t=this,e=this._data,o=Math.max(window.devicePixelRatio||1,1),i=this.canvas.width/o,n=this.canvas.height/o,s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width",this.canvas.width.toString()),s.setAttribute("height",this.canvas.height.toString()),this._fromData(e,function(t){var e=t.color,o=t.curve,i=document.createElement("path");if(!(isNaN(o.control1.x)||isNaN(o.control1.y)||isNaN(o.control2.x)||isNaN(o.control2.y))){var n="M "+o.startPoint.x.toFixed(3)+","+o.startPoint.y.toFixed(3)+" C "+o.control1.x.toFixed(3)+","+o.control1.y.toFixed(3)+" "+o.control2.x.toFixed(3)+","+o.control2.y.toFixed(3)+" "+o.endPoint.x.toFixed(3)+","+o.endPoint.y.toFixed(3);i.setAttribute("d",n),i.setAttribute("stroke-width",(2.25*o.endWidth).toFixed(3)),i.setAttribute("stroke",e),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),s.appendChild(i)}},function(e){var o=e.color,i=e.point,n=document.createElement("circle"),r="function"==typeof t.dotSize?t.dotSize():t.dotSize;n.setAttribute("r",r.toString()),n.setAttribute("cx",i.x.toString()),n.setAttribute("cy",i.y.toString()),n.setAttribute("fill",o),s.appendChild(n)});var r='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 '+i+" "+n+'" width="'+i+'" height="'+n+'">',h=s.innerHTML;if(void 0===h){var a=document.createElement("dummy"),c=s.childNodes;a.innerHTML="";for(var u=0;u<c.length;u+=1)a.appendChild(c[u].cloneNode(!0));h=a.innerHTML}return"data:image/svg+xml;base64,"+btoa(r+h+"</svg>")},t}();module.exports=SignaturePad; | ||
"use strict";var Point=function(){function t(t,e,o){this.x=t,this.y=e,this.time=o||Date.now()}return t.prototype.distanceTo=function(t){return Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))},t.prototype.equals=function(t){return this.x===t.x&&this.y===t.y&&this.time===t.time},t.prototype.velocityFrom=function(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0},t}(),Bezier=function(){function t(t,e,o,i,n,s){this.startPoint=t,this.control2=e,this.control1=o,this.endPoint=i,this.startWidth=n,this.endWidth=s}return t.fromPoints=function(e,o){var i=this.calculateControlPoints(e[0],e[1],e[2]).c2,n=this.calculateControlPoints(e[1],e[2],e[3]).c1;return new t(e[1],i,n,e[2],o.start,o.end)},t.calculateControlPoints=function(t,e,o){var i=t.x-e.x,n=t.y-e.y,s=e.x-o.x,r=e.y-o.y,h=(t.x+e.x)/2,a=(t.y+e.y)/2,c=(e.x+o.x)/2,u=(e.y+o.y)/2,l=Math.sqrt(i*i+n*n),d=Math.sqrt(s*s+r*r),v=d/(l+d),p=c+(h-c)*v,f=u+(a-u)*v,_=e.x-p,y=e.y-f;return{c1:new Point(h+_,a+y),c2:new Point(c+_,u+y)}},t.prototype.length=function(){for(var t,e,o=0,i=0;i<=10;i+=1){var n=i/10,s=this.point(n,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),r=this.point(n,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(i>0){var h=s-t,a=r-e;o+=Math.sqrt(h*h+a*a)}t=s,e=r}return o},t.prototype.point=function(t,e,o,i,n){return e*(1-t)*(1-t)*(1-t)+3*o*(1-t)*(1-t)*t+3*i*(1-t)*t*t+n*t*t*t},t}();function throttle(t,e){void 0===e&&(e=250);var o,i,n,s=0,r=null,h=function(){s=Date.now(),r=null,o=t.apply(i,n),r||(i=null,n=[])};return function(){for(var a=[],c=0;c<arguments.length;c++)a[c]=arguments[c];var u=Date.now(),l=e-(u-s);return i=this,n=a,l<=0||l>e?(r&&(clearTimeout(r),r=null),s=u,o=t.apply(i,n),r||(i=null,n=[])):r||(r=setTimeout(h,l)),o}}var SignaturePad=function(){function t(e,o){void 0===o&&(o={});var i=this;this.canvas=e,this.options=o,this._handleMouseDown=function(t){1===t.which&&(i._mouseButtonDown=!0,i._strokeBegin(t))},this._handleMouseMove=function(t){i._mouseButtonDown&&i._strokeMoveUpdate(t)},this._handleMouseUp=function(t){1===t.which&&i._mouseButtonDown&&(i._mouseButtonDown=!1,i._strokeEnd(t))},this._handleTouchStart=function(t){if(t.preventDefault(),1===t.targetTouches.length){var e=t.changedTouches[0];i._strokeBegin(e)}},this._handleTouchMove=function(t){t.preventDefault();var e=t.targetTouches[0];i._strokeMoveUpdate(e)},this._handleTouchEnd=function(t){if(t.target===i.canvas){t.preventDefault();var e=t.changedTouches[0];i._strokeEnd(e)}},this.velocityFilterWeight=o.velocityFilterWeight||.7,this.minWidth=o.minWidth||.5,this.maxWidth=o.maxWidth||2.5,this.throttle="throttle"in o?o.throttle:16,this.minDistance="minDistance"in o?o.minDistance:5,this.throttle?this._strokeMoveUpdate=throttle(t.prototype._strokeUpdate,this.throttle):this._strokeMoveUpdate=t.prototype._strokeUpdate,this.dotSize=o.dotSize||function(){return(this.minWidth+this.maxWidth)/2},this.penColor=o.penColor||"black",this.backgroundColor=o.backgroundColor||"rgba(0,0,0,0)",this.onBegin=o.onBegin,this.onEnd=o.onEnd,this._ctx=e.getContext("2d"),this.clear(),this.on()}return t.prototype.clear=function(){var t=this._ctx,e=this.canvas;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._isEmpty=!0},t.prototype.fromDataURL=function(t,e,o){var i=this;void 0===e&&(e={});var n=new Image,s=e.ratio||window.devicePixelRatio||1,r=e.width||this.canvas.width/s,h=e.height||this.canvas.height/s;this._reset(),n.onload=function(){i._ctx.drawImage(n,0,0,r,h),o&&o()},n.onerror=function(t){o&&o(t)},n.src=t,this._isEmpty=!1},t.prototype.toDataURL=function(t,e){switch(void 0===t&&(t="image/png"),t){case"image/svg+xml":return this._toSVG();default:return this.canvas.toDataURL(t,e)}},t.prototype.on=function(){this._handleMouseEvents(),"ontouchstart"in window&&this._handleTouchEvents()},t.prototype.off=function(){this.canvas.style.msTouchAction="auto",this.canvas.style.touchAction="auto",this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("mousemove",this._handleMouseMove),document.removeEventListener("mouseup",this._handleMouseUp),this.canvas.removeEventListener("touchstart",this._handleTouchStart),this.canvas.removeEventListener("touchmove",this._handleTouchMove),this.canvas.removeEventListener("touchend",this._handleTouchEnd)},t.prototype.isEmpty=function(){return this._isEmpty},t.prototype.fromData=function(t){var e=this;this.clear(),this._fromData(t,function(t){var o=t.color,i=t.curve;return e._drawCurve({color:o,curve:i})},function(t){var o=t.color,i=t.point;return e._drawDot({color:o,point:i})}),this._data=t},t.prototype.toData=function(){return this._data},t.prototype._strokeBegin=function(t){var e={color:this.penColor,points:[]};this._data.push(e),this._reset(),this._strokeUpdate(t),"function"==typeof this.onBegin&&this.onBegin(t)},t.prototype._strokeUpdate=function(t){var e=t.clientX,o=t.clientY,i=this._createPoint(e,o),n=this._data[this._data.length-1],s=n.points,r=s.length>0&&s[s.length-1],h=!!r&&i.distanceTo(r)<=this.minDistance,a=n.color;if(!r||!r||!h){var c=this._addPoint(i);r?c&&this._drawCurve({color:a,curve:c}):this._drawDot({color:a,point:i}),s.push({time:i.time,x:i.x,y:i.y})}},t.prototype._strokeEnd=function(t){this._strokeUpdate(t),"function"==typeof this.onEnd&&this.onEnd(t)},t.prototype._handleMouseEvents=function(){this._mouseButtonDown=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown),this.canvas.addEventListener("mousemove",this._handleMouseMove),document.addEventListener("mouseup",this._handleMouseUp)},t.prototype._handleTouchEvents=function(){this.canvas.style.msTouchAction="none",this.canvas.style.touchAction="none",this.canvas.addEventListener("touchstart",this._handleTouchStart),this.canvas.addEventListener("touchmove",this._handleTouchMove),this.canvas.addEventListener("touchend",this._handleTouchEnd)},t.prototype._reset=function(){this._points=[],this._lastVelocity=0,this._lastWidth=(this.minWidth+this.maxWidth)/2,this._ctx.fillStyle=this.penColor},t.prototype._createPoint=function(t,e){var o=this.canvas.getBoundingClientRect();return new Point(t-o.left,e-o.top,(new Date).getTime())},t.prototype._addPoint=function(t){var e=this._points;if(e.push(t),e.length>2){3===e.length&&e.unshift(e[0]);var o=this._calculateCurveWidths(e[1],e[2]),i=Bezier.fromPoints(e,o);return e.shift(),i}return null},t.prototype._calculateCurveWidths=function(t,e){var o=this.velocityFilterWeight*e.velocityFrom(t)+(1-this.velocityFilterWeight)*this._lastVelocity,i=this._strokeWidth(o),n={end:i,start:this._lastWidth};return this._lastVelocity=o,this._lastWidth=i,n},t.prototype._strokeWidth=function(t){return Math.max(this.maxWidth/(t+1),this.minWidth)},t.prototype._drawCurveSegment=function(t,e,o){var i=this._ctx;i.moveTo(t,e),i.arc(t,e,o,0,2*Math.PI,!1),this._isEmpty=!1},t.prototype._drawCurve=function(t){var e=t.color,o=t.curve,i=this._ctx,n=o.endWidth-o.startWidth,s=2*Math.floor(o.length());i.beginPath(),i.fillStyle=e;for(var r=0;r<s;r+=1){var h=r/s,a=h*h,c=a*h,u=1-h,l=u*u,d=l*u,v=d*o.startPoint.x;v+=3*l*h*o.control1.x,v+=3*u*a*o.control2.x,v+=c*o.endPoint.x;var p=d*o.startPoint.y;p+=3*l*h*o.control1.y,p+=3*u*a*o.control2.y,p+=c*o.endPoint.y;var f=o.startWidth+c*n;this._drawCurveSegment(v,p,f)}i.closePath(),i.fill()},t.prototype._drawDot=function(t){var e=t.color,o=t.point,i=this._ctx,n="function"==typeof this.dotSize?this.dotSize():this.dotSize;i.beginPath(),this._drawCurveSegment(o.x,o.y,n),i.closePath(),i.fillStyle=e,i.fill()},t.prototype._fromData=function(t,e,o){for(var i=0,n=t;i<n.length;i++){var s=n[i],r=s.color,h=s.points;if(h.length>1)for(var a=0;a<h.length;a+=1){var c=h[a],u=new Point(c.x,c.y,c.time);this.penColor=r,0===a&&this._reset();var l=this._addPoint(u);l&&e({color:r,curve:l})}else this._reset(),o({color:r,point:h[0]})}},t.prototype._toSVG=function(){var t=this,e=this._data,o=Math.max(window.devicePixelRatio||1,1),i=this.canvas.width/o,n=this.canvas.height/o,s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width",this.canvas.width.toString()),s.setAttribute("height",this.canvas.height.toString()),this._fromData(e,function(t){var e=t.color,o=t.curve,i=document.createElement("path");if(!(isNaN(o.control1.x)||isNaN(o.control1.y)||isNaN(o.control2.x)||isNaN(o.control2.y))){var n="M "+o.startPoint.x.toFixed(3)+","+o.startPoint.y.toFixed(3)+" C "+o.control1.x.toFixed(3)+","+o.control1.y.toFixed(3)+" "+o.control2.x.toFixed(3)+","+o.control2.y.toFixed(3)+" "+o.endPoint.x.toFixed(3)+","+o.endPoint.y.toFixed(3);i.setAttribute("d",n),i.setAttribute("stroke-width",(2.25*o.endWidth).toFixed(3)),i.setAttribute("stroke",e),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),s.appendChild(i)}},function(e){var o=e.color,i=e.point,n=document.createElement("circle"),r="function"==typeof t.dotSize?t.dotSize():t.dotSize;n.setAttribute("r",r.toString()),n.setAttribute("cx",i.x.toString()),n.setAttribute("cy",i.y.toString()),n.setAttribute("fill",o),s.appendChild(n)});var r='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 '+i+" "+n+'" width="'+i+'" height="'+n+'">',h=s.innerHTML;if(void 0===h){var a=document.createElement("dummy"),c=s.childNodes;a.innerHTML="";for(var u=0;u<c.length;u+=1)a.appendChild(c[u].cloneNode(!0));h=a.innerHTML}return"data:image/svg+xml;base64,"+btoa(r+h+"</svg>")},t}();module.exports=SignaturePad; |
/*! | ||
* Signature Pad v3.0.0-beta.1 | https://github.com/szimek/signature_pad | ||
* Signature Pad v3.0.0-beta.2 | https://github.com/szimek/signature_pad | ||
* (c) 2018 Szymon Nowak | Released under the MIT license | ||
@@ -7,491 +7,502 @@ */ | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global.SignaturePad = factory()); | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global.SignaturePad = factory()); | ||
}(this, (function () { 'use strict'; | ||
var Point = (function () { | ||
function Point(x, y, time) { | ||
this.x = x; | ||
this.y = y; | ||
this.time = time || Date.now(); | ||
} | ||
Point.prototype.distanceTo = function (start) { | ||
return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2)); | ||
}; | ||
Point.prototype.equals = function (other) { | ||
return this.x === other.x && this.y === other.y && this.time === other.time; | ||
}; | ||
Point.prototype.velocityFrom = function (start) { | ||
return (this.time !== start.time) ? this.distanceTo(start) / (this.time - start.time) : 0; | ||
}; | ||
return Point; | ||
}()); | ||
var Point = (function () { | ||
function Point(x, y, time) { | ||
this.x = x; | ||
this.y = y; | ||
this.time = time || Date.now(); | ||
} | ||
Point.prototype.distanceTo = function (start) { | ||
return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2)); | ||
}; | ||
Point.prototype.equals = function (other) { | ||
return this.x === other.x && this.y === other.y && this.time === other.time; | ||
}; | ||
Point.prototype.velocityFrom = function (start) { | ||
return (this.time !== start.time) ? this.distanceTo(start) / (this.time - start.time) : 0; | ||
}; | ||
return Point; | ||
}()); | ||
var Bezier = (function () { | ||
function Bezier(startPoint, control2, control1, endPoint, startWidth, endWidth) { | ||
this.startPoint = startPoint; | ||
this.control2 = control2; | ||
this.control1 = control1; | ||
this.endPoint = endPoint; | ||
this.startWidth = startWidth; | ||
this.endWidth = endWidth; | ||
} | ||
Bezier.fromPoints = function (points, widths) { | ||
var c2 = this.calculateControlPoints(points[0], points[1], points[2]).c2; | ||
var c3 = this.calculateControlPoints(points[1], points[2], points[3]).c1; | ||
return new Bezier(points[1], c2, c3, points[2], widths.start, widths.end); | ||
}; | ||
Bezier.calculateControlPoints = function (s1, s2, s3) { | ||
var dx1 = s1.x - s2.x; | ||
var dy1 = s1.y - s2.y; | ||
var dx2 = s2.x - s3.x; | ||
var dy2 = s2.y - s3.y; | ||
var m1 = { x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0 }; | ||
var m2 = { x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.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 = s2.x - cm.x; | ||
var ty = s2.y - cm.y; | ||
return { | ||
c1: new Point(m1.x + tx, m1.y + ty), | ||
c2: new Point(m2.x + tx, m2.y + ty) | ||
}; | ||
}; | ||
Bezier.prototype.length = function () { | ||
var steps = 10; | ||
var length = 0; | ||
var px; | ||
var py; | ||
for (var i = 0; i <= steps; i += 1) { | ||
var t = i / steps; | ||
var cx = this.point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x); | ||
var cy = this.point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y); | ||
if (i > 0) { | ||
var xdiff = cx - px; | ||
var ydiff = cy - py; | ||
length += Math.sqrt((xdiff * xdiff) + (ydiff * ydiff)); | ||
} | ||
px = cx; | ||
py = cy; | ||
} | ||
return length; | ||
}; | ||
Bezier.prototype.point = function (t, start, c1, c2, end) { | ||
return (start * (1.0 - t) * (1.0 - t) * (1.0 - t)) | ||
+ (3.0 * c1 * (1.0 - t) * (1.0 - t) * t) | ||
+ (3.0 * c2 * (1.0 - t) * t * t) | ||
+ (end * t * t * t); | ||
}; | ||
return Bezier; | ||
}()); | ||
var Bezier = (function () { | ||
function Bezier(startPoint, control2, control1, endPoint, startWidth, endWidth) { | ||
this.startPoint = startPoint; | ||
this.control2 = control2; | ||
this.control1 = control1; | ||
this.endPoint = endPoint; | ||
this.startWidth = startWidth; | ||
this.endWidth = endWidth; | ||
} | ||
Bezier.fromPoints = function (points, widths) { | ||
var c2 = this.calculateControlPoints(points[0], points[1], points[2]).c2; | ||
var c3 = this.calculateControlPoints(points[1], points[2], points[3]).c1; | ||
return new Bezier(points[1], c2, c3, points[2], widths.start, widths.end); | ||
}; | ||
Bezier.calculateControlPoints = function (s1, s2, s3) { | ||
var dx1 = s1.x - s2.x; | ||
var dy1 = s1.y - s2.y; | ||
var dx2 = s2.x - s3.x; | ||
var dy2 = s2.y - s3.y; | ||
var m1 = { x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0 }; | ||
var m2 = { x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.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 = s2.x - cm.x; | ||
var ty = s2.y - cm.y; | ||
return { | ||
c1: new Point(m1.x + tx, m1.y + ty), | ||
c2: new Point(m2.x + tx, m2.y + ty) | ||
}; | ||
}; | ||
Bezier.prototype.length = function () { | ||
var steps = 10; | ||
var length = 0; | ||
var px; | ||
var py; | ||
for (var i = 0; i <= steps; i += 1) { | ||
var t = i / steps; | ||
var cx = this.point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x); | ||
var cy = this.point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y); | ||
if (i > 0) { | ||
var xdiff = cx - px; | ||
var ydiff = cy - py; | ||
length += Math.sqrt((xdiff * xdiff) + (ydiff * ydiff)); | ||
} | ||
px = cx; | ||
py = cy; | ||
} | ||
return length; | ||
}; | ||
Bezier.prototype.point = function (t, start, c1, c2, end) { | ||
return (start * (1.0 - t) * (1.0 - t) * (1.0 - t)) | ||
+ (3.0 * c1 * (1.0 - t) * (1.0 - t) * t) | ||
+ (3.0 * c2 * (1.0 - t) * t * t) | ||
+ (end * t * t * t); | ||
}; | ||
return Bezier; | ||
}()); | ||
function throttle(fn, wait) { | ||
if (wait === void 0) { wait = 250; } | ||
var previous = 0; | ||
var timeout = null; | ||
var result; | ||
var storedContext; | ||
var storedArgs; | ||
var later = function () { | ||
previous = Date.now(); | ||
timeout = null; | ||
result = fn.apply(storedContext, storedArgs); | ||
if (!timeout) { | ||
storedContext = null; | ||
storedArgs = []; | ||
} | ||
}; | ||
return function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
var now = Date.now(); | ||
var remaining = wait - (now - previous); | ||
storedContext = this; | ||
storedArgs = args; | ||
if (remaining <= 0 || remaining > wait) { | ||
if (timeout) { | ||
clearTimeout(timeout); | ||
timeout = null; | ||
} | ||
previous = now; | ||
result = fn.apply(storedContext, storedArgs); | ||
if (!timeout) { | ||
storedContext = null; | ||
storedArgs = []; | ||
} | ||
} | ||
else if (!timeout) { | ||
timeout = setTimeout(later, remaining); | ||
} | ||
return result; | ||
}; | ||
} | ||
function throttle(fn, wait) { | ||
if (wait === void 0) { wait = 250; } | ||
var previous = 0; | ||
var timeout = null; | ||
var result; | ||
var storedContext; | ||
var storedArgs; | ||
var later = function () { | ||
previous = Date.now(); | ||
timeout = null; | ||
result = fn.apply(storedContext, storedArgs); | ||
if (!timeout) { | ||
storedContext = null; | ||
storedArgs = []; | ||
} | ||
}; | ||
return function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
var now = Date.now(); | ||
var remaining = wait - (now - previous); | ||
storedContext = this; | ||
storedArgs = args; | ||
if (remaining <= 0 || remaining > wait) { | ||
if (timeout) { | ||
clearTimeout(timeout); | ||
timeout = null; | ||
} | ||
previous = now; | ||
result = fn.apply(storedContext, storedArgs); | ||
if (!timeout) { | ||
storedContext = null; | ||
storedArgs = []; | ||
} | ||
} | ||
else if (!timeout) { | ||
timeout = setTimeout(later, remaining); | ||
} | ||
return result; | ||
}; | ||
} | ||
var SignaturePad = (function () { | ||
function SignaturePad(canvas, options) { | ||
if (options === void 0) { options = {}; } | ||
var _this = this; | ||
this.canvas = canvas; | ||
this.options = options; | ||
this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.minWidth = options.minWidth || 0.5; | ||
this.maxWidth = options.maxWidth || 2.5; | ||
this.throttle = ("throttle" in options ? options.throttle : 16); | ||
this.minDistance = ("minDistance" in options ? options.minDistance : 5); | ||
if (this.throttle) { | ||
this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle); | ||
} | ||
else { | ||
this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate; | ||
} | ||
this.dotSize = options.dotSize || function () { | ||
return (this.minWidth + this.maxWidth) / 2; | ||
}; | ||
this.penColor = options.penColor || "black"; | ||
this.backgroundColor = options.backgroundColor || "rgba(0,0,0,0)"; | ||
this.onBegin = options.onBegin; | ||
this.onEnd = options.onEnd; | ||
this._ctx = canvas.getContext("2d"); | ||
this.clear(); | ||
this._handleMouseDown = function (event) { | ||
if (event.which === 1) { | ||
_this._mouseButtonDown = true; | ||
_this._strokeBegin(event); | ||
} | ||
}; | ||
this._handleMouseMove = function (event) { | ||
if (_this._mouseButtonDown) { | ||
_this._strokeMoveUpdate(event); | ||
} | ||
}; | ||
this._handleMouseUp = function (event) { | ||
if (event.which === 1 && _this._mouseButtonDown) { | ||
_this._mouseButtonDown = false; | ||
_this._strokeEnd(event); | ||
} | ||
}; | ||
this._handleTouchStart = function (event) { | ||
event.preventDefault(); | ||
if (event.targetTouches.length === 1) { | ||
var touch = event.changedTouches[0]; | ||
_this._strokeBegin(touch); | ||
} | ||
}; | ||
this._handleTouchMove = function (event) { | ||
event.preventDefault(); | ||
var touch = event.targetTouches[0]; | ||
_this._strokeMoveUpdate(touch); | ||
}; | ||
this._handleTouchEnd = function (event) { | ||
var wasCanvasTouched = event.target === _this.canvas; | ||
if (wasCanvasTouched) { | ||
event.preventDefault(); | ||
var touch = event.targetTouches[0]; | ||
_this._strokeEnd(touch); | ||
} | ||
}; | ||
this.on(); | ||
} | ||
SignaturePad.prototype.clear = function () { | ||
var ctx = this._ctx; | ||
var canvas = this.canvas; | ||
ctx.fillStyle = this.backgroundColor; | ||
ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
ctx.fillRect(0, 0, canvas.width, canvas.height); | ||
this._data = []; | ||
this._reset(); | ||
this._isEmpty = true; | ||
}; | ||
SignaturePad.prototype.fromDataURL = function (dataUrl, options) { | ||
var _this = this; | ||
if (options === void 0) { options = {}; } | ||
var image = new Image(); | ||
var ratio = options.ratio || window.devicePixelRatio || 1; | ||
var width = options.width || (this.canvas.width / ratio); | ||
var height = options.height || (this.canvas.height / ratio); | ||
this._reset(); | ||
image.src = dataUrl; | ||
image.onload = function () { | ||
_this._ctx.drawImage(image, 0, 0, width, height); | ||
}; | ||
this._isEmpty = false; | ||
}; | ||
SignaturePad.prototype.toDataURL = function (type, encoderOptions) { | ||
switch (type) { | ||
case "image/svg+xml": | ||
return this._toSVG(); | ||
default: | ||
return this.canvas.toDataURL(type, encoderOptions); | ||
} | ||
}; | ||
SignaturePad.prototype.on = function () { | ||
this._handleMouseEvents(); | ||
this._handleTouchEvents(); | ||
}; | ||
SignaturePad.prototype.off = function () { | ||
this.canvas.style.msTouchAction = "auto"; | ||
this.canvas.style.touchAction = "auto"; | ||
this.canvas.removeEventListener("mousedown", this._handleMouseDown); | ||
this.canvas.removeEventListener("mousemove", this._handleMouseMove); | ||
document.removeEventListener("mouseup", this._handleMouseUp); | ||
this.canvas.removeEventListener("touchstart", this._handleTouchStart); | ||
this.canvas.removeEventListener("touchmove", this._handleTouchMove); | ||
this.canvas.removeEventListener("touchend", this._handleTouchEnd); | ||
}; | ||
SignaturePad.prototype.isEmpty = function () { | ||
return this._isEmpty; | ||
}; | ||
SignaturePad.prototype.fromData = function (pointGroups) { | ||
var _this = this; | ||
this.clear(); | ||
this._fromData(pointGroups, function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
return _this._drawCurve({ color: color, curve: curve }); | ||
}, function (_a) { | ||
var color = _a.color, point = _a.point; | ||
return _this._drawDot({ color: color, point: point }); | ||
}); | ||
this._data = pointGroups; | ||
}; | ||
SignaturePad.prototype.toData = function () { | ||
return this._data; | ||
}; | ||
SignaturePad.prototype._strokeBegin = function (event) { | ||
var newPointGroup = { | ||
color: this.penColor, | ||
points: [] | ||
}; | ||
this._data.push(newPointGroup); | ||
this._reset(); | ||
this._strokeUpdate(event); | ||
if (typeof this.onBegin === "function") { | ||
this.onBegin(event); | ||
} | ||
}; | ||
SignaturePad.prototype._strokeUpdate = function (event) { | ||
var x = event.clientX; | ||
var y = event.clientY; | ||
var point = this._createPoint(x, y); | ||
var lastPointGroup = this._data[this._data.length - 1]; | ||
var lastPoints = lastPointGroup.points; | ||
var lastPoint = lastPoints.length > 0 && lastPoints[lastPoints.length - 1]; | ||
var isLastPointTooClose = lastPoint ? point.distanceTo(lastPoint) <= this.minDistance : false; | ||
var color = lastPointGroup.color; | ||
if (!lastPoint || !(lastPoint && isLastPointTooClose)) { | ||
var curve = this._addPoint(point); | ||
if (!lastPoint) { | ||
this._drawDot({ color: color, point: point }); | ||
} | ||
else if (curve) { | ||
this._drawCurve({ color: color, curve: curve }); | ||
} | ||
lastPoints.push({ | ||
time: point.time, | ||
x: point.x, | ||
y: point.y | ||
}); | ||
} | ||
}; | ||
SignaturePad.prototype._strokeEnd = function (event) { | ||
this._strokeUpdate(event); | ||
if (typeof this.onEnd === "function") { | ||
this.onEnd(event); | ||
} | ||
}; | ||
SignaturePad.prototype._handleMouseEvents = function () { | ||
this._mouseButtonDown = false; | ||
this.canvas.addEventListener("mousedown", this._handleMouseDown); | ||
this.canvas.addEventListener("mousemove", this._handleMouseMove); | ||
document.addEventListener("mouseup", this._handleMouseUp); | ||
}; | ||
SignaturePad.prototype._handleTouchEvents = function () { | ||
this.canvas.style.msTouchAction = "none"; | ||
this.canvas.style.touchAction = "none"; | ||
this.canvas.addEventListener("touchstart", this._handleTouchStart); | ||
this.canvas.addEventListener("touchmove", this._handleTouchMove); | ||
this.canvas.addEventListener("touchend", this._handleTouchEnd); | ||
}; | ||
SignaturePad.prototype._reset = function () { | ||
this._points = []; | ||
this._lastVelocity = 0; | ||
this._lastWidth = (this.minWidth + this.maxWidth) / 2; | ||
this._ctx.fillStyle = this.penColor; | ||
}; | ||
SignaturePad.prototype._createPoint = function (x, y) { | ||
var rect = this.canvas.getBoundingClientRect(); | ||
return new Point(x - rect.left, y - rect.top, new Date().getTime()); | ||
}; | ||
SignaturePad.prototype._addPoint = function (point) { | ||
var _points = this._points; | ||
_points.push(point); | ||
if (_points.length > 2) { | ||
if (_points.length === 3) { | ||
_points.unshift(_points[0]); | ||
} | ||
var widths = this._calculateCurveWidths(_points[1], _points[2]); | ||
var curve = Bezier.fromPoints(_points, widths); | ||
_points.shift(); | ||
return curve; | ||
} | ||
return null; | ||
}; | ||
SignaturePad.prototype._calculateCurveWidths = function (startPoint, endPoint) { | ||
var velocity = (this.velocityFilterWeight * endPoint.velocityFrom(startPoint)) | ||
+ ((1 - this.velocityFilterWeight) * this._lastVelocity); | ||
var newWidth = this._strokeWidth(velocity); | ||
var widths = { | ||
end: newWidth, | ||
start: this._lastWidth | ||
}; | ||
this._lastVelocity = velocity; | ||
this._lastWidth = newWidth; | ||
return widths; | ||
}; | ||
SignaturePad.prototype._strokeWidth = function (velocity) { | ||
return Math.max(this.maxWidth / (velocity + 1), this.minWidth); | ||
}; | ||
SignaturePad.prototype._drawCurveSegment = function (x, y, width) { | ||
var ctx = this._ctx; | ||
ctx.moveTo(x, y); | ||
ctx.arc(x, y, width, 0, 2 * Math.PI, false); | ||
this._isEmpty = false; | ||
}; | ||
SignaturePad.prototype._drawCurve = function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
var ctx = this._ctx; | ||
var widthDelta = curve.endWidth - curve.startWidth; | ||
var drawSteps = Math.floor(curve.length()) * 2; | ||
ctx.beginPath(); | ||
ctx.fillStyle = color; | ||
for (var i = 0; i < drawSteps; i += 1) { | ||
var t = i / drawSteps; | ||
var tt = t * t; | ||
var ttt = tt * t; | ||
var u = 1 - t; | ||
var uu = u * u; | ||
var uuu = uu * u; | ||
var x = uuu * curve.startPoint.x; | ||
x += 3 * uu * t * curve.control1.x; | ||
x += 3 * u * tt * curve.control2.x; | ||
x += ttt * curve.endPoint.x; | ||
var y = uuu * curve.startPoint.y; | ||
y += 3 * uu * t * curve.control1.y; | ||
y += 3 * u * tt * curve.control2.y; | ||
y += ttt * curve.endPoint.y; | ||
var width = curve.startWidth + (ttt * widthDelta); | ||
this._drawCurveSegment(x, y, width); | ||
} | ||
ctx.closePath(); | ||
ctx.fill(); | ||
}; | ||
SignaturePad.prototype._drawDot = function (_a) { | ||
var color = _a.color, point = _a.point; | ||
var ctx = this._ctx; | ||
var width = typeof this.dotSize === "function" ? this.dotSize() : this.dotSize; | ||
ctx.beginPath(); | ||
this._drawCurveSegment(point.x, point.y, width); | ||
ctx.closePath(); | ||
ctx.fillStyle = color; | ||
ctx.fill(); | ||
}; | ||
SignaturePad.prototype._fromData = function (pointGroups, drawCurve, drawDot) { | ||
for (var _i = 0, pointGroups_1 = pointGroups; _i < pointGroups_1.length; _i++) { | ||
var group = pointGroups_1[_i]; | ||
var color = group.color, points = group.points; | ||
if (points.length > 1) { | ||
for (var j = 0; j < points.length; j += 1) { | ||
var basicPoint = points[j]; | ||
var point = new Point(basicPoint.x, basicPoint.y, basicPoint.time); | ||
this.penColor = color; | ||
if (j === 0) { | ||
this._reset(); | ||
} | ||
var curve = this._addPoint(point); | ||
if (curve) { | ||
drawCurve({ color: color, curve: curve }); | ||
} | ||
} | ||
} | ||
else { | ||
this._reset(); | ||
drawDot({ | ||
color: color, | ||
point: points[0] | ||
}); | ||
} | ||
} | ||
}; | ||
SignaturePad.prototype._toSVG = function () { | ||
var _this = this; | ||
var pointGroups = this._data; | ||
var ratio = Math.max(window.devicePixelRatio || 1, 1); | ||
var minX = 0; | ||
var minY = 0; | ||
var maxX = this.canvas.width / ratio; | ||
var maxY = this.canvas.height / ratio; | ||
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | ||
svg.setAttribute("width", this.canvas.width.toString()); | ||
svg.setAttribute("height", this.canvas.height.toString()); | ||
this._fromData(pointGroups, function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
var path = document.createElement("path"); | ||
if (!isNaN(curve.control1.x) && | ||
!isNaN(curve.control1.y) && | ||
!isNaN(curve.control2.x) && | ||
!isNaN(curve.control2.y)) { | ||
var attr = "M " + curve.startPoint.x.toFixed(3) + "," + curve.startPoint.y.toFixed(3) + " " | ||
+ ("C " + curve.control1.x.toFixed(3) + "," + curve.control1.y.toFixed(3) + " ") | ||
+ (curve.control2.x.toFixed(3) + "," + curve.control2.y.toFixed(3) + " ") | ||
+ (curve.endPoint.x.toFixed(3) + "," + curve.endPoint.y.toFixed(3)); | ||
path.setAttribute("d", attr); | ||
path.setAttribute("stroke-width", (curve.endWidth * 2.25).toFixed(3)); | ||
path.setAttribute("stroke", color); | ||
path.setAttribute("fill", "none"); | ||
path.setAttribute("stroke-linecap", "round"); | ||
svg.appendChild(path); | ||
} | ||
}, function (_a) { | ||
var color = _a.color, point = _a.point; | ||
var circle = document.createElement("circle"); | ||
var dotSize = typeof _this.dotSize === "function" ? _this.dotSize() : _this.dotSize; | ||
circle.setAttribute("r", dotSize.toString()); | ||
circle.setAttribute("cx", point.x.toString()); | ||
circle.setAttribute("cy", point.y.toString()); | ||
circle.setAttribute("fill", color); | ||
svg.appendChild(circle); | ||
}); | ||
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\"" | ||
+ (" viewBox=\"" + minX + " " + minY + " " + maxX + " " + maxY + "\"") | ||
+ (" width=\"" + maxX + "\"") | ||
+ (" height=\"" + maxY + "\"") | ||
+ ">"; | ||
var body = svg.innerHTML; | ||
if (body === undefined) { | ||
var dummy = document.createElement("dummy"); | ||
var nodes = svg.childNodes; | ||
dummy.innerHTML = ""; | ||
for (var i = 0; i < nodes.length; i += 1) { | ||
dummy.appendChild(nodes[i].cloneNode(true)); | ||
} | ||
body = dummy.innerHTML; | ||
} | ||
var footer = "</svg>"; | ||
var data = header + body + footer; | ||
return prefix + btoa(data); | ||
}; | ||
return SignaturePad; | ||
}()); | ||
var SignaturePad = (function () { | ||
function SignaturePad(canvas, options) { | ||
if (options === void 0) { options = {}; } | ||
var _this = this; | ||
this.canvas = canvas; | ||
this.options = options; | ||
this._handleMouseDown = function (event) { | ||
if (event.which === 1) { | ||
_this._mouseButtonDown = true; | ||
_this._strokeBegin(event); | ||
} | ||
}; | ||
this._handleMouseMove = function (event) { | ||
if (_this._mouseButtonDown) { | ||
_this._strokeMoveUpdate(event); | ||
} | ||
}; | ||
this._handleMouseUp = function (event) { | ||
if (event.which === 1 && _this._mouseButtonDown) { | ||
_this._mouseButtonDown = false; | ||
_this._strokeEnd(event); | ||
} | ||
}; | ||
this._handleTouchStart = function (event) { | ||
event.preventDefault(); | ||
if (event.targetTouches.length === 1) { | ||
var touch = event.changedTouches[0]; | ||
_this._strokeBegin(touch); | ||
} | ||
}; | ||
this._handleTouchMove = function (event) { | ||
event.preventDefault(); | ||
var touch = event.targetTouches[0]; | ||
_this._strokeMoveUpdate(touch); | ||
}; | ||
this._handleTouchEnd = function (event) { | ||
var wasCanvasTouched = event.target === _this.canvas; | ||
if (wasCanvasTouched) { | ||
event.preventDefault(); | ||
var touch = event.changedTouches[0]; | ||
_this._strokeEnd(touch); | ||
} | ||
}; | ||
this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.minWidth = options.minWidth || 0.5; | ||
this.maxWidth = options.maxWidth || 2.5; | ||
this.throttle = ("throttle" in options ? options.throttle : 16); | ||
this.minDistance = ("minDistance" in options ? options.minDistance : 5); | ||
if (this.throttle) { | ||
this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle); | ||
} | ||
else { | ||
this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate; | ||
} | ||
this.dotSize = options.dotSize || function () { | ||
return (this.minWidth + this.maxWidth) / 2; | ||
}; | ||
this.penColor = options.penColor || "black"; | ||
this.backgroundColor = options.backgroundColor || "rgba(0,0,0,0)"; | ||
this.onBegin = options.onBegin; | ||
this.onEnd = options.onEnd; | ||
this._ctx = canvas.getContext("2d"); | ||
this.clear(); | ||
this.on(); | ||
} | ||
SignaturePad.prototype.clear = function () { | ||
var ctx = this._ctx; | ||
var canvas = this.canvas; | ||
ctx.fillStyle = this.backgroundColor; | ||
ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
ctx.fillRect(0, 0, canvas.width, canvas.height); | ||
this._data = []; | ||
this._reset(); | ||
this._isEmpty = true; | ||
}; | ||
SignaturePad.prototype.fromDataURL = function (dataUrl, options, callback) { | ||
var _this = this; | ||
if (options === void 0) { options = {}; } | ||
var image = new Image(); | ||
var ratio = options.ratio || window.devicePixelRatio || 1; | ||
var width = options.width || (this.canvas.width / ratio); | ||
var height = options.height || (this.canvas.height / ratio); | ||
this._reset(); | ||
image.onload = function () { | ||
_this._ctx.drawImage(image, 0, 0, width, height); | ||
if (callback) { | ||
callback(); | ||
} | ||
}; | ||
image.onerror = function (error) { | ||
if (callback) { | ||
callback(error); | ||
} | ||
}; | ||
image.src = dataUrl; | ||
this._isEmpty = false; | ||
}; | ||
SignaturePad.prototype.toDataURL = function (type, encoderOptions) { | ||
if (type === void 0) { type = "image/png"; } | ||
switch (type) { | ||
case "image/svg+xml": | ||
return this._toSVG(); | ||
default: | ||
return this.canvas.toDataURL(type, encoderOptions); | ||
} | ||
}; | ||
SignaturePad.prototype.on = function () { | ||
this._handleMouseEvents(); | ||
if ("ontouchstart" in window) { | ||
this._handleTouchEvents(); | ||
} | ||
}; | ||
SignaturePad.prototype.off = function () { | ||
this.canvas.style.msTouchAction = "auto"; | ||
this.canvas.style.touchAction = "auto"; | ||
this.canvas.removeEventListener("mousedown", this._handleMouseDown); | ||
this.canvas.removeEventListener("mousemove", this._handleMouseMove); | ||
document.removeEventListener("mouseup", this._handleMouseUp); | ||
this.canvas.removeEventListener("touchstart", this._handleTouchStart); | ||
this.canvas.removeEventListener("touchmove", this._handleTouchMove); | ||
this.canvas.removeEventListener("touchend", this._handleTouchEnd); | ||
}; | ||
SignaturePad.prototype.isEmpty = function () { | ||
return this._isEmpty; | ||
}; | ||
SignaturePad.prototype.fromData = function (pointGroups) { | ||
var _this = this; | ||
this.clear(); | ||
this._fromData(pointGroups, function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
return _this._drawCurve({ color: color, curve: curve }); | ||
}, function (_a) { | ||
var color = _a.color, point = _a.point; | ||
return _this._drawDot({ color: color, point: point }); | ||
}); | ||
this._data = pointGroups; | ||
}; | ||
SignaturePad.prototype.toData = function () { | ||
return this._data; | ||
}; | ||
SignaturePad.prototype._strokeBegin = function (event) { | ||
var newPointGroup = { | ||
color: this.penColor, | ||
points: [] | ||
}; | ||
this._data.push(newPointGroup); | ||
this._reset(); | ||
this._strokeUpdate(event); | ||
if (typeof this.onBegin === "function") { | ||
this.onBegin(event); | ||
} | ||
}; | ||
SignaturePad.prototype._strokeUpdate = function (event) { | ||
var x = event.clientX; | ||
var y = event.clientY; | ||
var point = this._createPoint(x, y); | ||
var lastPointGroup = this._data[this._data.length - 1]; | ||
var lastPoints = lastPointGroup.points; | ||
var lastPoint = lastPoints.length > 0 && lastPoints[lastPoints.length - 1]; | ||
var isLastPointTooClose = lastPoint ? point.distanceTo(lastPoint) <= this.minDistance : false; | ||
var color = lastPointGroup.color; | ||
if (!lastPoint || !(lastPoint && isLastPointTooClose)) { | ||
var curve = this._addPoint(point); | ||
if (!lastPoint) { | ||
this._drawDot({ color: color, point: point }); | ||
} | ||
else if (curve) { | ||
this._drawCurve({ color: color, curve: curve }); | ||
} | ||
lastPoints.push({ | ||
time: point.time, | ||
x: point.x, | ||
y: point.y | ||
}); | ||
} | ||
}; | ||
SignaturePad.prototype._strokeEnd = function (event) { | ||
this._strokeUpdate(event); | ||
if (typeof this.onEnd === "function") { | ||
this.onEnd(event); | ||
} | ||
}; | ||
SignaturePad.prototype._handleMouseEvents = function () { | ||
this._mouseButtonDown = false; | ||
this.canvas.addEventListener("mousedown", this._handleMouseDown); | ||
this.canvas.addEventListener("mousemove", this._handleMouseMove); | ||
document.addEventListener("mouseup", this._handleMouseUp); | ||
}; | ||
SignaturePad.prototype._handleTouchEvents = function () { | ||
this.canvas.style.msTouchAction = "none"; | ||
this.canvas.style.touchAction = "none"; | ||
this.canvas.addEventListener("touchstart", this._handleTouchStart); | ||
this.canvas.addEventListener("touchmove", this._handleTouchMove); | ||
this.canvas.addEventListener("touchend", this._handleTouchEnd); | ||
}; | ||
SignaturePad.prototype._reset = function () { | ||
this._points = []; | ||
this._lastVelocity = 0; | ||
this._lastWidth = (this.minWidth + this.maxWidth) / 2; | ||
this._ctx.fillStyle = this.penColor; | ||
}; | ||
SignaturePad.prototype._createPoint = function (x, y) { | ||
var rect = this.canvas.getBoundingClientRect(); | ||
return new Point(x - rect.left, y - rect.top, new Date().getTime()); | ||
}; | ||
SignaturePad.prototype._addPoint = function (point) { | ||
var _points = this._points; | ||
_points.push(point); | ||
if (_points.length > 2) { | ||
if (_points.length === 3) { | ||
_points.unshift(_points[0]); | ||
} | ||
var widths = this._calculateCurveWidths(_points[1], _points[2]); | ||
var curve = Bezier.fromPoints(_points, widths); | ||
_points.shift(); | ||
return curve; | ||
} | ||
return null; | ||
}; | ||
SignaturePad.prototype._calculateCurveWidths = function (startPoint, endPoint) { | ||
var velocity = (this.velocityFilterWeight * endPoint.velocityFrom(startPoint)) | ||
+ ((1 - this.velocityFilterWeight) * this._lastVelocity); | ||
var newWidth = this._strokeWidth(velocity); | ||
var widths = { | ||
end: newWidth, | ||
start: this._lastWidth | ||
}; | ||
this._lastVelocity = velocity; | ||
this._lastWidth = newWidth; | ||
return widths; | ||
}; | ||
SignaturePad.prototype._strokeWidth = function (velocity) { | ||
return Math.max(this.maxWidth / (velocity + 1), this.minWidth); | ||
}; | ||
SignaturePad.prototype._drawCurveSegment = function (x, y, width) { | ||
var ctx = this._ctx; | ||
ctx.moveTo(x, y); | ||
ctx.arc(x, y, width, 0, 2 * Math.PI, false); | ||
this._isEmpty = false; | ||
}; | ||
SignaturePad.prototype._drawCurve = function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
var ctx = this._ctx; | ||
var widthDelta = curve.endWidth - curve.startWidth; | ||
var drawSteps = Math.floor(curve.length()) * 2; | ||
ctx.beginPath(); | ||
ctx.fillStyle = color; | ||
for (var i = 0; i < drawSteps; i += 1) { | ||
var t = i / drawSteps; | ||
var tt = t * t; | ||
var ttt = tt * t; | ||
var u = 1 - t; | ||
var uu = u * u; | ||
var uuu = uu * u; | ||
var x = uuu * curve.startPoint.x; | ||
x += 3 * uu * t * curve.control1.x; | ||
x += 3 * u * tt * curve.control2.x; | ||
x += ttt * curve.endPoint.x; | ||
var y = uuu * curve.startPoint.y; | ||
y += 3 * uu * t * curve.control1.y; | ||
y += 3 * u * tt * curve.control2.y; | ||
y += ttt * curve.endPoint.y; | ||
var width = curve.startWidth + (ttt * widthDelta); | ||
this._drawCurveSegment(x, y, width); | ||
} | ||
ctx.closePath(); | ||
ctx.fill(); | ||
}; | ||
SignaturePad.prototype._drawDot = function (_a) { | ||
var color = _a.color, point = _a.point; | ||
var ctx = this._ctx; | ||
var width = typeof this.dotSize === "function" ? this.dotSize() : this.dotSize; | ||
ctx.beginPath(); | ||
this._drawCurveSegment(point.x, point.y, width); | ||
ctx.closePath(); | ||
ctx.fillStyle = color; | ||
ctx.fill(); | ||
}; | ||
SignaturePad.prototype._fromData = function (pointGroups, drawCurve, drawDot) { | ||
for (var _i = 0, pointGroups_1 = pointGroups; _i < pointGroups_1.length; _i++) { | ||
var group = pointGroups_1[_i]; | ||
var color = group.color, points = group.points; | ||
if (points.length > 1) { | ||
for (var j = 0; j < points.length; j += 1) { | ||
var basicPoint = points[j]; | ||
var point = new Point(basicPoint.x, basicPoint.y, basicPoint.time); | ||
this.penColor = color; | ||
if (j === 0) { | ||
this._reset(); | ||
} | ||
var curve = this._addPoint(point); | ||
if (curve) { | ||
drawCurve({ color: color, curve: curve }); | ||
} | ||
} | ||
} | ||
else { | ||
this._reset(); | ||
drawDot({ | ||
color: color, | ||
point: points[0] | ||
}); | ||
} | ||
} | ||
}; | ||
SignaturePad.prototype._toSVG = function () { | ||
var _this = this; | ||
var pointGroups = this._data; | ||
var ratio = Math.max(window.devicePixelRatio || 1, 1); | ||
var minX = 0; | ||
var minY = 0; | ||
var maxX = this.canvas.width / ratio; | ||
var maxY = this.canvas.height / ratio; | ||
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | ||
svg.setAttribute("width", this.canvas.width.toString()); | ||
svg.setAttribute("height", this.canvas.height.toString()); | ||
this._fromData(pointGroups, function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
var path = document.createElement("path"); | ||
if (!isNaN(curve.control1.x) && | ||
!isNaN(curve.control1.y) && | ||
!isNaN(curve.control2.x) && | ||
!isNaN(curve.control2.y)) { | ||
var attr = "M " + curve.startPoint.x.toFixed(3) + "," + curve.startPoint.y.toFixed(3) + " " | ||
+ ("C " + curve.control1.x.toFixed(3) + "," + curve.control1.y.toFixed(3) + " ") | ||
+ (curve.control2.x.toFixed(3) + "," + curve.control2.y.toFixed(3) + " ") | ||
+ (curve.endPoint.x.toFixed(3) + "," + curve.endPoint.y.toFixed(3)); | ||
path.setAttribute("d", attr); | ||
path.setAttribute("stroke-width", (curve.endWidth * 2.25).toFixed(3)); | ||
path.setAttribute("stroke", color); | ||
path.setAttribute("fill", "none"); | ||
path.setAttribute("stroke-linecap", "round"); | ||
svg.appendChild(path); | ||
} | ||
}, function (_a) { | ||
var color = _a.color, point = _a.point; | ||
var circle = document.createElement("circle"); | ||
var dotSize = typeof _this.dotSize === "function" ? _this.dotSize() : _this.dotSize; | ||
circle.setAttribute("r", dotSize.toString()); | ||
circle.setAttribute("cx", point.x.toString()); | ||
circle.setAttribute("cy", point.y.toString()); | ||
circle.setAttribute("fill", color); | ||
svg.appendChild(circle); | ||
}); | ||
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\"" | ||
+ (" viewBox=\"" + minX + " " + minY + " " + maxX + " " + maxY + "\"") | ||
+ (" width=\"" + maxX + "\"") | ||
+ (" height=\"" + maxY + "\"") | ||
+ ">"; | ||
var body = svg.innerHTML; | ||
if (body === undefined) { | ||
var dummy = document.createElement("dummy"); | ||
var nodes = svg.childNodes; | ||
dummy.innerHTML = ""; | ||
for (var i = 0; i < nodes.length; i += 1) { | ||
dummy.appendChild(nodes[i].cloneNode(true)); | ||
} | ||
body = dummy.innerHTML; | ||
} | ||
var footer = "</svg>"; | ||
var data = header + body + footer; | ||
return prefix + btoa(data); | ||
}; | ||
return SignaturePad; | ||
}()); | ||
return SignaturePad; | ||
return SignaturePad; | ||
}))); |
@@ -1,1 +0,1 @@ | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.SignaturePad=e()}(this,function(){"use strict";var t=function(){function t(t,e,o){this.x=t,this.y=e,this.time=o||Date.now()}return t.prototype.distanceTo=function(t){return Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))},t.prototype.equals=function(t){return this.x===t.x&&this.y===t.y&&this.time===t.time},t.prototype.velocityFrom=function(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0},t}(),e=function(){function e(t,e,o,i,n,s){this.startPoint=t,this.control2=e,this.control1=o,this.endPoint=i,this.startWidth=n,this.endWidth=s}return e.fromPoints=function(t,o){var i=this.calculateControlPoints(t[0],t[1],t[2]).c2,n=this.calculateControlPoints(t[1],t[2],t[3]).c1;return new e(t[1],i,n,t[2],o.start,o.end)},e.calculateControlPoints=function(e,o,i){var n=e.x-o.x,s=e.y-o.y,r=o.x-i.x,h=o.y-i.y,a=(e.x+o.x)/2,c=(e.y+o.y)/2,u=(o.x+i.x)/2,l=(o.y+i.y)/2,d=Math.sqrt(n*n+s*s),v=Math.sqrt(r*r+h*h),p=v/(d+v),f=u+(a-u)*p,_=l+(c-l)*p,y=o.x-f,m=o.y-_;return{c1:new t(a+y,c+m),c2:new t(u+y,l+m)}},e.prototype.length=function(){for(var t,e,o=0,i=0;i<=10;i+=1){var n=i/10,s=this.point(n,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),r=this.point(n,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(i>0){var h=s-t,a=r-e;o+=Math.sqrt(h*h+a*a)}t=s,e=r}return o},e.prototype.point=function(t,e,o,i,n){return e*(1-t)*(1-t)*(1-t)+3*o*(1-t)*(1-t)*t+3*i*(1-t)*t*t+n*t*t*t},e}();return function(){function o(t,e){void 0===e&&(e={});var i=this;this.canvas=t,this.options=e,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.throttle?this._strokeMoveUpdate=function(t,e){void 0===e&&(e=250);var o,i,n,s=0,r=null,h=function(){s=Date.now(),r=null,o=t.apply(i,n),r||(i=null,n=[])};return function(){for(var a=[],c=0;c<arguments.length;c++)a[c]=arguments[c];var u=Date.now(),l=e-(u-s);return i=this,n=a,l<=0||l>e?(r&&(clearTimeout(r),r=null),s=u,o=t.apply(i,n),r||(i=null,n=[])):r||(r=setTimeout(h,l)),o}}(o.prototype._strokeUpdate,this.throttle):this._strokeMoveUpdate=o.prototype._strokeUpdate,this.dotSize=e.dotSize||function(){return(this.minWidth+this.maxWidth)/2},this.penColor=e.penColor||"black",this.backgroundColor=e.backgroundColor||"rgba(0,0,0,0)",this.onBegin=e.onBegin,this.onEnd=e.onEnd,this._ctx=t.getContext("2d"),this.clear(),this._handleMouseDown=function(t){1===t.which&&(i._mouseButtonDown=!0,i._strokeBegin(t))},this._handleMouseMove=function(t){i._mouseButtonDown&&i._strokeMoveUpdate(t)},this._handleMouseUp=function(t){1===t.which&&i._mouseButtonDown&&(i._mouseButtonDown=!1,i._strokeEnd(t))},this._handleTouchStart=function(t){if(t.preventDefault(),1===t.targetTouches.length){var e=t.changedTouches[0];i._strokeBegin(e)}},this._handleTouchMove=function(t){t.preventDefault();var e=t.targetTouches[0];i._strokeMoveUpdate(e)},this._handleTouchEnd=function(t){if(t.target===i.canvas){t.preventDefault();var e=t.targetTouches[0];i._strokeEnd(e)}},this.on()}return o.prototype.clear=function(){var t=this._ctx,e=this.canvas;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._isEmpty=!0},o.prototype.fromDataURL=function(t,e){var o=this;void 0===e&&(e={});var i=new Image,n=e.ratio||window.devicePixelRatio||1,s=e.width||this.canvas.width/n,r=e.height||this.canvas.height/n;this._reset(),i.src=t,i.onload=function(){o._ctx.drawImage(i,0,0,s,r)},this._isEmpty=!1},o.prototype.toDataURL=function(t,e){switch(t){case"image/svg+xml":return this._toSVG();default:return this.canvas.toDataURL(t,e)}},o.prototype.on=function(){this._handleMouseEvents(),this._handleTouchEvents()},o.prototype.off=function(){this.canvas.style.msTouchAction="auto",this.canvas.style.touchAction="auto",this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("mousemove",this._handleMouseMove),document.removeEventListener("mouseup",this._handleMouseUp),this.canvas.removeEventListener("touchstart",this._handleTouchStart),this.canvas.removeEventListener("touchmove",this._handleTouchMove),this.canvas.removeEventListener("touchend",this._handleTouchEnd)},o.prototype.isEmpty=function(){return this._isEmpty},o.prototype.fromData=function(t){var e=this;this.clear(),this._fromData(t,function(t){var o=t.color,i=t.curve;return e._drawCurve({color:o,curve:i})},function(t){var o=t.color,i=t.point;return e._drawDot({color:o,point:i})}),this._data=t},o.prototype.toData=function(){return this._data},o.prototype._strokeBegin=function(t){var e={color:this.penColor,points:[]};this._data.push(e),this._reset(),this._strokeUpdate(t),"function"==typeof this.onBegin&&this.onBegin(t)},o.prototype._strokeUpdate=function(t){var e=t.clientX,o=t.clientY,i=this._createPoint(e,o),n=this._data[this._data.length-1],s=n.points,r=s.length>0&&s[s.length-1],h=!!r&&i.distanceTo(r)<=this.minDistance,a=n.color;if(!r||!r||!h){var c=this._addPoint(i);r?c&&this._drawCurve({color:a,curve:c}):this._drawDot({color:a,point:i}),s.push({time:i.time,x:i.x,y:i.y})}},o.prototype._strokeEnd=function(t){this._strokeUpdate(t),"function"==typeof this.onEnd&&this.onEnd(t)},o.prototype._handleMouseEvents=function(){this._mouseButtonDown=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown),this.canvas.addEventListener("mousemove",this._handleMouseMove),document.addEventListener("mouseup",this._handleMouseUp)},o.prototype._handleTouchEvents=function(){this.canvas.style.msTouchAction="none",this.canvas.style.touchAction="none",this.canvas.addEventListener("touchstart",this._handleTouchStart),this.canvas.addEventListener("touchmove",this._handleTouchMove),this.canvas.addEventListener("touchend",this._handleTouchEnd)},o.prototype._reset=function(){this._points=[],this._lastVelocity=0,this._lastWidth=(this.minWidth+this.maxWidth)/2,this._ctx.fillStyle=this.penColor},o.prototype._createPoint=function(e,o){var i=this.canvas.getBoundingClientRect();return new t(e-i.left,o-i.top,(new Date).getTime())},o.prototype._addPoint=function(t){var o=this._points;if(o.push(t),o.length>2){3===o.length&&o.unshift(o[0]);var i=this._calculateCurveWidths(o[1],o[2]),n=e.fromPoints(o,i);return o.shift(),n}return null},o.prototype._calculateCurveWidths=function(t,e){var o=this.velocityFilterWeight*e.velocityFrom(t)+(1-this.velocityFilterWeight)*this._lastVelocity,i=this._strokeWidth(o),n={end:i,start:this._lastWidth};return this._lastVelocity=o,this._lastWidth=i,n},o.prototype._strokeWidth=function(t){return Math.max(this.maxWidth/(t+1),this.minWidth)},o.prototype._drawCurveSegment=function(t,e,o){var i=this._ctx;i.moveTo(t,e),i.arc(t,e,o,0,2*Math.PI,!1),this._isEmpty=!1},o.prototype._drawCurve=function(t){var e=t.color,o=t.curve,i=this._ctx,n=o.endWidth-o.startWidth,s=2*Math.floor(o.length());i.beginPath(),i.fillStyle=e;for(var r=0;r<s;r+=1){var h=r/s,a=h*h,c=a*h,u=1-h,l=u*u,d=l*u,v=d*o.startPoint.x;v+=3*l*h*o.control1.x,v+=3*u*a*o.control2.x,v+=c*o.endPoint.x;var p=d*o.startPoint.y;p+=3*l*h*o.control1.y,p+=3*u*a*o.control2.y,p+=c*o.endPoint.y;var f=o.startWidth+c*n;this._drawCurveSegment(v,p,f)}i.closePath(),i.fill()},o.prototype._drawDot=function(t){var e=t.color,o=t.point,i=this._ctx,n="function"==typeof this.dotSize?this.dotSize():this.dotSize;i.beginPath(),this._drawCurveSegment(o.x,o.y,n),i.closePath(),i.fillStyle=e,i.fill()},o.prototype._fromData=function(e,o,i){for(var n=0,s=e;n<s.length;n++){var r=s[n],h=r.color,a=r.points;if(a.length>1)for(var c=0;c<a.length;c+=1){var u=a[c],l=new t(u.x,u.y,u.time);this.penColor=h,0===c&&this._reset();var d=this._addPoint(l);d&&o({color:h,curve:d})}else this._reset(),i({color:h,point:a[0]})}},o.prototype._toSVG=function(){var t=this,e=this._data,o=Math.max(window.devicePixelRatio||1,1),i=this.canvas.width/o,n=this.canvas.height/o,s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width",this.canvas.width.toString()),s.setAttribute("height",this.canvas.height.toString()),this._fromData(e,function(t){var e=t.color,o=t.curve,i=document.createElement("path");if(!(isNaN(o.control1.x)||isNaN(o.control1.y)||isNaN(o.control2.x)||isNaN(o.control2.y))){var n="M "+o.startPoint.x.toFixed(3)+","+o.startPoint.y.toFixed(3)+" C "+o.control1.x.toFixed(3)+","+o.control1.y.toFixed(3)+" "+o.control2.x.toFixed(3)+","+o.control2.y.toFixed(3)+" "+o.endPoint.x.toFixed(3)+","+o.endPoint.y.toFixed(3);i.setAttribute("d",n),i.setAttribute("stroke-width",(2.25*o.endWidth).toFixed(3)),i.setAttribute("stroke",e),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),s.appendChild(i)}},function(e){var o=e.color,i=e.point,n=document.createElement("circle"),r="function"==typeof t.dotSize?t.dotSize():t.dotSize;n.setAttribute("r",r.toString()),n.setAttribute("cx",i.x.toString()),n.setAttribute("cy",i.y.toString()),n.setAttribute("fill",o),s.appendChild(n)});var r='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 '+i+" "+n+'" width="'+i+'" height="'+n+'">',h=s.innerHTML;if(void 0===h){var a=document.createElement("dummy"),c=s.childNodes;a.innerHTML="";for(var u=0;u<c.length;u+=1)a.appendChild(c[u].cloneNode(!0));h=a.innerHTML}return"data:image/svg+xml;base64,"+btoa(r+h+"</svg>")},o}()}); | ||
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.SignaturePad=e()}(this,function(){"use strict";var t=function(){function t(t,e,o){this.x=t,this.y=e,this.time=o||Date.now()}return t.prototype.distanceTo=function(t){return Math.sqrt(Math.pow(this.x-t.x,2)+Math.pow(this.y-t.y,2))},t.prototype.equals=function(t){return this.x===t.x&&this.y===t.y&&this.time===t.time},t.prototype.velocityFrom=function(t){return this.time!==t.time?this.distanceTo(t)/(this.time-t.time):0},t}(),e=function(){function e(t,e,o,i,n,s){this.startPoint=t,this.control2=e,this.control1=o,this.endPoint=i,this.startWidth=n,this.endWidth=s}return e.fromPoints=function(t,o){var i=this.calculateControlPoints(t[0],t[1],t[2]).c2,n=this.calculateControlPoints(t[1],t[2],t[3]).c1;return new e(t[1],i,n,t[2],o.start,o.end)},e.calculateControlPoints=function(e,o,i){var n=e.x-o.x,s=e.y-o.y,r=o.x-i.x,h=o.y-i.y,a=(e.x+o.x)/2,c=(e.y+o.y)/2,u=(o.x+i.x)/2,l=(o.y+i.y)/2,d=Math.sqrt(n*n+s*s),v=Math.sqrt(r*r+h*h),p=v/(d+v),f=u+(a-u)*p,_=l+(c-l)*p,y=o.x-f,m=o.y-_;return{c1:new t(a+y,c+m),c2:new t(u+y,l+m)}},e.prototype.length=function(){for(var t,e,o=0,i=0;i<=10;i+=1){var n=i/10,s=this.point(n,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),r=this.point(n,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if(i>0){var h=s-t,a=r-e;o+=Math.sqrt(h*h+a*a)}t=s,e=r}return o},e.prototype.point=function(t,e,o,i,n){return e*(1-t)*(1-t)*(1-t)+3*o*(1-t)*(1-t)*t+3*i*(1-t)*t*t+n*t*t*t},e}();return function(){function o(t,e){void 0===e&&(e={});var i=this;this.canvas=t,this.options=e,this._handleMouseDown=function(t){1===t.which&&(i._mouseButtonDown=!0,i._strokeBegin(t))},this._handleMouseMove=function(t){i._mouseButtonDown&&i._strokeMoveUpdate(t)},this._handleMouseUp=function(t){1===t.which&&i._mouseButtonDown&&(i._mouseButtonDown=!1,i._strokeEnd(t))},this._handleTouchStart=function(t){if(t.preventDefault(),1===t.targetTouches.length){var e=t.changedTouches[0];i._strokeBegin(e)}},this._handleTouchMove=function(t){t.preventDefault();var e=t.targetTouches[0];i._strokeMoveUpdate(e)},this._handleTouchEnd=function(t){if(t.target===i.canvas){t.preventDefault();var e=t.changedTouches[0];i._strokeEnd(e)}},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.throttle?this._strokeMoveUpdate=function(t,e){void 0===e&&(e=250);var o,i,n,s=0,r=null,h=function(){s=Date.now(),r=null,o=t.apply(i,n),r||(i=null,n=[])};return function(){for(var a=[],c=0;c<arguments.length;c++)a[c]=arguments[c];var u=Date.now(),l=e-(u-s);return i=this,n=a,l<=0||l>e?(r&&(clearTimeout(r),r=null),s=u,o=t.apply(i,n),r||(i=null,n=[])):r||(r=setTimeout(h,l)),o}}(o.prototype._strokeUpdate,this.throttle):this._strokeMoveUpdate=o.prototype._strokeUpdate,this.dotSize=e.dotSize||function(){return(this.minWidth+this.maxWidth)/2},this.penColor=e.penColor||"black",this.backgroundColor=e.backgroundColor||"rgba(0,0,0,0)",this.onBegin=e.onBegin,this.onEnd=e.onEnd,this._ctx=t.getContext("2d"),this.clear(),this.on()}return o.prototype.clear=function(){var t=this._ctx,e=this.canvas;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._isEmpty=!0},o.prototype.fromDataURL=function(t,e,o){var i=this;void 0===e&&(e={});var n=new Image,s=e.ratio||window.devicePixelRatio||1,r=e.width||this.canvas.width/s,h=e.height||this.canvas.height/s;this._reset(),n.onload=function(){i._ctx.drawImage(n,0,0,r,h),o&&o()},n.onerror=function(t){o&&o(t)},n.src=t,this._isEmpty=!1},o.prototype.toDataURL=function(t,e){switch(void 0===t&&(t="image/png"),t){case"image/svg+xml":return this._toSVG();default:return this.canvas.toDataURL(t,e)}},o.prototype.on=function(){this._handleMouseEvents(),"ontouchstart"in window&&this._handleTouchEvents()},o.prototype.off=function(){this.canvas.style.msTouchAction="auto",this.canvas.style.touchAction="auto",this.canvas.removeEventListener("mousedown",this._handleMouseDown),this.canvas.removeEventListener("mousemove",this._handleMouseMove),document.removeEventListener("mouseup",this._handleMouseUp),this.canvas.removeEventListener("touchstart",this._handleTouchStart),this.canvas.removeEventListener("touchmove",this._handleTouchMove),this.canvas.removeEventListener("touchend",this._handleTouchEnd)},o.prototype.isEmpty=function(){return this._isEmpty},o.prototype.fromData=function(t){var e=this;this.clear(),this._fromData(t,function(t){var o=t.color,i=t.curve;return e._drawCurve({color:o,curve:i})},function(t){var o=t.color,i=t.point;return e._drawDot({color:o,point:i})}),this._data=t},o.prototype.toData=function(){return this._data},o.prototype._strokeBegin=function(t){var e={color:this.penColor,points:[]};this._data.push(e),this._reset(),this._strokeUpdate(t),"function"==typeof this.onBegin&&this.onBegin(t)},o.prototype._strokeUpdate=function(t){var e=t.clientX,o=t.clientY,i=this._createPoint(e,o),n=this._data[this._data.length-1],s=n.points,r=s.length>0&&s[s.length-1],h=!!r&&i.distanceTo(r)<=this.minDistance,a=n.color;if(!r||!r||!h){var c=this._addPoint(i);r?c&&this._drawCurve({color:a,curve:c}):this._drawDot({color:a,point:i}),s.push({time:i.time,x:i.x,y:i.y})}},o.prototype._strokeEnd=function(t){this._strokeUpdate(t),"function"==typeof this.onEnd&&this.onEnd(t)},o.prototype._handleMouseEvents=function(){this._mouseButtonDown=!1,this.canvas.addEventListener("mousedown",this._handleMouseDown),this.canvas.addEventListener("mousemove",this._handleMouseMove),document.addEventListener("mouseup",this._handleMouseUp)},o.prototype._handleTouchEvents=function(){this.canvas.style.msTouchAction="none",this.canvas.style.touchAction="none",this.canvas.addEventListener("touchstart",this._handleTouchStart),this.canvas.addEventListener("touchmove",this._handleTouchMove),this.canvas.addEventListener("touchend",this._handleTouchEnd)},o.prototype._reset=function(){this._points=[],this._lastVelocity=0,this._lastWidth=(this.minWidth+this.maxWidth)/2,this._ctx.fillStyle=this.penColor},o.prototype._createPoint=function(e,o){var i=this.canvas.getBoundingClientRect();return new t(e-i.left,o-i.top,(new Date).getTime())},o.prototype._addPoint=function(t){var o=this._points;if(o.push(t),o.length>2){3===o.length&&o.unshift(o[0]);var i=this._calculateCurveWidths(o[1],o[2]),n=e.fromPoints(o,i);return o.shift(),n}return null},o.prototype._calculateCurveWidths=function(t,e){var o=this.velocityFilterWeight*e.velocityFrom(t)+(1-this.velocityFilterWeight)*this._lastVelocity,i=this._strokeWidth(o),n={end:i,start:this._lastWidth};return this._lastVelocity=o,this._lastWidth=i,n},o.prototype._strokeWidth=function(t){return Math.max(this.maxWidth/(t+1),this.minWidth)},o.prototype._drawCurveSegment=function(t,e,o){var i=this._ctx;i.moveTo(t,e),i.arc(t,e,o,0,2*Math.PI,!1),this._isEmpty=!1},o.prototype._drawCurve=function(t){var e=t.color,o=t.curve,i=this._ctx,n=o.endWidth-o.startWidth,s=2*Math.floor(o.length());i.beginPath(),i.fillStyle=e;for(var r=0;r<s;r+=1){var h=r/s,a=h*h,c=a*h,u=1-h,l=u*u,d=l*u,v=d*o.startPoint.x;v+=3*l*h*o.control1.x,v+=3*u*a*o.control2.x,v+=c*o.endPoint.x;var p=d*o.startPoint.y;p+=3*l*h*o.control1.y,p+=3*u*a*o.control2.y,p+=c*o.endPoint.y;var f=o.startWidth+c*n;this._drawCurveSegment(v,p,f)}i.closePath(),i.fill()},o.prototype._drawDot=function(t){var e=t.color,o=t.point,i=this._ctx,n="function"==typeof this.dotSize?this.dotSize():this.dotSize;i.beginPath(),this._drawCurveSegment(o.x,o.y,n),i.closePath(),i.fillStyle=e,i.fill()},o.prototype._fromData=function(e,o,i){for(var n=0,s=e;n<s.length;n++){var r=s[n],h=r.color,a=r.points;if(a.length>1)for(var c=0;c<a.length;c+=1){var u=a[c],l=new t(u.x,u.y,u.time);this.penColor=h,0===c&&this._reset();var d=this._addPoint(l);d&&o({color:h,curve:d})}else this._reset(),i({color:h,point:a[0]})}},o.prototype._toSVG=function(){var t=this,e=this._data,o=Math.max(window.devicePixelRatio||1,1),i=this.canvas.width/o,n=this.canvas.height/o,s=document.createElementNS("http://www.w3.org/2000/svg","svg");s.setAttribute("width",this.canvas.width.toString()),s.setAttribute("height",this.canvas.height.toString()),this._fromData(e,function(t){var e=t.color,o=t.curve,i=document.createElement("path");if(!(isNaN(o.control1.x)||isNaN(o.control1.y)||isNaN(o.control2.x)||isNaN(o.control2.y))){var n="M "+o.startPoint.x.toFixed(3)+","+o.startPoint.y.toFixed(3)+" C "+o.control1.x.toFixed(3)+","+o.control1.y.toFixed(3)+" "+o.control2.x.toFixed(3)+","+o.control2.y.toFixed(3)+" "+o.endPoint.x.toFixed(3)+","+o.endPoint.y.toFixed(3);i.setAttribute("d",n),i.setAttribute("stroke-width",(2.25*o.endWidth).toFixed(3)),i.setAttribute("stroke",e),i.setAttribute("fill","none"),i.setAttribute("stroke-linecap","round"),s.appendChild(i)}},function(e){var o=e.color,i=e.point,n=document.createElement("circle"),r="function"==typeof t.dotSize?t.dotSize():t.dotSize;n.setAttribute("r",r.toString()),n.setAttribute("cx",i.x.toString()),n.setAttribute("cy",i.y.toString()),n.setAttribute("fill",o),s.appendChild(n)});var r='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 '+i+" "+n+'" width="'+i+'" height="'+n+'">',h=s.innerHTML;if(void 0===h){var a=document.createElement("dummy"),c=s.childNodes;a.innerHTML="";for(var u=0;u<c.length;u+=1)a.appendChild(c[u].cloneNode(!0));h=a.innerHTML}return"data:image/svg+xml;base64,"+btoa(r+h+"</svg>")},o}()}); |
@@ -39,8 +39,2 @@ import { IBasicPoint } from "./point"; | ||
private _strokeMoveUpdate; | ||
private _handleMouseDown; | ||
private _handleMouseMove; | ||
private _handleMouseUp; | ||
private _handleTouchStart; | ||
private _handleTouchMove; | ||
private _handleTouchEnd; | ||
constructor(canvas: HTMLCanvasElement, options?: IOptions); | ||
@@ -52,4 +46,4 @@ clear(): void; | ||
height?: number; | ||
}): void; | ||
toDataURL(type: string, encoderOptions: number): string; | ||
}, callback?: (error?: ErrorEvent) => void): void; | ||
toDataURL(type?: string, encoderOptions?: number): string; | ||
on(): void; | ||
@@ -60,2 +54,8 @@ off(): void; | ||
toData(): IPointGroup[]; | ||
private _handleMouseDown; | ||
private _handleMouseMove; | ||
private _handleMouseUp; | ||
private _handleTouchStart; | ||
private _handleTouchMove; | ||
private _handleTouchEnd; | ||
private _strokeBegin(event); | ||
@@ -62,0 +62,0 @@ private _strokeUpdate(event); |
/*! | ||
* Signature Pad v3.0.0-beta.1 | https://github.com/szimek/signature_pad | ||
* Signature Pad v3.0.0-beta.2 | https://github.com/szimek/signature_pad | ||
* (c) 2018 Szymon Nowak | Released under the MIT license | ||
@@ -7,491 +7,502 @@ */ | ||
(function (global, factory) { | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global.SignaturePad = factory()); | ||
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
typeof define === 'function' && define.amd ? define(factory) : | ||
(global.SignaturePad = factory()); | ||
}(this, (function () { 'use strict'; | ||
var Point = (function () { | ||
function Point(x, y, time) { | ||
this.x = x; | ||
this.y = y; | ||
this.time = time || Date.now(); | ||
} | ||
Point.prototype.distanceTo = function (start) { | ||
return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2)); | ||
}; | ||
Point.prototype.equals = function (other) { | ||
return this.x === other.x && this.y === other.y && this.time === other.time; | ||
}; | ||
Point.prototype.velocityFrom = function (start) { | ||
return (this.time !== start.time) ? this.distanceTo(start) / (this.time - start.time) : 0; | ||
}; | ||
return Point; | ||
}()); | ||
var Point = (function () { | ||
function Point(x, y, time) { | ||
this.x = x; | ||
this.y = y; | ||
this.time = time || Date.now(); | ||
} | ||
Point.prototype.distanceTo = function (start) { | ||
return Math.sqrt(Math.pow(this.x - start.x, 2) + Math.pow(this.y - start.y, 2)); | ||
}; | ||
Point.prototype.equals = function (other) { | ||
return this.x === other.x && this.y === other.y && this.time === other.time; | ||
}; | ||
Point.prototype.velocityFrom = function (start) { | ||
return (this.time !== start.time) ? this.distanceTo(start) / (this.time - start.time) : 0; | ||
}; | ||
return Point; | ||
}()); | ||
var Bezier = (function () { | ||
function Bezier(startPoint, control2, control1, endPoint, startWidth, endWidth) { | ||
this.startPoint = startPoint; | ||
this.control2 = control2; | ||
this.control1 = control1; | ||
this.endPoint = endPoint; | ||
this.startWidth = startWidth; | ||
this.endWidth = endWidth; | ||
} | ||
Bezier.fromPoints = function (points, widths) { | ||
var c2 = this.calculateControlPoints(points[0], points[1], points[2]).c2; | ||
var c3 = this.calculateControlPoints(points[1], points[2], points[3]).c1; | ||
return new Bezier(points[1], c2, c3, points[2], widths.start, widths.end); | ||
}; | ||
Bezier.calculateControlPoints = function (s1, s2, s3) { | ||
var dx1 = s1.x - s2.x; | ||
var dy1 = s1.y - s2.y; | ||
var dx2 = s2.x - s3.x; | ||
var dy2 = s2.y - s3.y; | ||
var m1 = { x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0 }; | ||
var m2 = { x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.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 = s2.x - cm.x; | ||
var ty = s2.y - cm.y; | ||
return { | ||
c1: new Point(m1.x + tx, m1.y + ty), | ||
c2: new Point(m2.x + tx, m2.y + ty) | ||
}; | ||
}; | ||
Bezier.prototype.length = function () { | ||
var steps = 10; | ||
var length = 0; | ||
var px; | ||
var py; | ||
for (var i = 0; i <= steps; i += 1) { | ||
var t = i / steps; | ||
var cx = this.point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x); | ||
var cy = this.point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y); | ||
if (i > 0) { | ||
var xdiff = cx - px; | ||
var ydiff = cy - py; | ||
length += Math.sqrt((xdiff * xdiff) + (ydiff * ydiff)); | ||
} | ||
px = cx; | ||
py = cy; | ||
} | ||
return length; | ||
}; | ||
Bezier.prototype.point = function (t, start, c1, c2, end) { | ||
return (start * (1.0 - t) * (1.0 - t) * (1.0 - t)) | ||
+ (3.0 * c1 * (1.0 - t) * (1.0 - t) * t) | ||
+ (3.0 * c2 * (1.0 - t) * t * t) | ||
+ (end * t * t * t); | ||
}; | ||
return Bezier; | ||
}()); | ||
var Bezier = (function () { | ||
function Bezier(startPoint, control2, control1, endPoint, startWidth, endWidth) { | ||
this.startPoint = startPoint; | ||
this.control2 = control2; | ||
this.control1 = control1; | ||
this.endPoint = endPoint; | ||
this.startWidth = startWidth; | ||
this.endWidth = endWidth; | ||
} | ||
Bezier.fromPoints = function (points, widths) { | ||
var c2 = this.calculateControlPoints(points[0], points[1], points[2]).c2; | ||
var c3 = this.calculateControlPoints(points[1], points[2], points[3]).c1; | ||
return new Bezier(points[1], c2, c3, points[2], widths.start, widths.end); | ||
}; | ||
Bezier.calculateControlPoints = function (s1, s2, s3) { | ||
var dx1 = s1.x - s2.x; | ||
var dy1 = s1.y - s2.y; | ||
var dx2 = s2.x - s3.x; | ||
var dy2 = s2.y - s3.y; | ||
var m1 = { x: (s1.x + s2.x) / 2.0, y: (s1.y + s2.y) / 2.0 }; | ||
var m2 = { x: (s2.x + s3.x) / 2.0, y: (s2.y + s3.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 = s2.x - cm.x; | ||
var ty = s2.y - cm.y; | ||
return { | ||
c1: new Point(m1.x + tx, m1.y + ty), | ||
c2: new Point(m2.x + tx, m2.y + ty) | ||
}; | ||
}; | ||
Bezier.prototype.length = function () { | ||
var steps = 10; | ||
var length = 0; | ||
var px; | ||
var py; | ||
for (var i = 0; i <= steps; i += 1) { | ||
var t = i / steps; | ||
var cx = this.point(t, this.startPoint.x, this.control1.x, this.control2.x, this.endPoint.x); | ||
var cy = this.point(t, this.startPoint.y, this.control1.y, this.control2.y, this.endPoint.y); | ||
if (i > 0) { | ||
var xdiff = cx - px; | ||
var ydiff = cy - py; | ||
length += Math.sqrt((xdiff * xdiff) + (ydiff * ydiff)); | ||
} | ||
px = cx; | ||
py = cy; | ||
} | ||
return length; | ||
}; | ||
Bezier.prototype.point = function (t, start, c1, c2, end) { | ||
return (start * (1.0 - t) * (1.0 - t) * (1.0 - t)) | ||
+ (3.0 * c1 * (1.0 - t) * (1.0 - t) * t) | ||
+ (3.0 * c2 * (1.0 - t) * t * t) | ||
+ (end * t * t * t); | ||
}; | ||
return Bezier; | ||
}()); | ||
function throttle(fn, wait) { | ||
if (wait === void 0) { wait = 250; } | ||
var previous = 0; | ||
var timeout = null; | ||
var result; | ||
var storedContext; | ||
var storedArgs; | ||
var later = function () { | ||
previous = Date.now(); | ||
timeout = null; | ||
result = fn.apply(storedContext, storedArgs); | ||
if (!timeout) { | ||
storedContext = null; | ||
storedArgs = []; | ||
} | ||
}; | ||
return function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
var now = Date.now(); | ||
var remaining = wait - (now - previous); | ||
storedContext = this; | ||
storedArgs = args; | ||
if (remaining <= 0 || remaining > wait) { | ||
if (timeout) { | ||
clearTimeout(timeout); | ||
timeout = null; | ||
} | ||
previous = now; | ||
result = fn.apply(storedContext, storedArgs); | ||
if (!timeout) { | ||
storedContext = null; | ||
storedArgs = []; | ||
} | ||
} | ||
else if (!timeout) { | ||
timeout = setTimeout(later, remaining); | ||
} | ||
return result; | ||
}; | ||
} | ||
function throttle(fn, wait) { | ||
if (wait === void 0) { wait = 250; } | ||
var previous = 0; | ||
var timeout = null; | ||
var result; | ||
var storedContext; | ||
var storedArgs; | ||
var later = function () { | ||
previous = Date.now(); | ||
timeout = null; | ||
result = fn.apply(storedContext, storedArgs); | ||
if (!timeout) { | ||
storedContext = null; | ||
storedArgs = []; | ||
} | ||
}; | ||
return function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
var now = Date.now(); | ||
var remaining = wait - (now - previous); | ||
storedContext = this; | ||
storedArgs = args; | ||
if (remaining <= 0 || remaining > wait) { | ||
if (timeout) { | ||
clearTimeout(timeout); | ||
timeout = null; | ||
} | ||
previous = now; | ||
result = fn.apply(storedContext, storedArgs); | ||
if (!timeout) { | ||
storedContext = null; | ||
storedArgs = []; | ||
} | ||
} | ||
else if (!timeout) { | ||
timeout = setTimeout(later, remaining); | ||
} | ||
return result; | ||
}; | ||
} | ||
var SignaturePad = (function () { | ||
function SignaturePad(canvas, options) { | ||
if (options === void 0) { options = {}; } | ||
var _this = this; | ||
this.canvas = canvas; | ||
this.options = options; | ||
this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.minWidth = options.minWidth || 0.5; | ||
this.maxWidth = options.maxWidth || 2.5; | ||
this.throttle = ("throttle" in options ? options.throttle : 16); | ||
this.minDistance = ("minDistance" in options ? options.minDistance : 5); | ||
if (this.throttle) { | ||
this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle); | ||
} | ||
else { | ||
this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate; | ||
} | ||
this.dotSize = options.dotSize || function () { | ||
return (this.minWidth + this.maxWidth) / 2; | ||
}; | ||
this.penColor = options.penColor || "black"; | ||
this.backgroundColor = options.backgroundColor || "rgba(0,0,0,0)"; | ||
this.onBegin = options.onBegin; | ||
this.onEnd = options.onEnd; | ||
this._ctx = canvas.getContext("2d"); | ||
this.clear(); | ||
this._handleMouseDown = function (event) { | ||
if (event.which === 1) { | ||
_this._mouseButtonDown = true; | ||
_this._strokeBegin(event); | ||
} | ||
}; | ||
this._handleMouseMove = function (event) { | ||
if (_this._mouseButtonDown) { | ||
_this._strokeMoveUpdate(event); | ||
} | ||
}; | ||
this._handleMouseUp = function (event) { | ||
if (event.which === 1 && _this._mouseButtonDown) { | ||
_this._mouseButtonDown = false; | ||
_this._strokeEnd(event); | ||
} | ||
}; | ||
this._handleTouchStart = function (event) { | ||
event.preventDefault(); | ||
if (event.targetTouches.length === 1) { | ||
var touch = event.changedTouches[0]; | ||
_this._strokeBegin(touch); | ||
} | ||
}; | ||
this._handleTouchMove = function (event) { | ||
event.preventDefault(); | ||
var touch = event.targetTouches[0]; | ||
_this._strokeMoveUpdate(touch); | ||
}; | ||
this._handleTouchEnd = function (event) { | ||
var wasCanvasTouched = event.target === _this.canvas; | ||
if (wasCanvasTouched) { | ||
event.preventDefault(); | ||
var touch = event.targetTouches[0]; | ||
_this._strokeEnd(touch); | ||
} | ||
}; | ||
this.on(); | ||
} | ||
SignaturePad.prototype.clear = function () { | ||
var ctx = this._ctx; | ||
var canvas = this.canvas; | ||
ctx.fillStyle = this.backgroundColor; | ||
ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
ctx.fillRect(0, 0, canvas.width, canvas.height); | ||
this._data = []; | ||
this._reset(); | ||
this._isEmpty = true; | ||
}; | ||
SignaturePad.prototype.fromDataURL = function (dataUrl, options) { | ||
var _this = this; | ||
if (options === void 0) { options = {}; } | ||
var image = new Image(); | ||
var ratio = options.ratio || window.devicePixelRatio || 1; | ||
var width = options.width || (this.canvas.width / ratio); | ||
var height = options.height || (this.canvas.height / ratio); | ||
this._reset(); | ||
image.src = dataUrl; | ||
image.onload = function () { | ||
_this._ctx.drawImage(image, 0, 0, width, height); | ||
}; | ||
this._isEmpty = false; | ||
}; | ||
SignaturePad.prototype.toDataURL = function (type, encoderOptions) { | ||
switch (type) { | ||
case "image/svg+xml": | ||
return this._toSVG(); | ||
default: | ||
return this.canvas.toDataURL(type, encoderOptions); | ||
} | ||
}; | ||
SignaturePad.prototype.on = function () { | ||
this._handleMouseEvents(); | ||
this._handleTouchEvents(); | ||
}; | ||
SignaturePad.prototype.off = function () { | ||
this.canvas.style.msTouchAction = "auto"; | ||
this.canvas.style.touchAction = "auto"; | ||
this.canvas.removeEventListener("mousedown", this._handleMouseDown); | ||
this.canvas.removeEventListener("mousemove", this._handleMouseMove); | ||
document.removeEventListener("mouseup", this._handleMouseUp); | ||
this.canvas.removeEventListener("touchstart", this._handleTouchStart); | ||
this.canvas.removeEventListener("touchmove", this._handleTouchMove); | ||
this.canvas.removeEventListener("touchend", this._handleTouchEnd); | ||
}; | ||
SignaturePad.prototype.isEmpty = function () { | ||
return this._isEmpty; | ||
}; | ||
SignaturePad.prototype.fromData = function (pointGroups) { | ||
var _this = this; | ||
this.clear(); | ||
this._fromData(pointGroups, function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
return _this._drawCurve({ color: color, curve: curve }); | ||
}, function (_a) { | ||
var color = _a.color, point = _a.point; | ||
return _this._drawDot({ color: color, point: point }); | ||
}); | ||
this._data = pointGroups; | ||
}; | ||
SignaturePad.prototype.toData = function () { | ||
return this._data; | ||
}; | ||
SignaturePad.prototype._strokeBegin = function (event) { | ||
var newPointGroup = { | ||
color: this.penColor, | ||
points: [] | ||
}; | ||
this._data.push(newPointGroup); | ||
this._reset(); | ||
this._strokeUpdate(event); | ||
if (typeof this.onBegin === "function") { | ||
this.onBegin(event); | ||
} | ||
}; | ||
SignaturePad.prototype._strokeUpdate = function (event) { | ||
var x = event.clientX; | ||
var y = event.clientY; | ||
var point = this._createPoint(x, y); | ||
var lastPointGroup = this._data[this._data.length - 1]; | ||
var lastPoints = lastPointGroup.points; | ||
var lastPoint = lastPoints.length > 0 && lastPoints[lastPoints.length - 1]; | ||
var isLastPointTooClose = lastPoint ? point.distanceTo(lastPoint) <= this.minDistance : false; | ||
var color = lastPointGroup.color; | ||
if (!lastPoint || !(lastPoint && isLastPointTooClose)) { | ||
var curve = this._addPoint(point); | ||
if (!lastPoint) { | ||
this._drawDot({ color: color, point: point }); | ||
} | ||
else if (curve) { | ||
this._drawCurve({ color: color, curve: curve }); | ||
} | ||
lastPoints.push({ | ||
time: point.time, | ||
x: point.x, | ||
y: point.y | ||
}); | ||
} | ||
}; | ||
SignaturePad.prototype._strokeEnd = function (event) { | ||
this._strokeUpdate(event); | ||
if (typeof this.onEnd === "function") { | ||
this.onEnd(event); | ||
} | ||
}; | ||
SignaturePad.prototype._handleMouseEvents = function () { | ||
this._mouseButtonDown = false; | ||
this.canvas.addEventListener("mousedown", this._handleMouseDown); | ||
this.canvas.addEventListener("mousemove", this._handleMouseMove); | ||
document.addEventListener("mouseup", this._handleMouseUp); | ||
}; | ||
SignaturePad.prototype._handleTouchEvents = function () { | ||
this.canvas.style.msTouchAction = "none"; | ||
this.canvas.style.touchAction = "none"; | ||
this.canvas.addEventListener("touchstart", this._handleTouchStart); | ||
this.canvas.addEventListener("touchmove", this._handleTouchMove); | ||
this.canvas.addEventListener("touchend", this._handleTouchEnd); | ||
}; | ||
SignaturePad.prototype._reset = function () { | ||
this._points = []; | ||
this._lastVelocity = 0; | ||
this._lastWidth = (this.minWidth + this.maxWidth) / 2; | ||
this._ctx.fillStyle = this.penColor; | ||
}; | ||
SignaturePad.prototype._createPoint = function (x, y) { | ||
var rect = this.canvas.getBoundingClientRect(); | ||
return new Point(x - rect.left, y - rect.top, new Date().getTime()); | ||
}; | ||
SignaturePad.prototype._addPoint = function (point) { | ||
var _points = this._points; | ||
_points.push(point); | ||
if (_points.length > 2) { | ||
if (_points.length === 3) { | ||
_points.unshift(_points[0]); | ||
} | ||
var widths = this._calculateCurveWidths(_points[1], _points[2]); | ||
var curve = Bezier.fromPoints(_points, widths); | ||
_points.shift(); | ||
return curve; | ||
} | ||
return null; | ||
}; | ||
SignaturePad.prototype._calculateCurveWidths = function (startPoint, endPoint) { | ||
var velocity = (this.velocityFilterWeight * endPoint.velocityFrom(startPoint)) | ||
+ ((1 - this.velocityFilterWeight) * this._lastVelocity); | ||
var newWidth = this._strokeWidth(velocity); | ||
var widths = { | ||
end: newWidth, | ||
start: this._lastWidth | ||
}; | ||
this._lastVelocity = velocity; | ||
this._lastWidth = newWidth; | ||
return widths; | ||
}; | ||
SignaturePad.prototype._strokeWidth = function (velocity) { | ||
return Math.max(this.maxWidth / (velocity + 1), this.minWidth); | ||
}; | ||
SignaturePad.prototype._drawCurveSegment = function (x, y, width) { | ||
var ctx = this._ctx; | ||
ctx.moveTo(x, y); | ||
ctx.arc(x, y, width, 0, 2 * Math.PI, false); | ||
this._isEmpty = false; | ||
}; | ||
SignaturePad.prototype._drawCurve = function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
var ctx = this._ctx; | ||
var widthDelta = curve.endWidth - curve.startWidth; | ||
var drawSteps = Math.floor(curve.length()) * 2; | ||
ctx.beginPath(); | ||
ctx.fillStyle = color; | ||
for (var i = 0; i < drawSteps; i += 1) { | ||
var t = i / drawSteps; | ||
var tt = t * t; | ||
var ttt = tt * t; | ||
var u = 1 - t; | ||
var uu = u * u; | ||
var uuu = uu * u; | ||
var x = uuu * curve.startPoint.x; | ||
x += 3 * uu * t * curve.control1.x; | ||
x += 3 * u * tt * curve.control2.x; | ||
x += ttt * curve.endPoint.x; | ||
var y = uuu * curve.startPoint.y; | ||
y += 3 * uu * t * curve.control1.y; | ||
y += 3 * u * tt * curve.control2.y; | ||
y += ttt * curve.endPoint.y; | ||
var width = curve.startWidth + (ttt * widthDelta); | ||
this._drawCurveSegment(x, y, width); | ||
} | ||
ctx.closePath(); | ||
ctx.fill(); | ||
}; | ||
SignaturePad.prototype._drawDot = function (_a) { | ||
var color = _a.color, point = _a.point; | ||
var ctx = this._ctx; | ||
var width = typeof this.dotSize === "function" ? this.dotSize() : this.dotSize; | ||
ctx.beginPath(); | ||
this._drawCurveSegment(point.x, point.y, width); | ||
ctx.closePath(); | ||
ctx.fillStyle = color; | ||
ctx.fill(); | ||
}; | ||
SignaturePad.prototype._fromData = function (pointGroups, drawCurve, drawDot) { | ||
for (var _i = 0, pointGroups_1 = pointGroups; _i < pointGroups_1.length; _i++) { | ||
var group = pointGroups_1[_i]; | ||
var color = group.color, points = group.points; | ||
if (points.length > 1) { | ||
for (var j = 0; j < points.length; j += 1) { | ||
var basicPoint = points[j]; | ||
var point = new Point(basicPoint.x, basicPoint.y, basicPoint.time); | ||
this.penColor = color; | ||
if (j === 0) { | ||
this._reset(); | ||
} | ||
var curve = this._addPoint(point); | ||
if (curve) { | ||
drawCurve({ color: color, curve: curve }); | ||
} | ||
} | ||
} | ||
else { | ||
this._reset(); | ||
drawDot({ | ||
color: color, | ||
point: points[0] | ||
}); | ||
} | ||
} | ||
}; | ||
SignaturePad.prototype._toSVG = function () { | ||
var _this = this; | ||
var pointGroups = this._data; | ||
var ratio = Math.max(window.devicePixelRatio || 1, 1); | ||
var minX = 0; | ||
var minY = 0; | ||
var maxX = this.canvas.width / ratio; | ||
var maxY = this.canvas.height / ratio; | ||
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | ||
svg.setAttribute("width", this.canvas.width.toString()); | ||
svg.setAttribute("height", this.canvas.height.toString()); | ||
this._fromData(pointGroups, function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
var path = document.createElement("path"); | ||
if (!isNaN(curve.control1.x) && | ||
!isNaN(curve.control1.y) && | ||
!isNaN(curve.control2.x) && | ||
!isNaN(curve.control2.y)) { | ||
var attr = "M " + curve.startPoint.x.toFixed(3) + "," + curve.startPoint.y.toFixed(3) + " " | ||
+ ("C " + curve.control1.x.toFixed(3) + "," + curve.control1.y.toFixed(3) + " ") | ||
+ (curve.control2.x.toFixed(3) + "," + curve.control2.y.toFixed(3) + " ") | ||
+ (curve.endPoint.x.toFixed(3) + "," + curve.endPoint.y.toFixed(3)); | ||
path.setAttribute("d", attr); | ||
path.setAttribute("stroke-width", (curve.endWidth * 2.25).toFixed(3)); | ||
path.setAttribute("stroke", color); | ||
path.setAttribute("fill", "none"); | ||
path.setAttribute("stroke-linecap", "round"); | ||
svg.appendChild(path); | ||
} | ||
}, function (_a) { | ||
var color = _a.color, point = _a.point; | ||
var circle = document.createElement("circle"); | ||
var dotSize = typeof _this.dotSize === "function" ? _this.dotSize() : _this.dotSize; | ||
circle.setAttribute("r", dotSize.toString()); | ||
circle.setAttribute("cx", point.x.toString()); | ||
circle.setAttribute("cy", point.y.toString()); | ||
circle.setAttribute("fill", color); | ||
svg.appendChild(circle); | ||
}); | ||
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\"" | ||
+ (" viewBox=\"" + minX + " " + minY + " " + maxX + " " + maxY + "\"") | ||
+ (" width=\"" + maxX + "\"") | ||
+ (" height=\"" + maxY + "\"") | ||
+ ">"; | ||
var body = svg.innerHTML; | ||
if (body === undefined) { | ||
var dummy = document.createElement("dummy"); | ||
var nodes = svg.childNodes; | ||
dummy.innerHTML = ""; | ||
for (var i = 0; i < nodes.length; i += 1) { | ||
dummy.appendChild(nodes[i].cloneNode(true)); | ||
} | ||
body = dummy.innerHTML; | ||
} | ||
var footer = "</svg>"; | ||
var data = header + body + footer; | ||
return prefix + btoa(data); | ||
}; | ||
return SignaturePad; | ||
}()); | ||
var SignaturePad = (function () { | ||
function SignaturePad(canvas, options) { | ||
if (options === void 0) { options = {}; } | ||
var _this = this; | ||
this.canvas = canvas; | ||
this.options = options; | ||
this._handleMouseDown = function (event) { | ||
if (event.which === 1) { | ||
_this._mouseButtonDown = true; | ||
_this._strokeBegin(event); | ||
} | ||
}; | ||
this._handleMouseMove = function (event) { | ||
if (_this._mouseButtonDown) { | ||
_this._strokeMoveUpdate(event); | ||
} | ||
}; | ||
this._handleMouseUp = function (event) { | ||
if (event.which === 1 && _this._mouseButtonDown) { | ||
_this._mouseButtonDown = false; | ||
_this._strokeEnd(event); | ||
} | ||
}; | ||
this._handleTouchStart = function (event) { | ||
event.preventDefault(); | ||
if (event.targetTouches.length === 1) { | ||
var touch = event.changedTouches[0]; | ||
_this._strokeBegin(touch); | ||
} | ||
}; | ||
this._handleTouchMove = function (event) { | ||
event.preventDefault(); | ||
var touch = event.targetTouches[0]; | ||
_this._strokeMoveUpdate(touch); | ||
}; | ||
this._handleTouchEnd = function (event) { | ||
var wasCanvasTouched = event.target === _this.canvas; | ||
if (wasCanvasTouched) { | ||
event.preventDefault(); | ||
var touch = event.changedTouches[0]; | ||
_this._strokeEnd(touch); | ||
} | ||
}; | ||
this.velocityFilterWeight = options.velocityFilterWeight || 0.7; | ||
this.minWidth = options.minWidth || 0.5; | ||
this.maxWidth = options.maxWidth || 2.5; | ||
this.throttle = ("throttle" in options ? options.throttle : 16); | ||
this.minDistance = ("minDistance" in options ? options.minDistance : 5); | ||
if (this.throttle) { | ||
this._strokeMoveUpdate = throttle(SignaturePad.prototype._strokeUpdate, this.throttle); | ||
} | ||
else { | ||
this._strokeMoveUpdate = SignaturePad.prototype._strokeUpdate; | ||
} | ||
this.dotSize = options.dotSize || function () { | ||
return (this.minWidth + this.maxWidth) / 2; | ||
}; | ||
this.penColor = options.penColor || "black"; | ||
this.backgroundColor = options.backgroundColor || "rgba(0,0,0,0)"; | ||
this.onBegin = options.onBegin; | ||
this.onEnd = options.onEnd; | ||
this._ctx = canvas.getContext("2d"); | ||
this.clear(); | ||
this.on(); | ||
} | ||
SignaturePad.prototype.clear = function () { | ||
var ctx = this._ctx; | ||
var canvas = this.canvas; | ||
ctx.fillStyle = this.backgroundColor; | ||
ctx.clearRect(0, 0, canvas.width, canvas.height); | ||
ctx.fillRect(0, 0, canvas.width, canvas.height); | ||
this._data = []; | ||
this._reset(); | ||
this._isEmpty = true; | ||
}; | ||
SignaturePad.prototype.fromDataURL = function (dataUrl, options, callback) { | ||
var _this = this; | ||
if (options === void 0) { options = {}; } | ||
var image = new Image(); | ||
var ratio = options.ratio || window.devicePixelRatio || 1; | ||
var width = options.width || (this.canvas.width / ratio); | ||
var height = options.height || (this.canvas.height / ratio); | ||
this._reset(); | ||
image.onload = function () { | ||
_this._ctx.drawImage(image, 0, 0, width, height); | ||
if (callback) { | ||
callback(); | ||
} | ||
}; | ||
image.onerror = function (error) { | ||
if (callback) { | ||
callback(error); | ||
} | ||
}; | ||
image.src = dataUrl; | ||
this._isEmpty = false; | ||
}; | ||
SignaturePad.prototype.toDataURL = function (type, encoderOptions) { | ||
if (type === void 0) { type = "image/png"; } | ||
switch (type) { | ||
case "image/svg+xml": | ||
return this._toSVG(); | ||
default: | ||
return this.canvas.toDataURL(type, encoderOptions); | ||
} | ||
}; | ||
SignaturePad.prototype.on = function () { | ||
this._handleMouseEvents(); | ||
if ("ontouchstart" in window) { | ||
this._handleTouchEvents(); | ||
} | ||
}; | ||
SignaturePad.prototype.off = function () { | ||
this.canvas.style.msTouchAction = "auto"; | ||
this.canvas.style.touchAction = "auto"; | ||
this.canvas.removeEventListener("mousedown", this._handleMouseDown); | ||
this.canvas.removeEventListener("mousemove", this._handleMouseMove); | ||
document.removeEventListener("mouseup", this._handleMouseUp); | ||
this.canvas.removeEventListener("touchstart", this._handleTouchStart); | ||
this.canvas.removeEventListener("touchmove", this._handleTouchMove); | ||
this.canvas.removeEventListener("touchend", this._handleTouchEnd); | ||
}; | ||
SignaturePad.prototype.isEmpty = function () { | ||
return this._isEmpty; | ||
}; | ||
SignaturePad.prototype.fromData = function (pointGroups) { | ||
var _this = this; | ||
this.clear(); | ||
this._fromData(pointGroups, function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
return _this._drawCurve({ color: color, curve: curve }); | ||
}, function (_a) { | ||
var color = _a.color, point = _a.point; | ||
return _this._drawDot({ color: color, point: point }); | ||
}); | ||
this._data = pointGroups; | ||
}; | ||
SignaturePad.prototype.toData = function () { | ||
return this._data; | ||
}; | ||
SignaturePad.prototype._strokeBegin = function (event) { | ||
var newPointGroup = { | ||
color: this.penColor, | ||
points: [] | ||
}; | ||
this._data.push(newPointGroup); | ||
this._reset(); | ||
this._strokeUpdate(event); | ||
if (typeof this.onBegin === "function") { | ||
this.onBegin(event); | ||
} | ||
}; | ||
SignaturePad.prototype._strokeUpdate = function (event) { | ||
var x = event.clientX; | ||
var y = event.clientY; | ||
var point = this._createPoint(x, y); | ||
var lastPointGroup = this._data[this._data.length - 1]; | ||
var lastPoints = lastPointGroup.points; | ||
var lastPoint = lastPoints.length > 0 && lastPoints[lastPoints.length - 1]; | ||
var isLastPointTooClose = lastPoint ? point.distanceTo(lastPoint) <= this.minDistance : false; | ||
var color = lastPointGroup.color; | ||
if (!lastPoint || !(lastPoint && isLastPointTooClose)) { | ||
var curve = this._addPoint(point); | ||
if (!lastPoint) { | ||
this._drawDot({ color: color, point: point }); | ||
} | ||
else if (curve) { | ||
this._drawCurve({ color: color, curve: curve }); | ||
} | ||
lastPoints.push({ | ||
time: point.time, | ||
x: point.x, | ||
y: point.y | ||
}); | ||
} | ||
}; | ||
SignaturePad.prototype._strokeEnd = function (event) { | ||
this._strokeUpdate(event); | ||
if (typeof this.onEnd === "function") { | ||
this.onEnd(event); | ||
} | ||
}; | ||
SignaturePad.prototype._handleMouseEvents = function () { | ||
this._mouseButtonDown = false; | ||
this.canvas.addEventListener("mousedown", this._handleMouseDown); | ||
this.canvas.addEventListener("mousemove", this._handleMouseMove); | ||
document.addEventListener("mouseup", this._handleMouseUp); | ||
}; | ||
SignaturePad.prototype._handleTouchEvents = function () { | ||
this.canvas.style.msTouchAction = "none"; | ||
this.canvas.style.touchAction = "none"; | ||
this.canvas.addEventListener("touchstart", this._handleTouchStart); | ||
this.canvas.addEventListener("touchmove", this._handleTouchMove); | ||
this.canvas.addEventListener("touchend", this._handleTouchEnd); | ||
}; | ||
SignaturePad.prototype._reset = function () { | ||
this._points = []; | ||
this._lastVelocity = 0; | ||
this._lastWidth = (this.minWidth + this.maxWidth) / 2; | ||
this._ctx.fillStyle = this.penColor; | ||
}; | ||
SignaturePad.prototype._createPoint = function (x, y) { | ||
var rect = this.canvas.getBoundingClientRect(); | ||
return new Point(x - rect.left, y - rect.top, new Date().getTime()); | ||
}; | ||
SignaturePad.prototype._addPoint = function (point) { | ||
var _points = this._points; | ||
_points.push(point); | ||
if (_points.length > 2) { | ||
if (_points.length === 3) { | ||
_points.unshift(_points[0]); | ||
} | ||
var widths = this._calculateCurveWidths(_points[1], _points[2]); | ||
var curve = Bezier.fromPoints(_points, widths); | ||
_points.shift(); | ||
return curve; | ||
} | ||
return null; | ||
}; | ||
SignaturePad.prototype._calculateCurveWidths = function (startPoint, endPoint) { | ||
var velocity = (this.velocityFilterWeight * endPoint.velocityFrom(startPoint)) | ||
+ ((1 - this.velocityFilterWeight) * this._lastVelocity); | ||
var newWidth = this._strokeWidth(velocity); | ||
var widths = { | ||
end: newWidth, | ||
start: this._lastWidth | ||
}; | ||
this._lastVelocity = velocity; | ||
this._lastWidth = newWidth; | ||
return widths; | ||
}; | ||
SignaturePad.prototype._strokeWidth = function (velocity) { | ||
return Math.max(this.maxWidth / (velocity + 1), this.minWidth); | ||
}; | ||
SignaturePad.prototype._drawCurveSegment = function (x, y, width) { | ||
var ctx = this._ctx; | ||
ctx.moveTo(x, y); | ||
ctx.arc(x, y, width, 0, 2 * Math.PI, false); | ||
this._isEmpty = false; | ||
}; | ||
SignaturePad.prototype._drawCurve = function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
var ctx = this._ctx; | ||
var widthDelta = curve.endWidth - curve.startWidth; | ||
var drawSteps = Math.floor(curve.length()) * 2; | ||
ctx.beginPath(); | ||
ctx.fillStyle = color; | ||
for (var i = 0; i < drawSteps; i += 1) { | ||
var t = i / drawSteps; | ||
var tt = t * t; | ||
var ttt = tt * t; | ||
var u = 1 - t; | ||
var uu = u * u; | ||
var uuu = uu * u; | ||
var x = uuu * curve.startPoint.x; | ||
x += 3 * uu * t * curve.control1.x; | ||
x += 3 * u * tt * curve.control2.x; | ||
x += ttt * curve.endPoint.x; | ||
var y = uuu * curve.startPoint.y; | ||
y += 3 * uu * t * curve.control1.y; | ||
y += 3 * u * tt * curve.control2.y; | ||
y += ttt * curve.endPoint.y; | ||
var width = curve.startWidth + (ttt * widthDelta); | ||
this._drawCurveSegment(x, y, width); | ||
} | ||
ctx.closePath(); | ||
ctx.fill(); | ||
}; | ||
SignaturePad.prototype._drawDot = function (_a) { | ||
var color = _a.color, point = _a.point; | ||
var ctx = this._ctx; | ||
var width = typeof this.dotSize === "function" ? this.dotSize() : this.dotSize; | ||
ctx.beginPath(); | ||
this._drawCurveSegment(point.x, point.y, width); | ||
ctx.closePath(); | ||
ctx.fillStyle = color; | ||
ctx.fill(); | ||
}; | ||
SignaturePad.prototype._fromData = function (pointGroups, drawCurve, drawDot) { | ||
for (var _i = 0, pointGroups_1 = pointGroups; _i < pointGroups_1.length; _i++) { | ||
var group = pointGroups_1[_i]; | ||
var color = group.color, points = group.points; | ||
if (points.length > 1) { | ||
for (var j = 0; j < points.length; j += 1) { | ||
var basicPoint = points[j]; | ||
var point = new Point(basicPoint.x, basicPoint.y, basicPoint.time); | ||
this.penColor = color; | ||
if (j === 0) { | ||
this._reset(); | ||
} | ||
var curve = this._addPoint(point); | ||
if (curve) { | ||
drawCurve({ color: color, curve: curve }); | ||
} | ||
} | ||
} | ||
else { | ||
this._reset(); | ||
drawDot({ | ||
color: color, | ||
point: points[0] | ||
}); | ||
} | ||
} | ||
}; | ||
SignaturePad.prototype._toSVG = function () { | ||
var _this = this; | ||
var pointGroups = this._data; | ||
var ratio = Math.max(window.devicePixelRatio || 1, 1); | ||
var minX = 0; | ||
var minY = 0; | ||
var maxX = this.canvas.width / ratio; | ||
var maxY = this.canvas.height / ratio; | ||
var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); | ||
svg.setAttribute("width", this.canvas.width.toString()); | ||
svg.setAttribute("height", this.canvas.height.toString()); | ||
this._fromData(pointGroups, function (_a) { | ||
var color = _a.color, curve = _a.curve; | ||
var path = document.createElement("path"); | ||
if (!isNaN(curve.control1.x) && | ||
!isNaN(curve.control1.y) && | ||
!isNaN(curve.control2.x) && | ||
!isNaN(curve.control2.y)) { | ||
var attr = "M " + curve.startPoint.x.toFixed(3) + "," + curve.startPoint.y.toFixed(3) + " " | ||
+ ("C " + curve.control1.x.toFixed(3) + "," + curve.control1.y.toFixed(3) + " ") | ||
+ (curve.control2.x.toFixed(3) + "," + curve.control2.y.toFixed(3) + " ") | ||
+ (curve.endPoint.x.toFixed(3) + "," + curve.endPoint.y.toFixed(3)); | ||
path.setAttribute("d", attr); | ||
path.setAttribute("stroke-width", (curve.endWidth * 2.25).toFixed(3)); | ||
path.setAttribute("stroke", color); | ||
path.setAttribute("fill", "none"); | ||
path.setAttribute("stroke-linecap", "round"); | ||
svg.appendChild(path); | ||
} | ||
}, function (_a) { | ||
var color = _a.color, point = _a.point; | ||
var circle = document.createElement("circle"); | ||
var dotSize = typeof _this.dotSize === "function" ? _this.dotSize() : _this.dotSize; | ||
circle.setAttribute("r", dotSize.toString()); | ||
circle.setAttribute("cx", point.x.toString()); | ||
circle.setAttribute("cy", point.y.toString()); | ||
circle.setAttribute("fill", color); | ||
svg.appendChild(circle); | ||
}); | ||
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\"" | ||
+ (" viewBox=\"" + minX + " " + minY + " " + maxX + " " + maxY + "\"") | ||
+ (" width=\"" + maxX + "\"") | ||
+ (" height=\"" + maxY + "\"") | ||
+ ">"; | ||
var body = svg.innerHTML; | ||
if (body === undefined) { | ||
var dummy = document.createElement("dummy"); | ||
var nodes = svg.childNodes; | ||
dummy.innerHTML = ""; | ||
for (var i = 0; i < nodes.length; i += 1) { | ||
dummy.appendChild(nodes[i].cloneNode(true)); | ||
} | ||
body = dummy.innerHTML; | ||
} | ||
var footer = "</svg>"; | ||
var data = header + body + footer; | ||
return prefix + btoa(data); | ||
}; | ||
return SignaturePad; | ||
}()); | ||
return SignaturePad; | ||
return SignaturePad; | ||
}))); |
{ | ||
"name": "signature_pad", | ||
"description": "Library for drawing smooth signatures.", | ||
"version": "3.0.0-beta.1", | ||
"version": "3.0.0-beta.2", | ||
"homepage": "https://github.com/szimek/signature_pad", | ||
@@ -33,25 +33,29 @@ "author": { | ||
"devDependencies": { | ||
"@types/jest": "^22.2.3", | ||
"canvas-prebuilt": "^1.6.5-prerelease.1", | ||
"del": "^3.0.0", | ||
"del-cli": "^1.1.0", | ||
"rollup": "^0.56.5", | ||
"jest": "^22.4.3", | ||
"rollup": "^0.57.1", | ||
"rollup-plugin-tslint": "^0.1.34", | ||
"rollup-plugin-typescript2": "^0.12.0", | ||
"rollup-plugin-typescript2": "^0.13.0", | ||
"rollup-plugin-uglify": "^3.0.0", | ||
"typescript": "^2.7.2", | ||
"@types/jest": "22.2.0", | ||
"jest": "22.4.2", | ||
"ts-jest": "22.4.1" | ||
"ts-jest": "^22.4.2", | ||
"typescript": "^2.8.1" | ||
}, | ||
"jest": { | ||
"transform": { | ||
"^.+\\.tsx?$": "ts-jest" | ||
"moduleFileExtensions": [ | ||
"ts", | ||
"js" | ||
], | ||
"testEnvironmentOptions": { | ||
"resources": "usable" | ||
}, | ||
"testMatch": [ | ||
"<rootDir>/tests/**/*.ts" | ||
"<rootDir>/tests/**/*.test.ts" | ||
], | ||
"moduleFileExtensions": [ | ||
"ts", | ||
"js" | ||
] | ||
"transform": { | ||
"^.+\\.tsx?$": "ts-jest" | ||
} | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
# Signature Pad [![npm](https://badge.fury.io/js/signature_pad.svg)](https://www.npmjs.com/package/signature_pad) [![Code Climate](https://codeclimate.com/github/szimek/signature_pad.png)](https://codeclimate.com/github/szimek/signature_pad) | ||
# Signature Pad [![npm](https://badge.fury.io/js/signature_pad.svg)](https://www.npmjs.com/package/signature_pad) [![Build Status](https://travis-ci.org/szimek/signature_pad.svg?branch=master)](https://travis-ci.org/szimek/signature_pad) [![Code Climate](https://codeclimate.com/github/szimek/signature_pad.png)](https://codeclimate.com/github/szimek/signature_pad) | ||
@@ -3,0 +3,0 @@ Signature Pad is a JavaScript library for drawing smooth signatures. It's HTML5 canvas based and uses variable width Bézier curve interpolation based on [Smoother Signatures](http://corner.squareup.com/2012/07/smoother-signatures.html) post by [Square](https://squareup.com). |
@@ -57,8 +57,2 @@ /** | ||
private _strokeMoveUpdate: (event: MouseEvent | Touch) => void; | ||
private _handleMouseDown: (event: MouseEvent) => void; | ||
private _handleMouseMove: (event: MouseEvent) => void; | ||
private _handleMouseUp: (event: MouseEvent) => void; | ||
private _handleTouchStart: (event: TouchEvent) => void; | ||
private _handleTouchMove: (event: TouchEvent) => void; | ||
private _handleTouchEnd: (event: TouchEvent) => void; | ||
/* tslint:enable: variable-name */ | ||
@@ -90,52 +84,2 @@ | ||
// We need add these inline so they are available to unbind while still having | ||
// access to 'this'. | ||
this._handleMouseDown = (event: MouseEvent) => { | ||
if (event.which === 1) { | ||
this._mouseButtonDown = true; | ||
this._strokeBegin(event); | ||
} | ||
}; | ||
this._handleMouseMove = (event) => { | ||
if (this._mouseButtonDown) { | ||
this._strokeMoveUpdate(event); | ||
} | ||
}; | ||
this._handleMouseUp = (event) => { | ||
if (event.which === 1 && this._mouseButtonDown) { | ||
this._mouseButtonDown = false; | ||
this._strokeEnd(event); | ||
} | ||
}; | ||
this._handleTouchStart = (event) => { | ||
// Prevent scrolling. | ||
event.preventDefault(); | ||
if (event.targetTouches.length === 1) { | ||
const touch = event.changedTouches[0]; | ||
this._strokeBegin(touch); | ||
} | ||
}; | ||
this._handleTouchMove = (event) => { | ||
// Prevent scrolling. | ||
event.preventDefault(); | ||
const touch = event.targetTouches[0]; | ||
this._strokeMoveUpdate(touch); | ||
}; | ||
this._handleTouchEnd = (event) => { | ||
const wasCanvasTouched = event.target === this.canvas; | ||
if (wasCanvasTouched) { | ||
event.preventDefault(); | ||
const touch = event.targetTouches[0]; | ||
this._strokeEnd(touch); | ||
} | ||
}; | ||
// Enable mouse and touch event handlers | ||
@@ -159,3 +103,7 @@ this.on(); | ||
public fromDataURL(dataUrl: string, options: { ratio?: number, width?: number, height?: number } = {}): void { | ||
public fromDataURL( | ||
dataUrl: string, | ||
options: { ratio?: number, width?: number, height?: number } = {}, | ||
callback?: (error?: ErrorEvent) => void, | ||
): void { | ||
const image = new Image(); | ||
@@ -167,10 +115,16 @@ const ratio = options.ratio || window.devicePixelRatio || 1; | ||
this._reset(); | ||
image.src = dataUrl; | ||
image.onload = () => { | ||
this._ctx.drawImage(image, 0, 0, width, height); | ||
if (callback) { callback(); } | ||
}; | ||
image.onerror = (error) => { | ||
if (callback) { callback(error); } | ||
}; | ||
image.src = dataUrl; | ||
this._isEmpty = false; | ||
} | ||
public toDataURL(type: string, encoderOptions: number) { | ||
public toDataURL(type = "image/png", encoderOptions?: number) { | ||
switch (type) { | ||
@@ -186,3 +140,6 @@ case "image/svg+xml": | ||
this._handleMouseEvents(); | ||
this._handleTouchEvents(); | ||
if ("ontouchstart" in window) { | ||
this._handleTouchEvents(); | ||
} | ||
} | ||
@@ -199,4 +156,8 @@ | ||
// TS 2.8.1 has incorrect type definition for touch event handlers | ||
// @ts-ignore | ||
this.canvas.removeEventListener("touchstart", this._handleTouchStart); | ||
// @ts-ignore | ||
this.canvas.removeEventListener("touchmove", this._handleTouchMove); | ||
// @ts-ignore | ||
this.canvas.removeEventListener("touchend", this._handleTouchEnd); | ||
@@ -225,2 +186,51 @@ } | ||
// Event handlers | ||
private _handleMouseDown = (event: MouseEvent): void => { | ||
if (event.which === 1) { | ||
this._mouseButtonDown = true; | ||
this._strokeBegin(event); | ||
} | ||
} | ||
private _handleMouseMove = (event: MouseEvent): void => { | ||
if (this._mouseButtonDown) { | ||
this._strokeMoveUpdate(event); | ||
} | ||
} | ||
private _handleMouseUp = (event: MouseEvent): void => { | ||
if (event.which === 1 && this._mouseButtonDown) { | ||
this._mouseButtonDown = false; | ||
this._strokeEnd(event); | ||
} | ||
} | ||
private _handleTouchStart = (event: TouchEvent): void => { | ||
// Prevent scrolling. | ||
event.preventDefault(); | ||
if (event.targetTouches.length === 1) { | ||
const touch = event.changedTouches[0]; | ||
this._strokeBegin(touch); | ||
} | ||
} | ||
private _handleTouchMove = (event: TouchEvent): void => { | ||
// Prevent scrolling. | ||
event.preventDefault(); | ||
const touch = event.targetTouches[0]; | ||
this._strokeMoveUpdate(touch); | ||
} | ||
private _handleTouchEnd = (event: TouchEvent): void => { | ||
const wasCanvasTouched = event.target === this.canvas; | ||
if (wasCanvasTouched) { | ||
event.preventDefault(); | ||
const touch = event.changedTouches[0]; | ||
this._strokeEnd(touch); | ||
} | ||
} | ||
// Private methods | ||
@@ -292,4 +302,8 @@ private _strokeBegin(event: MouseEvent | Touch): void { | ||
// TS 2.8.1 has incorrect type definition for touch event handlers | ||
// @ts-ignore | ||
this.canvas.addEventListener("touchstart", this._handleTouchStart); | ||
// @ts-ignore | ||
this.canvas.addEventListener("touchmove", this._handleTouchMove); | ||
// @ts-ignore | ||
this.canvas.addEventListener("touchend", this._handleTouchEnd); | ||
@@ -296,0 +310,0 @@ } |
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
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
165997
23
3027
0
11