invisible-watermark-vue
Version:
A TypeScript library for creating and detecting invisible watermarks using Canvas API, with Vue 3 support
2 lines • 4.32 kB
JavaScript
import{onMounted as e,onUnmounted as t,ref as n}from"vue";var r=class{constructor(){this.canvas=null,this.ctx=null,this.container=null,this.currentText=``,this.defaultOptions={text:``,opacity:.005,fontSize:20,fontFamily:`Arial`,rotate:-15,color:`0, 0, 0`,spacingX:1,spacingY:1.5},this.currentOptions={...this.defaultOptions}}initCanvas(e){let t=e.querySelector(`.invisible-watermark-canvas`);t||(t=document.createElement(`canvas`),t.className=`invisible-watermark-canvas`,t.style.position=`absolute`,t.style.top=`0`,t.style.left=`0`,t.style.width=`100%`,t.style.height=`100%`,t.style.pointerEvents=`none`,t.style.zIndex=`9999`,window.getComputedStyle(e).position===`static`&&(e.style.position=`relative`),e.appendChild(t)),this.canvas=t,this.ctx=t.getContext(`2d`),this.container=e}drawWatermark(){if(!this.canvas||!this.ctx||!this.container)throw Error(`Canvas not initialized. Call apply() first.`);let{opacity:e,fontSize:t,fontFamily:n,rotate:r,color:i,spacingX:a,spacingY:o}=this.currentOptions,s=window.devicePixelRatio||1;this.canvas.width=this.container.offsetWidth*s,this.canvas.height=this.container.offsetHeight*s,this.canvas.style.width=`${this.container.offsetWidth}px`,this.canvas.style.height=`${this.container.offsetHeight}px`,this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.scale(s,s),this.ctx.font=`${t}px ${n}`,this.ctx.fillStyle=`rgba(${i}, ${e})`,this.ctx.textAlign=`center`,this.ctx.textBaseline=`middle`;let c=this.ctx.measureText(this.currentText).width*a,l=t*o,u=Math.ceil(this.container.offsetWidth/c)+2,d=Math.ceil(this.container.offsetHeight/l)+2;this.ctx.save(),this.ctx.translate(this.container.offsetWidth/2,this.container.offsetHeight/2),this.ctx.rotate(r*Math.PI/180),this.ctx.translate(-this.container.offsetWidth/2,-this.container.offsetHeight/2);for(let e=0;e<d;e++)for(let t=0;t<u;t++){let n=t*c-c,r=e*l-l;this.ctx.fillText(this.currentText,n,r)}this.ctx.restore()}apply(e,t){if(!t.text||!t.text.trim())throw Error(`Watermark text cannot be empty`);this.currentOptions={...this.defaultOptions,...t},this.currentText=t.text,this.initCanvas(e),this.drawWatermark()}update(e){if(!this.container)throw Error(`Watermark not initialized. Call apply() first.`);e.text!==void 0&&(this.currentText=e.text),this.currentOptions={...this.currentOptions,...e},this.drawWatermark()}clear(){this.canvas&&this.ctx&&this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.currentText=``}destroy(){this.canvas&&this.canvas.parentNode&&this.canvas.parentNode.removeChild(this.canvas),this.canvas=null,this.ctx=null,this.container=null,this.currentText=``}getCurrentText(){return this.currentText}getCurrentOptions(){return{...this.currentOptions}}enableAutoResize(){let e=()=>{this.currentText&&this.container&&this.drawWatermark()};return window.addEventListener(`resize`,e),()=>{window.removeEventListener(`resize`,e)}}};function i(i,a){let o=new r,s=n(!1),c=n(``),l=null,u=e=>{if(!i.value){console.warn(`Container element not found`);return}let t=e||a;if(!t)throw Error(`Watermark options are required`);o.apply(i.value,t),c.value=t.text,s.value=!0,l||=o.enableAutoResize()},d=e=>{o.update(e),e.text!==void 0&&(c.value=e.text)},f=()=>{o.clear(),s.value=!1,c.value=``},p=()=>{o.destroy(),l&&=(l(),null),s.value=!1,c.value=``};return e(()=>{a&&i.value&&u(a)}),t(()=>{p()}),{isApplied:s,currentText:c,apply:u,update:d,clear:f,destroy:p}}const a=new WeakMap,o={mounted(e,t){let n=typeof t.value==`string`?{text:t.value}:t.value;if(!n||!n.text){console.warn(`[v-watermark] Watermark text is required`);return}try{let t=new r;t.apply(e,n);let i=t.enableAutoResize();a.set(e,t),e._watermarkCleanup=i}catch(e){console.error(`[v-watermark] Failed to apply watermark:`,e)}},updated(e,t){let n=a.get(e);if(!n){console.warn(`[v-watermark] Watermark instance not found`);return}let r=typeof t.value==`string`?{text:t.value}:t.value;if(!r||!r.text){console.warn(`[v-watermark] Watermark text is required`);return}try{n.update(r)}catch(e){console.error(`[v-watermark] Failed to update watermark:`,e)}},unmounted(e){let t=a.get(e);t&&(t.destroy(),a.delete(e));let n=e._watermarkCleanup;n&&(n(),delete e._watermarkCleanup)}},s={install(e){e.directive(`watermark`,o)}};export{r as WatermarkCreator,s as WatermarkPlugin,i as useWatermark,o as vWatermark};
//# sourceMappingURL=index.js.map