vue3-electronic-signature
Version:
一个基于Vue3的电子签名组件库,支持手写签名、触摸绘制和多种导出格式
2 lines (1 loc) • 38.6 kB
JavaScript
(function(v,u){typeof exports=="object"&&typeof module<"u"?u(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],u):(v=typeof globalThis<"u"?globalThis:v||self,u(v.Vue3ElectronicSignature={},v.Vue))})(this,function(v,u){"use strict";var qt=Object.defineProperty;var zt=(v,u,O)=>u in v?qt(v,u,{enumerable:!0,configurable:!0,writable:!0,value:O}):v[u]=O;var M=(v,u,O)=>(zt(v,typeof u!="symbol"?u+"":u,O),O);function O(r,e){return Math.sqrt(Math.pow(e.x-r.x,2)+Math.pow(e.y-r.y,2))}function oe(r,e){return Math.atan2(e.y-r.y,e.x-r.x)}function se(r,e,o,a){const s=e||r,i=o||r,h=.2,c=oe(s,i)*(a?1:-1),l=O(s,i)*h;return{x:r.x+Math.cos(c)*l,y:r.y+Math.sin(c)*l,time:r.time}}function ie(r,e,o){if(!o.pressure.enabled)return o.strokeWidth;const a=O(r,e),s=e.time-r.time,i=s>0?a/s:0,h=Math.max(.1,Math.min(1,1-i*.01)),{min:c,max:l}=o.pressure;return c+(l-c)*h}function qe(r,e,o){if(e.length<2)return;if(r.strokeStyle=o.strokeColor,r.lineCap="round",r.lineJoin="round",!o.smoothing||e.length<3){r.beginPath(),r.lineWidth=o.strokeWidth,r.moveTo(e[0].x,e[0].y);for(let s=1;s<e.length;s++)r.lineTo(e[s].x,e[s].y);r.stroke();return}r.beginPath(),r.moveTo(e[0].x,e[0].y);for(let s=1;s<e.length-1;s++){const i=e[s],h=e[s+1];o.pressure.enabled?r.lineWidth=ie(e[s-1],i,o):r.lineWidth=o.strokeWidth;const c=se(i,e[s-1],h);r.quadraticCurveTo(c.x,c.y,i.x,i.y)}const a=e[e.length-1];r.lineTo(a.x,a.y),r.stroke()}function re(r){const{canvasSize:e,paths:o}=r;let a=`<svg width="${e.width}" height="${e.height}" xmlns="http://www.w3.org/2000/svg">`;return o.forEach(s=>{if(s.points.length<2)return;let i=`M ${s.points[0].x} ${s.points[0].y}`;for(let h=1;h<s.points.length;h++)i+=` L ${s.points[h].x} ${s.points[h].y}`;a+=`<path d="${i}" stroke="${s.strokeColor}" stroke-width="${s.strokeWidth}" fill="none" stroke-linecap="round" stroke-linejoin="round"/>`}),a+="</svg>",a}function le(r,e,o={format:"png"}){const{format:a,quality:s=.9,size:i,backgroundColor:h}=o;if(a==="svg")return re(e);const c=document.createElement("canvas"),l=c.getContext("2d");if(i){c.width=i.width,c.height=i.height;const d=i.width/r.width,f=i.height/r.height;l.scale(d,f)}else c.width=r.width,c.height=r.height;switch(h&&h!=="transparent"&&(l.fillStyle=h,l.fillRect(0,0,c.width,c.height)),l.drawImage(r,0,0),a){case"jpeg":return c.toDataURL("image/jpeg",s);case"base64":return c.toDataURL("image/png").split(",")[1];case"png":default:return c.toDataURL("image/png")}}function ce(r,e){return new Promise((o,a)=>{const s=new Image;s.onload=()=>{const i=r.getContext("2d");i.clearRect(0,0,r.width,r.height),i.drawImage(s,0,0,r.width,r.height),o()},s.onerror=a,s.src=e})}function J(r){return r.paths.length===0||r.paths.every(e=>e.points.length===0)}function q(r,e){return{paths:[],canvasSize:{width:r,height:e},timestamp:Date.now(),isEmpty:!0}}function A(r){return JSON.parse(JSON.stringify(r))}class he{constructor(e){M(this,"canvas");M(this,"ctx");M(this,"replayData",null);M(this,"state","idle");M(this,"currentTime",0);M(this,"speed",1);M(this,"animationId",null);M(this,"startTimestamp",0);M(this,"pausedTime",0);M(this,"options",{});M(this,"eventCallbacks",new Map);M(this,"offscreenCanvas",null);M(this,"offscreenCtx",null);M(this,"lastFrameImageBitmap",null);M(this,"renderThrottle",0);M(this,"isRendering",!1);M(this,"seededRandom");this.canvas=e,this.ctx=e.getContext("2d"),this.initializeOffscreenCanvas(),this.seededRandom=this.createSeededRandom()}createSeededRandom(){return e=>{const s=Math.pow(2,32);return(1664525*e+1013904223)%s/s}}initializeOffscreenCanvas(){try{if(typeof OffscreenCanvas<"u"?(this.offscreenCanvas=new OffscreenCanvas(this.canvas.width,this.canvas.height),this.offscreenCtx=this.offscreenCanvas.getContext("2d")):(this.offscreenCanvas=document.createElement("canvas"),this.offscreenCanvas.width=this.canvas.width,this.offscreenCanvas.height=this.canvas.height,this.offscreenCtx=this.offscreenCanvas.getContext("2d")),this.offscreenCtx){this.offscreenCtx.imageSmoothingEnabled=!0,this.offscreenCtx.imageSmoothingQuality="high";try{this.offscreenCtx.textRenderingOptimization="optimizeSpeed"}catch{}}}catch(e){console.warn("Failed to initialize optimized offscreen canvas:",e),this.offscreenCanvas=document.createElement("canvas"),this.offscreenCanvas.width=this.canvas.width,this.offscreenCanvas.height=this.canvas.height,this.offscreenCtx=this.offscreenCanvas.getContext("2d")}}setReplayData(e,o={}){console.log("设置回放数据:",e),console.log("回放选项:",o),this.replayData=e,this.options={...o},this.speed=o.speed||e.speed||1,this.currentTime=o.startTime||0,this.state="idle",this.resetOptimizationState(),console.log("回放数据设置完成,路径数量:",e.paths.length),console.log("总时长:",e.totalDuration)}resetOptimizationState(){this.offscreenCanvas&&(this.offscreenCanvas.width=this.canvas.width,this.offscreenCanvas.height=this.canvas.height)}play(){if(console.log("播放方法调用,回放数据:",this.replayData),console.log("当前状态:",this.state),!this.replayData){console.error("没有回放数据,无法播放");return}if(this.replayData.totalDuration<=0){console.error("回放数据总时长为0,无法播放");return}if(this.replayData.paths.length===0){console.error("回放数据没有路径,无法播放");return}if(this.state==="playing"){console.log("已在播放中,忽略");return}this.state==="paused"?(console.log("从暂停状态恢复播放"),this.state="playing",this.startTimestamp=performance.now()-this.pausedTime,this.emit("replay-resume")):(console.log("开始新的播放"),this.state="playing",this.startTimestamp=performance.now(),this.pausedTime=0,this.currentTime=this.options.startTime||0,this.clearCanvas(),this.emit("replay-start")),this.animate()}pause(){this.state==="playing"&&(this.state="paused",this.pausedTime=performance.now()-this.startTimestamp,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.emit("replay-pause"))}stop(){this.state="stopped",this.currentTime=0,this.pausedTime=0,this.animationId&&(cancelAnimationFrame(this.animationId),this.animationId=null),this.clearCanvas(),this.emit("replay-stop")}seek(e){if(!this.replayData)return;const o=this.options.endTime||this.replayData.totalDuration;this.currentTime=Math.max(0,Math.min(e,o)),this.state==="playing"?this.startTimestamp=performance.now()-this.currentTime/this.speed:this.pausedTime=this.currentTime/this.speed,this.renderFrame(this.currentTime)}setSpeed(e){const o=this.state==="playing";o&&this.pause(),this.speed=Math.max(.1,Math.min(5,e)),this.emit("replay-speed-change",this.speed),o&&this.play()}getState(){return this.state}getCurrentTime(){return this.currentTime}getTotalDuration(){var e;return((e=this.replayData)==null?void 0:e.totalDuration)||0}getProgress(){const e=this.getTotalDuration();return e>0?this.currentTime/e:0}animate(){if(this.state!=="playing"||!this.replayData)return;const e=performance.now();this.currentTime=(e-this.startTimestamp)*this.speed;const o=this.options.endTime||this.replayData.totalDuration;if(this.currentTime>=o){this.currentTime=o,this.state="completed",this.renderFrame(this.currentTime),this.emit("replay-complete"),this.options.loop&&setTimeout(()=>{this.currentTime=this.options.startTime||0,this.play()},500);return}this.renderFrame(this.currentTime),this.emit("replay-progress",this.getProgress(),this.currentTime),this.animationId=requestAnimationFrame(()=>this.animate())}renderFrame(e){if(!this.replayData||!this.offscreenCanvas||!this.offscreenCtx)return;const o=performance.now();if(!(o-this.renderThrottle<16)&&(this.renderThrottle=o,!this.isRendering)){this.isRendering=!0;try{this.renderToOffscreenCanvas(e),this.transferToMainCanvasSync()}finally{this.isRendering=!1}}}transferToMainCanvasSync(){if(this.offscreenCanvas)try{this.ctx.imageSmoothingEnabled=!1,this.ctx.globalCompositeOperation="copy",this.ctx.drawImage(this.offscreenCanvas,0,0),this.ctx.globalCompositeOperation="source-over",this.ctx.imageSmoothingEnabled=!0}catch{this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.drawImage(this.offscreenCanvas,0,0)}}renderToOffscreenCanvas(e){if(!this.replayData||!this.offscreenCtx)return;const o=this.offscreenCanvas,a=this.offscreenCtx;a.globalCompositeOperation="copy",a.fillStyle="transparent",a.fillRect(0,0,o.width,o.height),a.globalCompositeOperation="source-over";let s=!1;for(let i=0;i<this.replayData.paths.length;i++){const h=this.replayData.paths[i],c=h.startTime||0,l=h.endTime||c+(h.duration||0);if(e<c)break;if(e>=l){this.drawCompletePathToOffscreen(h),!s&&Math.abs(e-l)<32&&this.emit("replay-path-end",i,h);continue}s=!0;const d=Math.max(0,Math.min(1,(e-c)/Math.max(l-c,1)));d>0&&Math.abs(e-c)<32&&this.emit("replay-path-start",i,h),this.drawPartialPathToOffscreen(h,d);break}}getPointsUpToTime(e,o,a){const s=[];for(let i=0;i<e.length;i++){const h=e[i],c=o+(h.relativeTime||i*50);if(c<=a)s.push(h);else{if(i>0){const l=e[i-1],d=o+(l.relativeTime||(i-1)*50);if(d<=a){const f=(a-d)/(c-d),C={x:l.x+(h.x-l.x)*f,y:l.y+(h.y-l.y)*f,time:a,pressure:l.pressure?l.pressure+(h.pressure||l.pressure-l.pressure)*f:h.pressure};s.push(C)}}break}}return s}calculateDynamicStrokeWidth(e,o,a,s){switch(a){case"pen":return 1;case"brush":if(o){const p=Math.sqrt(Math.pow(e.x-o.x,2)+Math.pow(e.y-o.y,2)),w=Math.max(1,(e.time||0)-(o.time||0)),T=p/w,W=Math.max(.1,Math.min(3,100/Math.max(T,1))),R=e.pressure||.5,S=Math.floor(e.x*1e3+e.y*1e3+(e.time||0)),P=.8+this.seededRandom(S)*.4;return Math.max(1,Math.min(20,s*W*(.3+R*1.4)*P))}return s;case"marker":return 12;case"pencil":const i=e.pressure||.5,h=Math.floor(e.x*1e3+e.y*1e3+(e.time||0)),c=.9+this.seededRandom(h+1)*.2;return s*(.7+i*.6)*c;case"ballpoint":const l=e.pressure||.5;return s*(.8+l*.4);case"elegant":const d=e.pressure||.5;let f=1;if(o){const p=Math.sqrt(Math.pow(e.x-o.x,2)+Math.pow(e.y-o.y,2)),w=Math.max(1,(e.time||0)-(o.time||0)),T=p/w;f=Math.max(.3,Math.min(2,50/Math.max(T,1)))}const C=d*f;return s*(.4+C*1.6);default:return s}}drawStyledStrokeForReplay(e,o,a,s){if(!(e.length<2))switch(this.ctx.strokeStyle=a,o){case"pen":if(this.ctx.lineWidth=1,this.ctx.lineCap="butt",this.ctx.lineJoin="miter",this.ctx.beginPath(),this.ctx.moveTo(e[0].x,e[0].y),e.length>=3){for(let i=1;i<e.length-1;i++){const h=this.getControlPoint(e[i],e[i-1],e[i+1]);this.ctx.quadraticCurveTo(h.x,h.y,e[i].x,e[i].y)}this.ctx.lineTo(e[e.length-1].x,e[e.length-1].y)}else for(let i=1;i<e.length;i++)this.ctx.lineTo(e[i].x,e[i].y);this.ctx.stroke();break;case"brush":this.ctx.lineCap="round",this.ctx.lineJoin="round";for(let i=1;i<e.length;i++){const h=e[i],c=e[i-1],l=this.calculateDynamicStrokeWidth(h,c,o,s);this.ctx.lineWidth=l,this.ctx.beginPath(),this.ctx.moveTo(c.x,c.y),this.ctx.lineTo(h.x,h.y),this.ctx.stroke();const d=Math.floor(h.x*100+h.y*100+i);l>8&&this.seededRandom(d)>.6&&(this.ctx.globalAlpha=.2,this.ctx.beginPath(),this.ctx.arc(h.x,h.y,l*.3,0,Math.PI*2),this.ctx.fill(),this.ctx.globalAlpha=1)}break;case"marker":this.ctx.globalAlpha=.7,this.ctx.lineWidth=12,this.ctx.lineCap="square",this.ctx.lineJoin="bevel",this.ctx.beginPath(),this.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<e.length;i++)this.ctx.lineTo(e[i].x,e[i].y);this.ctx.stroke(),this.ctx.globalAlpha=.3,this.ctx.lineWidth=16,this.ctx.beginPath(),this.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<e.length;i++)this.ctx.lineTo(e[i].x,e[i].y);this.ctx.stroke(),this.ctx.globalAlpha=1;break;case"pencil":this.ctx.lineCap="round",this.ctx.lineJoin="round";for(let i=1;i<e.length;i++){const h=e[i],c=e[i-1],l=this.calculateDynamicStrokeWidth(h,c,o,s);this.ctx.lineWidth=l,this.ctx.globalAlpha=.8,this.ctx.beginPath(),this.ctx.moveTo(c.x,c.y),this.ctx.lineTo(h.x,h.y),this.ctx.stroke();for(let f=0;f<3;f++){const C=Math.floor(h.x*10+h.y*10+i*10+f);if(this.seededRandom(C)>.5){this.ctx.globalAlpha=.2,this.ctx.lineWidth=l*.3;const p=(this.seededRandom(C+1)-.5)*2,w=(this.seededRandom(C+2)-.5)*2;this.ctx.beginPath(),this.ctx.moveTo(c.x+p,c.y+w),this.ctx.lineTo(h.x+p,h.y+w),this.ctx.stroke()}}const d=Math.floor(h.x*5+h.y*5+i*5);if(this.seededRandom(d)>.8){this.ctx.globalAlpha=.4;for(let f=0;f<5;f++){const C=d+f*10;this.ctx.beginPath(),this.ctx.arc(h.x+(this.seededRandom(C+1)-.5)*3,h.y+(this.seededRandom(C+2)-.5)*3,this.seededRandom(C+3)*.8,0,Math.PI*2),this.ctx.fill()}}}this.ctx.globalAlpha=1;break;case"ballpoint":this.ctx.lineCap="round",this.ctx.lineJoin="round";for(let i=1;i<e.length;i++){const h=e[i],c=e[i-1],l=this.calculateDynamicStrokeWidth(h,c,o,s);if(this.ctx.lineWidth=l,this.ctx.globalAlpha=1,this.ctx.beginPath(),i<e.length-1){const d=e[i+1],f=this.getControlPoint(h,c,d);this.ctx.moveTo(c.x,c.y),this.ctx.quadraticCurveTo(f.x,f.y,h.x,h.y)}else this.ctx.moveTo(c.x,c.y),this.ctx.lineTo(h.x,h.y);this.ctx.stroke()}this.ctx.globalAlpha=1;break;case"elegant":this.drawElegantStroke(e,a,s);break}}drawElegantStroke(e,o,a){if(e.length<2)return;this.ctx.strokeStyle=o,this.ctx.fillStyle=o,this.ctx.lineCap="round",this.ctx.lineJoin="round",this.ctx.globalCompositeOperation="source-over";const s=this.preprocessPointsForVelocity(e,a);this.drawVelocityBasedPath(s)}preprocessPointsForVelocity(e,o){const a=[];for(let s=0;s<e.length;s++){const i=e[s];let h=0,c=o;if(s>0){const d=e[s-1],f=Math.sqrt(Math.pow(i.x-d.x,2)+Math.pow(i.y-d.y,2)),C=Math.max(1,(i.time||0)-(d.time||0));h=f/C;const p=i.pressure||.5,w=Math.max(.1,Math.min(5,150/Math.max(h,1)));c=o*(.2+p*w*2)}let l=c;if(s>0){const d=a[s-1].smoothedWidth;l=d+(c-d)*.5}a.push({...i,velocity:h,dynamicWidth:c,smoothedWidth:Math.max(.3,Math.min(o*5,l))})}return a}drawVelocityBasedPath(e){if(!(e.length<2))for(let o=1;o<e.length;o++){const a=e[o],s=e[o-1];this.drawVelocitySegment(s,a,s.smoothedWidth,a.smoothedWidth)}}drawVelocitySegment(e,o,a,s){const i=Math.sqrt(Math.pow(o.x-e.x,2)+Math.pow(o.y-e.y,2)),h=Math.max(2,Math.min(10,Math.floor(i/3)));this.ctx.beginPath();const c=[];for(let l=0;l<=h;l++){const d=l/h,f=this.smoothStep(d),C=e.x+(o.x-e.x)*f,p=e.y+(o.y-e.y)*f,w=a+(s-a)*f,T=o.x-e.x,W=o.y-e.y,R=Math.sqrt(T*T+W*W);if(R>0){const S=-W/R*w/2,P=T/R*w/2;l===0?this.ctx.moveTo(C+S,p+P):this.ctx.lineTo(C+S,p+P),c.push({x:C-S,y:p-P})}}for(let l=c.length-1;l>=0;l--)this.ctx.lineTo(c[l].x,c[l].y);this.ctx.closePath(),this.ctx.fill()}smoothStep(e){return e*e*(3-2*e)}getControlPoint(e,o,a){const i={length:Math.sqrt(Math.pow(a.x-o.x,2)+Math.pow(a.y-o.y,2)),angle:Math.atan2(a.y-o.y,a.x-o.x)},h=i.angle+Math.PI,c=i.length*.2;return{x:e.x+Math.cos(h)*c,y:e.y+Math.sin(h)*c,time:e.time||0}}clearCanvas(){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)}on(e,o){this.eventCallbacks.has(e)||this.eventCallbacks.set(e,[]),this.eventCallbacks.get(e).push(o)}off(e,o){if(this.eventCallbacks.has(e))if(o){const a=this.eventCallbacks.get(e),s=a.indexOf(o);s>-1&&a.splice(s,1)}else this.eventCallbacks.delete(e)}emit(e,...o){const a=this.eventCallbacks.get(e);a&&a.forEach(s=>s(...o))}drawCompletePathToOffscreen(e){if(!this.offscreenCtx||e.points.length<2)return;const o=this.ctx;this.ctx=this.offscreenCtx;const a=e.penStyle||this.options.penStyle||"pen";this.drawStyledStrokeForReplay(e.points,a,e.strokeColor,e.strokeWidth),this.ctx=o}drawPartialPathToOffscreen(e,o){if(!this.offscreenCtx||e.points.length<2)return;const a=e.startTime||0,s=e.duration||0,i=a+s*o,h=this.getPointsUpToTime(e.points,a,i);if(h.length<2)return;const c=this.ctx;this.ctx=this.offscreenCtx;const l=e.penStyle||this.options.penStyle||"pen";this.drawStyledStrokeForReplay(h,l,e.strokeColor,e.strokeWidth),this.ctx=c}destroy(){this.stop(),this.eventCallbacks.clear(),this.replayData=null,this.lastFrameImageBitmap&&(this.lastFrameImageBitmap.close(),this.lastFrameImageBitmap=null)}}function ue(r){const e=r.paths.map(l=>{const d=l.points.map((C,p)=>{var T;let w;if(C.time&&l.points[0].time)w=C.time-l.points[0].time;else if(p===0)w=0;else{const W=l.points[p-1],S=Math.sqrt(Math.pow(C.x-W.x,2)+Math.pow(C.y-W.y,2))/100*1e3;w=(((T=d[p-1])==null?void 0:T.relativeTime)||0)+Math.max(S,16)}return{...C,relativeTime:w}}),f=d.length>0?d[d.length-1].relativeTime:0;return{...l,points:d,duration:f}}),o=[];for(let l=0;l<e.length;l++){const d=e[l];let f;if(l===0)f=0;else{const w=o[l-1],T=ze(r.paths[l-1].points,r.paths[l].points);f=w.endTime+T}const C=f+d.duration,p={...d,startTime:f,endTime:C};console.log(`路径 ${l}: 开始时间=${f}, 结束时间=${C}, 持续时间=${d.duration}`),o.push(p)}const a=o.length>0?o[o.length-1].endTime:0;console.log("回放数据生成完成:"),console.log("- 路径数量:",o.length),console.log("- 总时长:",a),console.log("- 路径详情:",o.map(l=>({startTime:l.startTime,endTime:l.endTime,duration:l.duration,pointCount:l.points.length})));const s=o.reduce((l,d)=>l+Ye(d.points),0),i=a>0?s/(a/1e3):0,h=o.slice(1).map((l,d)=>{const f=o[d];return l.startTime-f.endTime}),c=h.length>0?h.reduce((l,d)=>l+d,0)/h.length:0;return{paths:o,totalDuration:a,speed:1,metadata:{deviceType:$e(r),averageSpeed:i,totalDistance:s,averagePauseTime:c}}}function ze(r,e){if(r.length===0||e.length===0)return 200;const o=r[r.length-1],a=e[0];if(o.time&&a.time)return Math.max(a.time-o.time,50);const s=Math.sqrt(Math.pow(a.x-o.x,2)+Math.pow(a.y-o.y,2));return Math.min(Math.max(s*2,100),1e3)}function $e(r){const e=r.paths.reduce((i,h)=>i+h.points.length,0),o=r.paths.length;if(e===0)return"touch";const a=e/o;return a>20?"touch":a<10?"mouse":r.paths.some(i=>i.points.some(h=>h.pressure!==void 0))?"pen":"touch"}function Ye(r){let e=0;for(let o=1;o<r.length;o++){const a=r[o].x-r[o-1].x,s=r[o].y-r[o-1].y;e+=Math.sqrt(a*a+s*s)}return e}const U={ballpoint:{name:"适中笔迹",description:"连续流畅,简洁专业,商务首选",strokeWidth:2,smoothing:!0,pressure:{enabled:!0,min:1.5,max:2.5},lineCap:"round",lineJoin:"round",recommendedColor:"#374151"},elegant:{name:"优雅笔迹",description:"智能渐变,由粗到细,速度感应",strokeWidth:3,smoothing:!0,pressure:{enabled:!0,min:.3,max:15},lineCap:"round",lineJoin:"round",recommendedColor:"#374151"},brush:{name:"毛笔",description:"传统书法,自然变化,文化韵味",strokeWidth:8,smoothing:!0,pressure:{enabled:!0,min:1,max:20},lineCap:"round",lineJoin:"round",recommendedColor:"#2c3e50"},pencil:{name:"铅笔",description:"稳定连续,简洁清晰,自然书写",strokeWidth:3,smoothing:!0,pressure:{enabled:!0,min:2,max:5},lineCap:"round",lineJoin:"round",recommendedColor:"#666666"},pen:{name:"钢笔",description:"极细锐利,精准线条,技术绘图",strokeWidth:1,smoothing:!0,pressure:{enabled:!0,min:1,max:1},lineCap:"round",lineJoin:"round",recommendedColor:"#000080"},marker:{name:"马克笔",description:"超粗荧光,醒目标记,重点突出",strokeWidth:12,smoothing:!1,pressure:{enabled:!1,min:10,max:14},lineCap:"square",lineJoin:"bevel",recommendedColor:"#ff6b35"}};function de(r){return U[r]}function Xe(){return Object.entries(U).map(([r,e])=>({key:r,config:e}))}function me(r,e){const o=de(r);return{strokeWidth:o.strokeWidth,smoothing:o.smoothing,pressure:o.pressure,lineCap:o.lineCap,lineJoin:o.lineJoin,strokeColor:e||o.recommendedColor||"#000000"}}const Le=["width","height"],He={key:1,class:"signature-toolbar"},Ue=["disabled"],je=["disabled"],Ge=["disabled"],Qe={key:2,class:"replay-controls"},Ke={class:"replay-buttons"},Ze=["disabled"],et={key:0},tt={key:1},nt=["disabled"],at={class:"replay-progress"},ot=["max","value","disabled"],st={class:"time-display"},it={class:"replay-speed"},rt=16,lt=u.defineComponent({__name:"ElectronicSignature",props:{showToolbar:{type:Boolean,default:!1},width:{default:"100%"},height:{default:300},penStyle:{default:"ballpoint"},strokeColor:{default:"#000000"},strokeWidth:{default:2},backgroundColor:{default:"transparent"},disabled:{type:Boolean,default:!1},placeholder:{default:"请在此处签名"},smoothing:{type:Boolean,default:!0},pressureSensitive:{type:Boolean,default:!1},minStrokeWidth:{default:1},maxStrokeWidth:{default:4},borderStyle:{default:"1px solid #ddd"},borderRadius:{default:"4px"},replayMode:{type:Boolean},realTimeMode:{type:Boolean,default:!0},replayData:{},replayOptions:{}},emits:["signature-start","signature-drawing","signature-end","signature-clear","signature-undo","signature-redo","replay-start","replay-progress","replay-pause","replay-resume","replay-stop","replay-complete","replay-path-start","replay-path-end","replay-speed-change"],setup(r,{expose:e,emit:o}){const a=r,s=o,i=u.ref(),h=u.ref(!1),c=u.ref(null),l=u.ref(q(0,0)),d=u.ref([]),f=u.ref(-1),C=u.ref(0),p=u.ref(null),w=u.ref(!1),T=u.ref("idle"),W=u.ref(0),R=u.ref(0),S=u.computed(()=>typeof a.width=="number"?a.width:800),P=u.computed(()=>typeof a.height=="number"?a.height:300),ft=u.computed(()=>({position:"relative",display:"inline-block",width:typeof a.width=="string"?a.width:`${a.width}px`,height:typeof a.height=="string"?a.height:`${a.height}px`})),yt=u.computed(()=>({border:a.borderStyle,borderRadius:a.borderRadius,backgroundColor:a.backgroundColor,cursor:a.disabled?"not-allowed":"crosshair",display:"block",width:"100%",height:"100%"})),vt=u.computed(()=>({position:"absolute",top:"50%",left:"50%",transform:"translate(-50%, -50%)",color:"#999",fontSize:"14px",pointerEvents:"none",userSelect:"none"})),xt=u.computed(()=>w.value?!1:a.placeholder&&J(l.value)),fe=u.computed(()=>f.value>0),ye=u.computed(()=>f.value<d.value.length-1),ve=u.computed(()=>w.value&&p.value),_=u.computed(()=>!ve.value&&!a.disabled),Ct=u.computed(()=>{var t;return ve.value&&((t=a.replayOptions)==null?void 0:t.showControls)!==!1}),E=u.computed(()=>{if(a.penStyle){const t=me(a.penStyle,a.strokeColor);return{strokeColor:t.strokeColor,strokeWidth:a.strokeWidth||t.strokeWidth,smoothing:a.smoothing!==void 0?a.smoothing:t.smoothing,pressure:{enabled:a.pressureSensitive!==void 0?a.pressureSensitive:t.pressure.enabled,min:a.minStrokeWidth||t.pressure.min,max:a.maxStrokeWidth||t.pressure.max},lineCap:t.lineCap,lineJoin:t.lineJoin}}return{strokeColor:a.strokeColor||"#000000",strokeWidth:a.strokeWidth||2,smoothing:a.smoothing!==void 0?a.smoothing:!0,pressure:{enabled:a.pressureSensitive||!1,min:a.minStrokeWidth||1,max:a.maxStrokeWidth||4},lineCap:"round",lineJoin:"round"}}),z=()=>{var t;return((t=i.value)==null?void 0:t.getContext("2d"))||null},Y=(t,n)=>{const g=i.value,y=g.getBoundingClientRect(),m=g.width/y.width,x=g.height/y.height;return{x:(t-y.left)*m,y:(n-y.top)*x,time:Date.now()}},xe=t=>{if(!_.value)return;h.value=!0;const n=performance.now(),g={...t,time:n};c.value={points:[g],strokeColor:a.strokeColor,strokeWidth:a.strokeWidth,penStyle:a.penStyle,startTime:n,endTime:n,duration:0},s("signature-start")},G=(t,n,g,y)=>{switch(g){case"pen":return 1;case"brush":if(n){const I=Math.sqrt(Math.pow(t.x-n.x,2)+Math.pow(t.y-n.y,2)),V=Math.max(1,(t.time||0)-(n.time||0)),F=I/V,B=Math.max(.1,Math.min(3,100/Math.max(F,1))),H=t.pressure||.5;return Math.max(1,Math.min(20,y*B*(.3+H*1.4)))}return y;case"marker":return 12;case"pencil":const m=t.pressure||.5;return y*(.7+m*.6);case"ballpoint":const x=t.pressure||.5;return y*(.8+x*.4);case"elegant":const k=t.pressure||.5;let D=1;if(n){const I=Math.sqrt(Math.pow(t.x-n.x,2)+Math.pow(t.y-n.y,2)),V=Math.max(1,(t.time||0)-(n.time||0)),F=I/V;D=Math.max(.3,Math.min(2,50/Math.max(F,1)))}const b=k*D;return y*(.4+b*1.6);default:return y}},$=(t,n,g)=>{var y;if(!(n.length<2))switch(t.strokeStyle=((y=c.value)==null?void 0:y.strokeColor)||E.value.strokeColor,t.lineCap=E.value.lineCap||"round",t.lineJoin=E.value.lineJoin||"round",g){case"pen":if(t.lineWidth=1,t.lineCap="butt",t.lineJoin="miter",t.beginPath(),t.moveTo(n[0].x,n[0].y),n.length>=3){for(let m=1;m<n.length-1;m++){const x=Ce(n[m],n[m-1],n[m+1]);t.quadraticCurveTo(x.x,x.y,n[m].x,n[m].y)}t.lineTo(n[n.length-1].x,n[n.length-1].y)}else for(let m=1;m<n.length;m++)t.lineTo(n[m].x,n[m].y);t.stroke();break;case"brush":t.lineCap="round",t.lineJoin="round";for(let m=1;m<n.length;m++){const x=n[m],k=n[m-1],D=G(x,k,g,E.value.strokeWidth),b=t.createLinearGradient(k.x,k.y,x.x,x.y);b.addColorStop(0,t.strokeStyle),b.addColorStop(1,t.strokeStyle),t.lineWidth=D,t.beginPath(),t.moveTo(k.x,k.y),t.lineTo(x.x,x.y),t.stroke()}break;case"marker":t.globalAlpha=.7,t.lineWidth=12,t.lineCap="square",t.lineJoin="bevel",t.beginPath(),t.moveTo(n[0].x,n[0].y);for(let m=1;m<n.length;m++)t.lineTo(n[m].x,n[m].y);t.stroke(),t.globalAlpha=.3,t.lineWidth=16,t.beginPath(),t.moveTo(n[0].x,n[0].y);for(let m=1;m<n.length;m++)t.lineTo(n[m].x,n[m].y);t.stroke(),t.globalAlpha=1;break;case"pencil":t.lineCap="round",t.lineJoin="round";for(let m=1;m<n.length;m++){const x=n[m],k=n[m-1],D=G(x,k,g,E.value.strokeWidth);t.lineWidth=D,t.globalAlpha=.8,t.beginPath(),t.moveTo(k.x,k.y),t.lineTo(x.x,x.y),t.stroke()}t.globalAlpha=1;break;case"ballpoint":t.lineCap="round",t.lineJoin="round";for(let m=1;m<n.length;m++){const x=n[m],k=n[m-1],D=G(x,k,g,E.value.strokeWidth);if(t.lineWidth=D,t.globalAlpha=1,t.beginPath(),E.value.smoothing&&m<n.length-1){const b=n[m+1],I=Ce(x,k,b);t.moveTo(k.x,k.y),t.quadraticCurveTo(I.x,I.y,x.x,x.y)}else t.moveTo(k.x,k.y),t.lineTo(x.x,x.y);t.stroke()}t.globalAlpha=1;break;case"elegant":St(t,n);break}},wt=()=>{if(!c.value||c.value.points.length<2)return;const t=z();if(!t)return;const n=c.value.penStyle||a.penStyle||"pen";if(n==="brush"){Tt();return}if(n==="ballpoint"){kt();return}t.clearRect(0,0,S.value,P.value);for(const g of l.value.paths)g!==c.value&&Q(t,g);c.value.points.length>=2&&Q(t,c.value)},Tt=()=>{if(!c.value||c.value.points.length<2)return;const t=z();if(!t)return;const n=c.value.points;if(n.length>=2){const y=n.slice(-3);y.length>=2&&$(t,y,"brush")}},kt=()=>{if(!c.value||c.value.points.length<2)return;const t=z();if(!t)return;const n=c.value.points;if(n.length>=2){const y=n.slice(-3);y.length>=2&&$(t,y,"ballpoint")}},bt=()=>{if(!c.value||c.value.points.length<2)return;const t=z();if(!t)return;const n=c.value.points,g=n.length,y=a.penStyle||"pen";if(g===2)$(t,n,y);else if(g>=3){const m=n.slice(-3);$(t,m,y)}},St=(t,n)=>{var y,m;if(n.length<2)return;t.strokeStyle=((y=c.value)==null?void 0:y.strokeColor)||E.value.strokeColor,t.fillStyle=((m=c.value)==null?void 0:m.strokeColor)||E.value.strokeColor,t.lineCap="round",t.lineJoin="round",t.globalCompositeOperation="source-over";const g=Mt(n,E.value.strokeWidth);Pt(t,g)},Mt=(t,n)=>{const g=[];for(let y=0;y<t.length;y++){const m=t[y];let x=0,k=n;if(y>0){const b=t[y-1],I=Math.sqrt(Math.pow(m.x-b.x,2)+Math.pow(m.y-b.y,2)),V=Math.max(1,(m.time||0)-(b.time||0));x=I/V;const F=m.pressure||.5,B=Math.max(.1,Math.min(5,150/Math.max(x,1)));k=n*(.2+F*B*2)}let D=k;if(y>0){const b=g[y-1].smoothedWidth;D=b+(k-b)*.5}g.push({...m,velocity:x,dynamicWidth:k,smoothedWidth:Math.max(.3,Math.min(n*5,D))})}return g},Pt=(t,n)=>{if(!(n.length<2))for(let g=1;g<n.length;g++){const y=n[g],m=n[g-1];Dt(t,m,y,m.smoothedWidth,y.smoothedWidth)}},Dt=(t,n,g,y,m)=>{const x=Math.sqrt(Math.pow(g.x-n.x,2)+Math.pow(g.y-n.y,2)),k=Math.max(2,Math.min(10,Math.floor(x/3)));t.beginPath();const D=[];for(let b=0;b<=k;b++){const I=b/k,V=Et(I),F=n.x+(g.x-n.x)*V,B=n.y+(g.y-n.y)*V,H=y+(m-y)*V,Z=g.x-n.x,ee=g.y-n.y,te=Math.sqrt(Z*Z+ee*ee);if(te>0){const ne=-ee/te*H/2,ae=Z/te*H/2;b===0?t.moveTo(F+ne,B+ae):t.lineTo(F+ne,B+ae),D.push({x:F-ne,y:B-ae})}}for(let b=D.length-1;b>=0;b--)t.lineTo(D[b].x,D[b].y);t.closePath(),t.fill()},Et=t=>t*t*(3-2*t),Ce=(t,n,g)=>{const m={length:Math.sqrt(Math.pow(g.x-n.x,2)+Math.pow(g.y-n.y,2)),angle:Math.atan2(g.y-n.y,g.x-n.x)},x=m.angle+Math.PI,k=m.length*.2;return{x:t.x+Math.cos(x)*k,y:t.y+Math.sin(x)*k,time:t.time||0}},Q=(t,n)=>{if(n.points.length<2)return;const g=n.penStyle||a.penStyle||"pen",y=c.value;c.value=n,$(t,n.points,g),c.value=y},we=t=>{if(!h.value||!c.value||!_.value)return;const n=performance.now();if(n-C.value<rt)return;C.value=n;const g={...t,time:n};c.value.points.push(g),c.value.startTime&&(c.value.endTime=n,c.value.duration=n-c.value.startTime),a.realTimeMode?wt():bt(),Se(),s("signature-drawing",l.value)},Te=()=>{if(!(!h.value||!c.value)){if(h.value=!1,c.value.points.length>0){const t=c.value.points[c.value.points.length-1];t.time&&c.value.startTime&&(c.value.endTime=t.time,c.value.duration=t.time-c.value.startTime)}l.value.paths.push(c.value),l.value.isEmpty=!1,l.value.timestamp=Date.now(),X(),N(),c.value=null,s("signature-end",l.value)}},Wt=t=>{t.preventDefault();const n=Y(t.clientX,t.clientY);xe(n)},Rt=t=>{if(t.preventDefault(),!h.value)return;const n=Y(t.clientX,t.clientY);we(n)},ke=t=>{t.preventDefault(),Te()},_t=t=>{if(t.preventDefault(),t.touches.length!==1)return;const n=t.touches[0],g=Y(n.clientX,n.clientY);xe(g)},It=t=>{if(t.preventDefault(),t.touches.length!==1||!h.value)return;const n=t.touches[0],g=Y(n.clientX,n.clientY);we(g)},be=t=>{t.preventDefault(),Te()},Se=()=>{l.value.canvasSize={width:S.value,height:P.value},l.value.isEmpty=J(l.value)},X=()=>{d.value=d.value.slice(0,f.value+1),d.value.push(A(l.value)),f.value=d.value.length-1;const t=50;d.value.length>t&&(d.value=d.value.slice(-t),f.value=d.value.length-1)},N=()=>{const t=z();t&&(t.clearRect(0,0,S.value,P.value),a.backgroundColor&&a.backgroundColor!=="transparent"&&(t.fillStyle=a.backgroundColor,t.fillRect(0,0,S.value,P.value)),l.value.paths.forEach(n=>{n.points.length>0&&Q(t,n)}))},L=()=>{if(console.log("初始化回放控制器"),console.log("canvas引用是否存在:",!!i.value),!i.value){console.error("canvas引用不存在,无法初始化回放控制器");return}p.value&&(console.log("销毁现有回放控制器"),p.value.destroy()),console.log("创建新的回放控制器"),p.value=new he(i.value),console.log("回放控制器创建成功:",!!p.value),p.value.on("replay-start",()=>{T.value="playing",s("replay-start")}),p.value.on("replay-progress",(t,n)=>{W.value=t,R.value=n,s("replay-progress",t,n)}),p.value.on("replay-pause",()=>{T.value="paused",s("replay-pause")}),p.value.on("replay-resume",()=>{T.value="playing",s("replay-resume")}),p.value.on("replay-stop",()=>{T.value="stopped",s("replay-stop")}),p.value.on("replay-complete",()=>{T.value="completed",s("replay-complete")}),p.value.on("replay-path-start",(t,n)=>{s("replay-path-start",t,n)}),p.value.on("replay-path-end",(t,n)=>{s("replay-path-end",t,n)}),p.value.on("replay-speed-change",t=>{s("replay-speed-change",t)})},Me=(t,n)=>{if(p.value||L(),p.value){w.value=!0;const g={...n,drawOptions:E.value,penStyle:a.penStyle};p.value.setReplayData(t,g),console.log("startReplay调用,自动播放:",n==null?void 0:n.autoPlay),(n==null?void 0:n.autoPlay)===!0&&p.value.play()}},Pe=t=>{w.value=t,!t&&p.value&&(p.value.stop(),N())},Ot=()=>J(l.value)?null:ue(l.value),De=()=>{console.log("play方法被调用"),console.log("回放控制器是否存在:",!!p.value),p.value||(console.log("回放控制器不存在,尝试初始化"),L()),p.value?(console.log("调用回放控制器的play方法"),p.value.play()):console.error("回放控制器初始化失败,无法播放")},Ee=()=>{var t;(t=p.value)==null||t.pause()},We=()=>{var t;(t=p.value)==null||t.stop()},Re=t=>{var n;(n=p.value)==null||n.seek(t)},_e=t=>{var n;(n=p.value)==null||n.setSpeed(t)},Vt=()=>{var t;return((t=p.value)==null?void 0:t.getState())||"idle"},Ft=()=>{var t;return((t=p.value)==null?void 0:t.getCurrentTime())||0},K=()=>{var t;return((t=p.value)==null?void 0:t.getTotalDuration())||0},At=()=>{var t;return((t=p.value)==null?void 0:t.getProgress())||0},Ie=t=>{const n=Math.floor(t/1e3),g=Math.floor(n/60),y=n%60;return`${g}:${y.toString().padStart(2,"0")}`},Oe=()=>{_.value&&(l.value=q(S.value,P.value),N(),X(),s("signature-clear"))},Ve=()=>{!fe.value||!_.value||(f.value--,l.value=A(d.value[f.value]),N(),s("signature-undo",l.value))},Fe=()=>{!ye.value||!_.value||(f.value++,l.value=A(d.value[f.value]),N(),s("signature-redo",l.value))},Ae=t=>{const n=i.value;return le(n,l.value,t)},Ne=()=>J(l.value),Be=async t=>{if(!_.value)return;const n=i.value;await ce(n,t),l.value=q(S.value,P.value),l.value.isEmpty=!1,X()},Nt=()=>A(l.value),Bt=t=>{_.value&&(l.value=A(t),N(),X())},Je=(t,n)=>{const g=t||S.value,y=n||P.value,m=Ae({format:"png"});u.nextTick(()=>{const x=i.value;x.width=g,x.height=y,Ne()||Be(m),Se()})},Jt=()=>{const t=i.value;t.width=S.value,t.height=P.value,l.value=q(S.value,P.value),d.value=[A(l.value)],f.value=0,N()};return u.watch([()=>a.width,()=>a.height],()=>{u.nextTick(()=>{i.value&&Je()})}),u.watch(()=>a.replayMode,t=>{t!==void 0&&Pe(t)}),u.watch(()=>a.replayData,t=>{if(console.log("watch监听到回放数据变化:",t),console.log("当前回放模式:",a.replayMode),console.log("回放控制器是否存在:",!!p.value),t&&a.replayMode)if(p.value||(console.log("回放控制器未初始化,先初始化"),L()),p.value){console.log("开始设置回放数据到控制器");const n={...a.replayOptions,drawOptions:E.value,penStyle:a.penStyle};p.value.setReplayData(t,n),console.log("回放数据已更新:",t)}else console.error("回放控制器初始化失败");else t||console.log("回放数据为空,跳过设置"),a.replayMode||console.log("不在回放模式,跳过设置")},{immediate:!0}),u.onMounted(()=>{u.nextTick(()=>{Jt(),L(),a.replayMode&&a.replayData&&Me(a.replayData,a.replayOptions)})}),u.onUnmounted(()=>{p.value&&(p.value.destroy(),p.value=null)}),e({clear:Oe,undo:Ve,redo:Fe,save:Ae,isEmpty:Ne,fromDataURL:Be,getSignatureData:Nt,setSignatureData:Bt,resize:Je,startReplay:Me,getReplayData:Ot,setReplayMode:Pe,play:De,pause:Ee,stop:We,seek:Re,setSpeed:_e,getState:Vt,getCurrentTime:Ft,getTotalDuration:K,getProgress:At}),(t,n)=>(u.openBlock(),u.createElementBlock("div",{class:"electronic-signature",style:u.normalizeStyle(ft.value)},[u.createElementVNode("canvas",{ref_key:"canvasRef",ref:i,width:S.value,height:P.value,style:u.normalizeStyle(yt.value),onMousedown:Wt,onMousemove:Rt,onMouseup:ke,onMouseleave:ke,onTouchstart:_t,onTouchmove:It,onTouchend:be,onTouchcancel:be},null,44,Le),xt.value?(u.openBlock(),u.createElementBlock("div",{key:0,class:"signature-placeholder",style:u.normalizeStyle(vt.value)},u.toDisplayString(t.placeholder),5)):u.createCommentVNode("",!0),t.showToolbar?(u.openBlock(),u.createElementBlock("div",He,[u.createElementVNode("button",{onClick:Oe,disabled:!_.value},"清除",8,Ue),u.createElementVNode("button",{onClick:Ve,disabled:!_.value||!fe.value},"撤销",8,je),u.createElementVNode("button",{onClick:Fe,disabled:!_.value||!ye.value},"重做",8,Ge)])):u.createCommentVNode("",!0),Ct.value?(u.openBlock(),u.createElementBlock("div",Qe,[u.createElementVNode("div",Ke,[u.createElementVNode("button",{onClick:n[0]||(n[0]=g=>T.value==="playing"?Ee():De()),disabled:T.value==="idle",class:"replay-btn play-pause-btn"},[T.value==="playing"?(u.openBlock(),u.createElementBlock("span",et,"⏸️")):(u.openBlock(),u.createElementBlock("span",tt,"▶️"))],8,Ze),u.createElementVNode("button",{onClick:n[1]||(n[1]=g=>We()),disabled:T.value==="idle",class:"replay-btn stop-btn"}," ⏹️ ",8,nt)]),u.createElementVNode("div",at,[u.createElementVNode("input",{type:"range",min:"0",max:K(),value:R.value,onInput:n[2]||(n[2]=g=>Re(Number(g.target.value))),class:"progress-slider",disabled:T.value==="idle"},null,40,ot),u.createElementVNode("div",st,[u.createElementVNode("span",null,u.toDisplayString(Ie(R.value)),1),n[4]||(n[4]=u.createElementVNode("span",null,"/",-1)),u.createElementVNode("span",null,u.toDisplayString(Ie(K())),1)])]),u.createElementVNode("div",it,[n[6]||(n[6]=u.createElementVNode("label",null,"速度:",-1)),u.createElementVNode("select",{onChange:n[3]||(n[3]=g=>_e(Number(g.target.value))),class:"speed-select"},n[5]||(n[5]=[u.createElementVNode("option",{value:"0.5"},"0.5x",-1),u.createElementVNode("option",{value:"1",selected:""},"1x",-1),u.createElementVNode("option",{value:"1.5"},"1.5x",-1),u.createElementVNode("option",{value:"2"},"2x",-1)]),32)])])):u.createCommentVNode("",!0)],4))}}),$t="",j=((r,e)=>{const o=r.__vccOpts||r;for(const[a,s]of e)o[a]=s;return o})(lt,[["__scopeId","data-v-259e6ad4"]]);function ge(){return window.devicePixelRatio||1}function ct(r){const e=r.getContext("2d"),o=ge(),a=r.clientWidth,s=r.clientHeight;return r.width=a*o,r.height=s*o,e.scale(o,o),r.style.width=a+"px",r.style.height=s+"px",e}function pe(r){if(r.paths.length===0)return{minX:0,minY:0,maxX:0,maxY:0,width:0,height:0};let e=1/0,o=1/0,a=-1/0,s=-1/0;return r.paths.forEach(i=>{i.points.forEach(h=>{e=Math.min(e,h.x),o=Math.min(o,h.y),a=Math.max(a,h.x),s=Math.max(s,h.y)})}),{minX:e,minY:o,maxX:a,maxY:s,width:a-e,height:s-o}}function ht(r,e,o=10){const a=pe(e);if(a.width===0||a.height===0){const l=document.createElement("canvas");return l.width=1,l.height=1,l}const s=document.createElement("canvas"),i=s.getContext("2d"),h=a.width+o*2,c=a.height+o*2;return s.width=h,s.height=c,i.drawImage(r,a.minX-o,a.minY-o,h,c,0,0,h,c),s}function ut(r,e,o,a=!0){const s=document.createElement("canvas"),i=s.getContext("2d");let h=e,c=o;if(a){const l=r.width/r.height,d=e/o;l>d?c=e/l:h=o*l}return s.width=h,s.height=c,i.imageSmoothingEnabled=!0,i.imageSmoothingQuality="high",i.drawImage(r,0,0,h,c),s}function dt(r,e,o={}){const{fontSize:a=12,fontFamily:s="Arial",color:i="#999",opacity:h=.5,position:c="bottom-right"}=o,l=document.createElement("canvas"),d=l.getContext("2d");l.width=r.width,l.height=r.height,d.drawImage(r,0,0),d.font=`${a}px ${s}`,d.fillStyle=i,d.globalAlpha=h;const C=d.measureText(e).width,p=a;let w,T;switch(c){case"top-left":w=10,T=p+10;break;case"top-right":w=r.width-C-10,T=p+10;break;case"bottom-left":w=10,T=r.height-10;break;case"bottom-right":w=r.width-C-10,T=r.height-10;break;case"center":w=(r.width-C)/2,T=(r.height+p)/2;break;default:w=r.width-C-10,T=r.height-10}return d.fillText(e,w,T),d.globalAlpha=1,l}function mt(r){const e=document.createElement("canvas"),o=e.getContext("2d");e.width=r.width,e.height=r.height,o.drawImage(r,0,0);const a=o.getImageData(0,0,r.width,r.height),s=a.data;for(let i=0;i<s.length;i+=4){const h=s[i]*.299+s[i+1]*.587+s[i+2]*.114;s[i]=h,s[i+1]=h,s[i+2]=h}return o.putImageData(a,0,0),e}const gt={install:r=>{r.component("ElectronicSignature",j)},ElectronicSignature:j},pt="1.0.0";v.ElectronicSignature=j,v.PEN_STYLE_CONFIGS=U,v.SignatureReplayController=he,v.addWatermark=dt,v.calculateStrokeWidth=ie,v.cloneSignatureData=A,v.convertToGrayscale=mt,v.createDrawOptionsFromPenStyle=me,v.createEmptySignatureData=q,v.createReplayData=ue,v.cropSignature=ht,v.default=gt,v.drawSmoothPath=qe,v.exportSignature=le,v.getAllPenStyles=Xe,v.getAngle=oe,v.getControlPoint=se,v.getDevicePixelRatio=ge,v.getDistance=O,v.getPenStyleConfig=de,v.getSignatureBounds=pe,v.isSignatureEmpty=J,v.loadImageToCanvas=ce,v.resizeSignature=ut,v.setupHighDPICanvas=ct,v.signatureToSVG=re,v.version=pt,Object.defineProperties(v,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});