scratch-reveal 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -11
- package/dist/index.cjs.js +2 -2
- package/dist/index.es.js +127 -92
- package/dist/index.umd.js +2 -2
- package/dist/internal/utils.d.ts +1 -1
- package/dist/options.d.ts +0 -1
- package/dist/scratch-reveal.d.ts +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -37,9 +37,9 @@ app.mount('#app');
|
|
|
37
37
|
<scratch-reveal
|
|
38
38
|
width="300"
|
|
39
39
|
height="300"
|
|
40
|
-
percent
|
|
40
|
+
complete-percent="60"
|
|
41
41
|
brush-src="/demo/assets/brush.png"
|
|
42
|
-
brush-size="15
|
|
42
|
+
brush-size="15"
|
|
43
43
|
mask-src="/demo/assets/scratch-reveal.png"
|
|
44
44
|
background-src="/demo/assets/scratch-reveal-background.svg"
|
|
45
45
|
></scratch-reveal>
|
|
@@ -51,9 +51,9 @@ app.mount('#app');
|
|
|
51
51
|
<div style="width: 420px; height: 240px;">
|
|
52
52
|
<scratch-reveal
|
|
53
53
|
style="width: 100%; height: 100%;"
|
|
54
|
-
percent
|
|
54
|
+
complete-percent="60"
|
|
55
55
|
brush-src="/demo/assets/brush.png"
|
|
56
|
-
brush-size="12
|
|
56
|
+
brush-size="12"
|
|
57
57
|
mask-src="/demo/assets/scratch-reveal.png"
|
|
58
58
|
background-src="/demo/assets/scratch-reveal-background.svg"
|
|
59
59
|
></scratch-reveal>
|
|
@@ -72,9 +72,13 @@ el.addEventListener('progress', (event) => {
|
|
|
72
72
|
el.addEventListener('complete', () => {
|
|
73
73
|
console.log('done!');
|
|
74
74
|
});
|
|
75
|
+
el.addEventListener('error', (event) => {
|
|
76
|
+
console.error(event.detail.message);
|
|
77
|
+
});
|
|
75
78
|
```
|
|
76
79
|
— `progress` (detail: `{ percent: number }`)
|
|
77
|
-
— `complete` (detail: `{ percent: 100 }`)
|
|
80
|
+
— `complete` (detail: `{ percent: 100 }`)
|
|
81
|
+
— `error` (detail: `{ message: string }`)
|
|
78
82
|
|
|
79
83
|
<br>
|
|
80
84
|
|
|
@@ -83,12 +87,11 @@ el.addEventListener('complete', () => {
|
|
|
83
87
|
| Attribute | Type | Default | Description |
|
|
84
88
|
|:------------------------:|:------------------:|:--------------------------------------------:|:---------------------------------------------------------------------------------------------------------|
|
|
85
89
|
| `width` / `height` | `number` | `300` | Container/mask size in px. If omitted, size follows layout (auto-size). |
|
|
86
|
-
| `percent
|
|
87
|
-
| `brush-src` | `string` |
|
|
88
|
-
| `brush-size` | `string \| number` | `0` | Brush width:
|
|
89
|
-
| `mask-src` | `string` |
|
|
90
|
-
| `background-src` | `string` |
|
|
91
|
-
| `enabled-percent-update` | `boolean` | `true` | Compute cleared percent (used for `progress` and threshold checks). |
|
|
90
|
+
| `complete-percent` | `number` | `60` | Percent cleared to consider done. |
|
|
91
|
+
| `brush-src` | `string` | — | Brush image (**required**). |
|
|
92
|
+
| `brush-size` | `string \| number` | `0` | Brush width: numbers mean percent of min(canvas width, height) (e.g., `12` = 12%). Use `80px` for px. `0` = natural image size. |
|
|
93
|
+
| `mask-src` | `string` | — | Top mask (scratched away) (**required**). |
|
|
94
|
+
| `background-src` | `string` | — | Background beneath the mask (**required**). |
|
|
92
95
|
<br>
|
|
93
96
|
|
|
94
97
|
➠ **Styles**
|
package/dist/index.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class z{ctx;mouseX;mouseY;constructor(t,e,s){this.ctx=t,this.mouseX=e,this.mouseY=s}updateMousePosition(t,e){this.mouseX=t,this.mouseY=e}brush(t,e=0){if(!t)
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class z{ctx;mouseX;mouseY;constructor(t,e,s){this.ctx=t,this.mouseX=e,this.mouseY=s}updateMousePosition(t,e){this.mouseX=t,this.mouseY=e}brush(t,e=0){if(!t)return;const s=Math.atan2(this.mouseY,this.mouseX);if(this.ctx.save(),this.ctx.translate(this.mouseX,this.mouseY),this.ctx.rotate(s),e>0){const i=e,n=e*(t.height/t.width);this.ctx.drawImage(t,-(i/2),-(n/2),i,n)}else this.ctx.drawImage(t,-(t.width/2),-(t.height/2));this.ctx.restore()}}function v(h){return new Promise((t,e)=>{const s=new Image;s.crossOrigin="anonymous",s.onload=()=>t(s),s.onerror=()=>e(new Error(`Image ${h} failed to load`)),s.src=h})}function E(h){let t=0;return((...s)=>{t||(t=requestAnimationFrame(()=>{t=0,h(...s)}))})}const b=`.sr {
|
|
2
2
|
position: relative;
|
|
3
3
|
overflow: hidden;
|
|
4
4
|
width: 100%;
|
|
@@ -25,4 +25,4 @@ scratch-reveal {
|
|
|
25
25
|
width: 100%;
|
|
26
26
|
height: 100%;
|
|
27
27
|
}
|
|
28
|
-
`,
|
|
28
|
+
`,C=b;function R(h){return"adoptedStyleSheets"in h}function P(h){if(typeof CSSStyleSheet>"u")return null;try{const t=new CSSStyleSheet;return t.replaceSync(h),t}catch{return null}}const _=P(b),u={width:300,height:300,brushSrc:"",imageMaskSrc:"",imageBackgroundSrc:"",brushSize:0,percentToFinish:60};class I{config;ctx;container;_canvas;brush;maskImage;backgroundImage;brushImage;backgroundEl;brushSize=0;percent=0;done=!1;completing=!1;destroyed=!1;lastProgressEmitMs=0;lastScratchX;lastScratchY;removeListeners;get canvas(){return this._canvas}constructor(t,e={}){if(this.config={...u,...e},this.container=typeof t=="string"?document.querySelector(t):t,!this.container)throw new Error("ScratchReveal: container not found");this._canvas=this.createCanvas(this.config.width,this.config.height),this.ctx=this._canvas.getContext("2d",{willReadFrequently:!0}),this.brush=new z(this.ctx,0,0),this.brushSize=this.config.brushSize,this.container.appendChild(this._canvas)}async init(){if(!this.config.brushSrc)throw new Error('ScratchReveal: "brushSrc" is required');if(!this.config.imageMaskSrc)throw new Error('ScratchReveal: "imageMaskSrc" is required');if(!this.config.imageBackgroundSrc)throw new Error('ScratchReveal: "imageBackgroundSrc" is required');const[t,e,s]=await Promise.all([v(this.config.brushSrc),v(this.config.imageMaskSrc),v(this.config.imageBackgroundSrc)]);return this.destroyed?this:(this.brushImage=t,this.maskImage=e,this.backgroundImage=s,this.drawMask(),this.setBackground(),this.bindEvents(),this)}destroy(){this.destroyed=!0,this.removeListeners?.()}getPercent(){return this.percent}createCanvas(t,e){const s=document.createElement("canvas");return s.className="sr__canvas",s.width=t,s.height=e,s.style.width="100%",s.style.height="100%",s}resize(t,e){this.destroyed||this.done||t<=0||e<=0||this._canvas.width===t&&this._canvas.height===e||(this._canvas.width=t,this._canvas.height=e,this.percent=0,this.ctx.globalCompositeOperation="source-over",this.drawMask())}setBrushSize(t){this.destroyed||!Number.isFinite(t)||t<0||(this.brushSize=t)}bindEvents(){const e=E((r,a)=>{this.percent=this.updatePercent();const o=performance.now();(!this.lastProgressEmitMs||o-this.lastProgressEmitMs>=120)&&(this.lastProgressEmitMs=o,this.config.onProgress?.(this.percent)),this.finish(r,a)}),s=E(r=>{this.updatePosition(r),this.scratch(),e(r,s)}),i=r=>{r.preventDefault(),this.updatePosition(r),this.scratch(),this._canvas.setPointerCapture(r.pointerId),this._canvas.addEventListener("pointermove",s),this.resetScratchTrail(),this.percent=this.updatePercent(),this.config.onProgress?.(this.percent),this.finish(r,s)},n=r=>{this.resetScratchTrail(),this.percent=this.updatePercent(),this.config.onProgress?.(this.percent),this.finish(r,s)};this._canvas.addEventListener("pointerdown",i),this._canvas.addEventListener("pointerup",n),this._canvas.addEventListener("pointerleave",n),this.removeListeners=()=>{this._canvas.removeEventListener("pointerdown",i),this._canvas.removeEventListener("pointerup",n),this._canvas.removeEventListener("pointerleave",n),this._canvas.removeEventListener("pointermove",s)}}updatePosition(t){const e=this._canvas.getBoundingClientRect(),s=e.width?this._canvas.width/e.width:1,i=e.height?this._canvas.height/e.height:1,n=(t.clientX-e.left)*s,r=(t.clientY-e.top)*i;this.brush.updateMousePosition(n,r)}drawMask(){this.maskImage&&(this.ctx.globalCompositeOperation="source-over",this.ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this.ctx.drawImage(this.maskImage,0,0,this._canvas.width,this._canvas.height))}setBackground(){if(this.destroyed||!this.backgroundImage||!this.container.contains(this._canvas))return;const t=this.backgroundEl??document.createElement("img");t.src=this.backgroundImage.src,t.className="sr__bg",t.isConnected||this.container.insertBefore(t,this._canvas),this.backgroundEl=t}scratch(){if(!this.brushImage)return;const t=this.brushSize>0?this.brushSize:Math.max(1,Math.min(this.brushImage.width,this.brushImage.height)),e=Math.max(2,t*.4);if(this.lastScratchX!==void 0&&this.lastScratchY!==void 0){const i=this.brush.mouseX-this.lastScratchX,n=this.brush.mouseY-this.lastScratchY;if(i*i+n*n<e*e)return}const s=this.brushSize>0?this.brushSize:0;this.ctx.globalCompositeOperation="destination-out",this.ctx.save(),this.brush.brush(this.brushImage,s),this.ctx.restore(),this.lastScratchX=this.brush.mouseX,this.lastScratchY=this.brush.mouseY}resetScratchTrail(){this.lastScratchX=void 0,this.lastScratchY=void 0}updatePercent(){const e=this.ctx.getImageData(0,0,this._canvas.width,this._canvas.height).data;let s=0;for(let i=3;i<e.length;i+=4)e[i]===0&&s++;return s/(this._canvas.width*this._canvas.height)*100}finish(t,e){if(!this.done&&this.percent>this.config.percentToFinish&&(this.done=!0,this._canvas.style.pointerEvents="none",this.config.onComplete?.(),this.playCompleteEffect(),t&&e)){try{this._canvas.releasePointerCapture(t.pointerId)}catch{}this._canvas.removeEventListener("pointermove",e)}}playCompleteEffect(){if(this.destroyed||this.completing)return;this.completing=!0;const t=350,e="ease-out";this._canvas.style.transition=`opacity ${t}ms ${e}`,this._canvas.style.opacity||(this._canvas.style.opacity="1"),requestAnimationFrame(()=>{this._canvas.style.opacity="0",window.setTimeout(()=>{this.destroyed||this.clear()},t)})}clear(){this.ctx.clearRect(0,0,this._canvas.width,this._canvas.height)}}function y(h="scratch-reveal"){if(typeof window>"u"||!("customElements"in window)||customElements.get(h))return;function t(s,i,n,r){if(!s)return r;const a=s.trim();if(!a)return r;const o=Number.parseFloat(a.endsWith("%")?a.slice(0,-1):a.endsWith("px")?a.slice(0,-2):a);if(!Number.isFinite(o))return r;if(a.endsWith("px"))return Math.max(0,o);const d=Math.min(i,n);return Math.max(0,d*o/100)}class e extends HTMLElement{instance;container;styleEl=null;rebuildScheduled=!1;resizeObserver;lastErrorMessage=null;static get observedAttributes(){return["width","height","complete-percent","brush-src","brush-size","mask-src","background-src"]}constructor(){super();const i=this.attachShadow({mode:"open"});R(i)&&_?i.adoptedStyleSheets=[_]:(this.styleEl=document.createElement("style"),this.styleEl.textContent=b,i.append(this.styleEl)),this.container=document.createElement("div"),this.container.className="sr",i.append(this.container)}connectedCallback(){this.scheduleRebuild()}disconnectedCallback(){this.instance?.destroy(),this.instance=void 0,this.resizeObserver?.disconnect(),this.resizeObserver=void 0}attributeChangedCallback(i,n,r){n!==r&&this.scheduleRebuild()}scheduleRebuild(){this.rebuildScheduled||(this.rebuildScheduled=!0,queueMicrotask(()=>{this.rebuildScheduled=!1,this.isConnected&&this.rebuild()}))}rebuild(){this.container.replaceChildren(),this.instance?.destroy();const i=this.hasAttribute("width"),n=this.hasAttribute("height"),r=this.getBoundingClientRect(),a=Math.round(r.width),o=Math.round(r.height),d=i?Number(this.getAttribute("width")):a||u.width,m=n?Number(this.getAttribute("height")):o||u.height,k=Number(this.getAttribute("complete-percent")??u.percentToFinish),f=(this.getAttribute("brush-src")??"").trim(),x=t(this.getAttribute("brush-size"),d,m,u.brushSize),p=(this.getAttribute("mask-src")??"").trim(),S=(this.getAttribute("background-src")??"").trim(),l=[];if(f||l.push("brush-src"),p||l.push("mask-src"),S||l.push("background-src"),l.length){const c=`ScratchReveal: missing required attribute(s): ${l.join(", ")}`;this.renderError(c);return}i?this.container.style.width=`${d}px`:this.container.style.width="100%",n?this.container.style.height=`${m}px`:this.container.style.height="100%",this.instance=new I(this.container,{width:d,height:m,percentToFinish:k,brushSrc:f,brushSize:x,imageMaskSrc:p,imageBackgroundSrc:S,onProgress:c=>{this.dispatchEvent(new CustomEvent("progress",{detail:{percent:c}}))},onComplete:()=>{this.dispatchEvent(new CustomEvent("complete",{detail:{percent:100}}))}}),this.instance.init().catch(c=>{const g=c instanceof Error?c.message:"ScratchReveal: init failed";this.renderError(g)}),(!i||!n)&&"ResizeObserver"in window?(this.resizeObserver?.disconnect(),this.resizeObserver=new ResizeObserver(()=>{if(this.hasAttribute("width")&&this.hasAttribute("height")){this.resizeObserver?.disconnect(),this.resizeObserver=void 0;return}const c=this.getBoundingClientRect(),g=Math.round(c.width),w=Math.round(c.height);this.instance?.resize(g,w);const M=t(this.getAttribute("brush-size"),g,w,u.brushSize);this.instance?.setBrushSize(M)}),this.resizeObserver.observe(this)):(this.resizeObserver?.disconnect(),this.resizeObserver=void 0)}renderError(i){this.instance?.destroy(),this.instance=void 0,this.lastErrorMessage!==i&&(this.lastErrorMessage=i,this.dispatchEvent(new CustomEvent("error",{detail:{message:i}})))}}customElements.define(h,e)}function A(h){y(),h.config.globalProperties.$scratchReveal=!0}exports.installScratchReveal=A;exports.registerScratchRevealElement=y;exports.scratchRevealCssText=C;
|
package/dist/index.es.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class M {
|
|
2
2
|
ctx;
|
|
3
3
|
mouseX;
|
|
4
4
|
mouseY;
|
|
@@ -9,11 +9,8 @@ class C {
|
|
|
9
9
|
this.mouseX = t, this.mouseY = e;
|
|
10
10
|
}
|
|
11
11
|
brush(t, e = 0) {
|
|
12
|
-
if (!t)
|
|
13
|
-
const i = new Error("Brush.brush: img is required");
|
|
14
|
-
console.log(i.message);
|
|
12
|
+
if (!t)
|
|
15
13
|
return;
|
|
16
|
-
}
|
|
17
14
|
const s = Math.atan2(this.mouseY, this.mouseX);
|
|
18
15
|
if (this.ctx.save(), this.ctx.translate(this.mouseX, this.mouseY), this.ctx.rotate(s), e > 0) {
|
|
19
16
|
const i = e, n = e * (t.height / t.width);
|
|
@@ -23,13 +20,13 @@ class C {
|
|
|
23
20
|
this.ctx.restore();
|
|
24
21
|
}
|
|
25
22
|
}
|
|
26
|
-
function
|
|
23
|
+
function v(h) {
|
|
27
24
|
return new Promise((t, e) => {
|
|
28
25
|
const s = new Image();
|
|
29
26
|
s.crossOrigin = "anonymous", s.onload = () => t(s), s.onerror = () => e(new Error(`Image ${h} failed to load`)), s.src = h;
|
|
30
27
|
});
|
|
31
28
|
}
|
|
32
|
-
function
|
|
29
|
+
function E(h) {
|
|
33
30
|
let t = 0;
|
|
34
31
|
return ((...s) => {
|
|
35
32
|
t || (t = requestAnimationFrame(() => {
|
|
@@ -37,7 +34,7 @@ function z(h) {
|
|
|
37
34
|
}));
|
|
38
35
|
});
|
|
39
36
|
}
|
|
40
|
-
const
|
|
37
|
+
const b = `.sr {
|
|
41
38
|
position: relative;
|
|
42
39
|
overflow: hidden;
|
|
43
40
|
width: 100%;
|
|
@@ -64,11 +61,11 @@ scratch-reveal {
|
|
|
64
61
|
width: 100%;
|
|
65
62
|
height: 100%;
|
|
66
63
|
}
|
|
67
|
-
`,
|
|
68
|
-
function
|
|
64
|
+
`, A = b;
|
|
65
|
+
function z(h) {
|
|
69
66
|
return "adoptedStyleSheets" in h;
|
|
70
67
|
}
|
|
71
|
-
function
|
|
68
|
+
function C(h) {
|
|
72
69
|
if (typeof CSSStyleSheet > "u") return null;
|
|
73
70
|
try {
|
|
74
71
|
const t = new CSSStyleSheet();
|
|
@@ -77,17 +74,16 @@ function P(h) {
|
|
|
77
74
|
return null;
|
|
78
75
|
}
|
|
79
76
|
}
|
|
80
|
-
const
|
|
77
|
+
const _ = C(b), u = {
|
|
81
78
|
width: 300,
|
|
82
79
|
height: 300,
|
|
83
|
-
brushSrc: "
|
|
84
|
-
imageMaskSrc: "
|
|
85
|
-
imageBackgroundSrc: "
|
|
80
|
+
brushSrc: "",
|
|
81
|
+
imageMaskSrc: "",
|
|
82
|
+
imageBackgroundSrc: "",
|
|
86
83
|
brushSize: 0,
|
|
87
|
-
percentToFinish: 60
|
|
88
|
-
enabledPercentUpdate: !0
|
|
84
|
+
percentToFinish: 60
|
|
89
85
|
};
|
|
90
|
-
class
|
|
86
|
+
class R {
|
|
91
87
|
config;
|
|
92
88
|
ctx;
|
|
93
89
|
container;
|
|
@@ -100,23 +96,33 @@ class I {
|
|
|
100
96
|
brushSize = 0;
|
|
101
97
|
percent = 0;
|
|
102
98
|
done = !1;
|
|
99
|
+
completing = !1;
|
|
103
100
|
destroyed = !1;
|
|
101
|
+
lastProgressEmitMs = 0;
|
|
102
|
+
lastScratchX;
|
|
103
|
+
lastScratchY;
|
|
104
104
|
removeListeners;
|
|
105
105
|
get canvas() {
|
|
106
106
|
return this._canvas;
|
|
107
107
|
}
|
|
108
108
|
constructor(t, e = {}) {
|
|
109
|
-
if (this.config = { ...
|
|
109
|
+
if (this.config = { ...u, ...e }, this.container = typeof t == "string" ? document.querySelector(t) : t, !this.container)
|
|
110
110
|
throw new Error("ScratchReveal: container not found");
|
|
111
111
|
this._canvas = this.createCanvas(this.config.width, this.config.height), this.ctx = this._canvas.getContext("2d", {
|
|
112
112
|
willReadFrequently: !0
|
|
113
|
-
}), this.brush = new
|
|
113
|
+
}), this.brush = new M(this.ctx, 0, 0), this.brushSize = this.config.brushSize, this.container.appendChild(this._canvas);
|
|
114
114
|
}
|
|
115
115
|
async init() {
|
|
116
|
+
if (!this.config.brushSrc)
|
|
117
|
+
throw new Error('ScratchReveal: "brushSrc" is required');
|
|
118
|
+
if (!this.config.imageMaskSrc)
|
|
119
|
+
throw new Error('ScratchReveal: "imageMaskSrc" is required');
|
|
120
|
+
if (!this.config.imageBackgroundSrc)
|
|
121
|
+
throw new Error('ScratchReveal: "imageBackgroundSrc" is required');
|
|
116
122
|
const [t, e, s] = await Promise.all([
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
v(this.config.brushSrc),
|
|
124
|
+
v(this.config.imageMaskSrc),
|
|
125
|
+
v(this.config.imageBackgroundSrc)
|
|
120
126
|
]);
|
|
121
127
|
return this.destroyed ? this : (this.brushImage = t, this.maskImage = e, this.backgroundImage = s, this.drawMask(), this.setBackground(), this.bindEvents(), this);
|
|
122
128
|
}
|
|
@@ -137,15 +143,21 @@ class I {
|
|
|
137
143
|
this.destroyed || !Number.isFinite(t) || t < 0 || (this.brushSize = t);
|
|
138
144
|
}
|
|
139
145
|
bindEvents() {
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
+
const e = E(
|
|
147
|
+
(r, a) => {
|
|
148
|
+
this.percent = this.updatePercent();
|
|
149
|
+
const o = performance.now();
|
|
150
|
+
(!this.lastProgressEmitMs || o - this.lastProgressEmitMs >= 120) && (this.lastProgressEmitMs = o, this.config.onProgress?.(this.percent)), this.finish(r, a);
|
|
151
|
+
}
|
|
152
|
+
), s = E((r) => {
|
|
153
|
+
this.updatePosition(r), this.scratch(), e(r, s);
|
|
154
|
+
}), i = (r) => {
|
|
155
|
+
r.preventDefault(), this.updatePosition(r), this.scratch(), this._canvas.setPointerCapture(r.pointerId), this._canvas.addEventListener("pointermove", s), this.resetScratchTrail(), this.percent = this.updatePercent(), this.config.onProgress?.(this.percent), this.finish(r, s);
|
|
156
|
+
}, n = (r) => {
|
|
157
|
+
this.resetScratchTrail(), this.percent = this.updatePercent(), this.config.onProgress?.(this.percent), this.finish(r, s);
|
|
146
158
|
};
|
|
147
|
-
this._canvas.addEventListener("pointerdown",
|
|
148
|
-
this._canvas.removeEventListener("pointerdown",
|
|
159
|
+
this._canvas.addEventListener("pointerdown", i), this._canvas.addEventListener("pointerup", n), this._canvas.addEventListener("pointerleave", n), this.removeListeners = () => {
|
|
160
|
+
this._canvas.removeEventListener("pointerdown", i), this._canvas.removeEventListener("pointerup", n), this._canvas.removeEventListener("pointerleave", n), this._canvas.removeEventListener("pointermove", s);
|
|
149
161
|
};
|
|
150
162
|
}
|
|
151
163
|
updatePosition(t) {
|
|
@@ -161,7 +173,18 @@ class I {
|
|
|
161
173
|
t.src = this.backgroundImage.src, t.className = "sr__bg", t.isConnected || this.container.insertBefore(t, this._canvas), this.backgroundEl = t;
|
|
162
174
|
}
|
|
163
175
|
scratch() {
|
|
164
|
-
|
|
176
|
+
if (!this.brushImage) return;
|
|
177
|
+
const t = this.brushSize > 0 ? this.brushSize : Math.max(1, Math.min(this.brushImage.width, this.brushImage.height)), e = Math.max(2, t * 0.4);
|
|
178
|
+
if (this.lastScratchX !== void 0 && this.lastScratchY !== void 0) {
|
|
179
|
+
const i = this.brush.mouseX - this.lastScratchX, n = this.brush.mouseY - this.lastScratchY;
|
|
180
|
+
if (i * i + n * n < e * e)
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
const s = this.brushSize > 0 ? this.brushSize : 0;
|
|
184
|
+
this.ctx.globalCompositeOperation = "destination-out", this.ctx.save(), this.brush.brush(this.brushImage, s), this.ctx.restore(), this.lastScratchX = this.brush.mouseX, this.lastScratchY = this.brush.mouseY;
|
|
185
|
+
}
|
|
186
|
+
resetScratchTrail() {
|
|
187
|
+
this.lastScratchX = void 0, this.lastScratchY = void 0;
|
|
165
188
|
}
|
|
166
189
|
updatePercent() {
|
|
167
190
|
const e = this.ctx.getImageData(0, 0, this._canvas.width, this._canvas.height).data;
|
|
@@ -171,7 +194,7 @@ class I {
|
|
|
171
194
|
return s / (this._canvas.width * this._canvas.height) * 100;
|
|
172
195
|
}
|
|
173
196
|
finish(t, e) {
|
|
174
|
-
if (!this.done && this.percent > this.config.percentToFinish && (this.done = !0, this.
|
|
197
|
+
if (!this.done && this.percent > this.config.percentToFinish && (this.done = !0, this._canvas.style.pointerEvents = "none", this.config.onComplete?.(), this.playCompleteEffect(), t && e)) {
|
|
175
198
|
try {
|
|
176
199
|
this._canvas.releasePointerCapture(t.pointerId);
|
|
177
200
|
} catch {
|
|
@@ -179,52 +202,57 @@ class I {
|
|
|
179
202
|
this._canvas.removeEventListener("pointermove", e);
|
|
180
203
|
}
|
|
181
204
|
}
|
|
205
|
+
playCompleteEffect() {
|
|
206
|
+
if (this.destroyed || this.completing) return;
|
|
207
|
+
this.completing = !0;
|
|
208
|
+
const t = 350, e = "ease-out";
|
|
209
|
+
this._canvas.style.transition = `opacity ${t}ms ${e}`, this._canvas.style.opacity || (this._canvas.style.opacity = "1"), requestAnimationFrame(() => {
|
|
210
|
+
this._canvas.style.opacity = "0", window.setTimeout(() => {
|
|
211
|
+
this.destroyed || this.clear();
|
|
212
|
+
}, t);
|
|
213
|
+
});
|
|
214
|
+
}
|
|
182
215
|
clear() {
|
|
183
216
|
this.ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
|
|
184
217
|
}
|
|
185
218
|
}
|
|
186
|
-
function
|
|
219
|
+
function I(h = "scratch-reveal") {
|
|
187
220
|
if (typeof window > "u" || !("customElements" in window) || customElements.get(h)) return;
|
|
188
|
-
function t(i, n) {
|
|
189
|
-
if (
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
const d = Math.min(n, r);
|
|
201
|
-
return Math.max(0, d * u / 100);
|
|
202
|
-
}
|
|
203
|
-
const l = o.endsWith("px") ? Number.parseFloat(o.slice(0, -2)) : Number.parseFloat(o);
|
|
204
|
-
return Number.isFinite(l) ? Math.max(0, l) : c;
|
|
221
|
+
function t(s, i, n, r) {
|
|
222
|
+
if (!s) return r;
|
|
223
|
+
const a = s.trim();
|
|
224
|
+
if (!a) return r;
|
|
225
|
+
const o = Number.parseFloat(
|
|
226
|
+
a.endsWith("%") ? a.slice(0, -1) : a.endsWith("px") ? a.slice(0, -2) : a
|
|
227
|
+
);
|
|
228
|
+
if (!Number.isFinite(o)) return r;
|
|
229
|
+
if (a.endsWith("px"))
|
|
230
|
+
return Math.max(0, o);
|
|
231
|
+
const d = Math.min(i, n);
|
|
232
|
+
return Math.max(0, d * o / 100);
|
|
205
233
|
}
|
|
206
|
-
class
|
|
234
|
+
class e extends HTMLElement {
|
|
207
235
|
instance;
|
|
208
236
|
container;
|
|
209
237
|
styleEl = null;
|
|
210
238
|
rebuildScheduled = !1;
|
|
211
239
|
resizeObserver;
|
|
240
|
+
lastErrorMessage = null;
|
|
212
241
|
static get observedAttributes() {
|
|
213
242
|
return [
|
|
214
243
|
"width",
|
|
215
244
|
"height",
|
|
216
|
-
"percent
|
|
245
|
+
"complete-percent",
|
|
217
246
|
"brush-src",
|
|
218
247
|
"brush-size",
|
|
219
248
|
"mask-src",
|
|
220
|
-
"background-src"
|
|
221
|
-
"enabled-percent-update"
|
|
249
|
+
"background-src"
|
|
222
250
|
];
|
|
223
251
|
}
|
|
224
252
|
constructor() {
|
|
225
253
|
super();
|
|
226
|
-
const
|
|
227
|
-
|
|
254
|
+
const i = this.attachShadow({ mode: "open" });
|
|
255
|
+
z(i) && _ ? i.adoptedStyleSheets = [_] : (this.styleEl = document.createElement("style"), this.styleEl.textContent = b, i.append(this.styleEl)), this.container = document.createElement("div"), this.container.className = "sr", i.append(this.container);
|
|
228
256
|
}
|
|
229
257
|
connectedCallback() {
|
|
230
258
|
this.scheduleRebuild();
|
|
@@ -232,8 +260,8 @@ function M(h = "scratch-reveal") {
|
|
|
232
260
|
disconnectedCallback() {
|
|
233
261
|
this.instance?.destroy(), this.instance = void 0, this.resizeObserver?.disconnect(), this.resizeObserver = void 0;
|
|
234
262
|
}
|
|
235
|
-
attributeChangedCallback(n, r
|
|
236
|
-
|
|
263
|
+
attributeChangedCallback(i, n, r) {
|
|
264
|
+
n !== r && this.scheduleRebuild();
|
|
237
265
|
}
|
|
238
266
|
scheduleRebuild() {
|
|
239
267
|
this.rebuildScheduled || (this.rebuildScheduled = !0, queueMicrotask(() => {
|
|
@@ -242,56 +270,63 @@ function M(h = "scratch-reveal") {
|
|
|
242
270
|
}
|
|
243
271
|
rebuild() {
|
|
244
272
|
this.container.replaceChildren(), this.instance?.destroy();
|
|
245
|
-
const
|
|
246
|
-
this.getAttribute("percent
|
|
247
|
-
),
|
|
248
|
-
this.getAttribute("enabled-percent-update"),
|
|
249
|
-
a.enabledPercentUpdate
|
|
250
|
-
), E = e(
|
|
273
|
+
const i = this.hasAttribute("width"), n = this.hasAttribute("height"), r = this.getBoundingClientRect(), a = Math.round(r.width), o = Math.round(r.height), d = i ? Number(this.getAttribute("width")) : a || u.width, m = n ? Number(this.getAttribute("height")) : o || u.height, y = Number(
|
|
274
|
+
this.getAttribute("complete-percent") ?? u.percentToFinish
|
|
275
|
+
), p = (this.getAttribute("brush-src") ?? "").trim(), k = t(
|
|
251
276
|
this.getAttribute("brush-size"),
|
|
252
|
-
u,
|
|
253
277
|
d,
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
278
|
+
m,
|
|
279
|
+
u.brushSize
|
|
280
|
+
), f = (this.getAttribute("mask-src") ?? "").trim(), S = (this.getAttribute("background-src") ?? "").trim(), l = [];
|
|
281
|
+
if (p || l.push("brush-src"), f || l.push("mask-src"), S || l.push("background-src"), l.length) {
|
|
282
|
+
const c = `ScratchReveal: missing required attribute(s): ${l.join(", ")}`;
|
|
283
|
+
this.renderError(c);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
i ? this.container.style.width = `${d}px` : this.container.style.width = "100%", n ? this.container.style.height = `${m}px` : this.container.style.height = "100%", this.instance = new R(this.container, {
|
|
287
|
+
width: d,
|
|
288
|
+
height: m,
|
|
289
|
+
percentToFinish: y,
|
|
290
|
+
brushSrc: p,
|
|
291
|
+
brushSize: k,
|
|
292
|
+
imageMaskSrc: f,
|
|
293
|
+
imageBackgroundSrc: S,
|
|
294
|
+
onProgress: (c) => {
|
|
295
|
+
this.dispatchEvent(new CustomEvent("progress", { detail: { percent: c } }));
|
|
267
296
|
},
|
|
268
297
|
onComplete: () => {
|
|
269
298
|
this.dispatchEvent(new CustomEvent("complete", { detail: { percent: 100 } }));
|
|
270
299
|
}
|
|
271
|
-
}), this.instance.init()
|
|
300
|
+
}), this.instance.init().catch((c) => {
|
|
301
|
+
const g = c instanceof Error ? c.message : "ScratchReveal: init failed";
|
|
302
|
+
this.renderError(g);
|
|
303
|
+
}), (!i || !n) && "ResizeObserver" in window ? (this.resizeObserver?.disconnect(), this.resizeObserver = new ResizeObserver(() => {
|
|
272
304
|
if (this.hasAttribute("width") && this.hasAttribute("height")) {
|
|
273
305
|
this.resizeObserver?.disconnect(), this.resizeObserver = void 0;
|
|
274
306
|
return;
|
|
275
307
|
}
|
|
276
|
-
const
|
|
277
|
-
this.instance?.resize(
|
|
278
|
-
const x =
|
|
308
|
+
const c = this.getBoundingClientRect(), g = Math.round(c.width), w = Math.round(c.height);
|
|
309
|
+
this.instance?.resize(g, w);
|
|
310
|
+
const x = t(
|
|
279
311
|
this.getAttribute("brush-size"),
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
312
|
+
g,
|
|
313
|
+
w,
|
|
314
|
+
u.brushSize
|
|
283
315
|
);
|
|
284
316
|
this.instance?.setBrushSize(x);
|
|
285
317
|
}), this.resizeObserver.observe(this)) : (this.resizeObserver?.disconnect(), this.resizeObserver = void 0);
|
|
286
318
|
}
|
|
319
|
+
renderError(i) {
|
|
320
|
+
this.instance?.destroy(), this.instance = void 0, this.lastErrorMessage !== i && (this.lastErrorMessage = i, this.dispatchEvent(new CustomEvent("error", { detail: { message: i } })));
|
|
321
|
+
}
|
|
287
322
|
}
|
|
288
|
-
customElements.define(h,
|
|
323
|
+
customElements.define(h, e);
|
|
289
324
|
}
|
|
290
|
-
function
|
|
291
|
-
|
|
325
|
+
function T(h) {
|
|
326
|
+
I(), h.config.globalProperties.$scratchReveal = !0;
|
|
292
327
|
}
|
|
293
328
|
export {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
329
|
+
T as installScratchReveal,
|
|
330
|
+
I as registerScratchRevealElement,
|
|
331
|
+
A as scratchRevealCssText
|
|
297
332
|
};
|
package/dist/index.umd.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(o,l){typeof exports=="object"&&typeof module<"u"?l(exports):typeof define=="function"&&define.amd?define(["exports"],l):(o=typeof globalThis<"u"?globalThis:o||self,l(o.ScratchReveal={}))})(this,(function(o){"use strict";class l{ctx;mouseX;mouseY;constructor(t,e,s){this.ctx=t,this.mouseX=e,this.mouseY=s}updateMousePosition(t,e){this.mouseX=t,this.mouseY=e}brush(t,e=0){if(!t)
|
|
1
|
+
(function(o,l){typeof exports=="object"&&typeof module<"u"?l(exports):typeof define=="function"&&define.amd?define(["exports"],l):(o=typeof globalThis<"u"?globalThis:o||self,l(o.ScratchReveal={}))})(this,(function(o){"use strict";class l{ctx;mouseX;mouseY;constructor(t,e,s){this.ctx=t,this.mouseX=e,this.mouseY=s}updateMousePosition(t,e){this.mouseX=t,this.mouseY=e}brush(t,e=0){if(!t)return;const s=Math.atan2(this.mouseY,this.mouseX);if(this.ctx.save(),this.ctx.translate(this.mouseX,this.mouseY),this.ctx.rotate(s),e>0){const i=e,n=e*(t.height/t.width);this.ctx.drawImage(t,-(i/2),-(n/2),i,n)}else this.ctx.drawImage(t,-(t.width/2),-(t.height/2));this.ctx.restore()}}function f(h){return new Promise((t,e)=>{const s=new Image;s.crossOrigin="anonymous",s.onload=()=>t(s),s.onerror=()=>e(new Error(`Image ${h} failed to load`)),s.src=h})}function S(h){let t=0;return((...s)=>{t||(t=requestAnimationFrame(()=>{t=0,h(...s)}))})}const b=`.sr {
|
|
2
2
|
position: relative;
|
|
3
3
|
overflow: hidden;
|
|
4
4
|
width: 100%;
|
|
@@ -25,4 +25,4 @@ scratch-reveal {
|
|
|
25
25
|
width: 100%;
|
|
26
26
|
height: 100%;
|
|
27
27
|
}
|
|
28
|
-
`,
|
|
28
|
+
`,M=b;function R(h){return"adoptedStyleSheets"in h}function z(h){if(typeof CSSStyleSheet>"u")return null;try{const t=new CSSStyleSheet;return t.replaceSync(h),t}catch{return null}}const w=z(b),d={width:300,height:300,brushSrc:"",imageMaskSrc:"",imageBackgroundSrc:"",brushSize:0,percentToFinish:60};class C{config;ctx;container;_canvas;brush;maskImage;backgroundImage;brushImage;backgroundEl;brushSize=0;percent=0;done=!1;completing=!1;destroyed=!1;lastProgressEmitMs=0;lastScratchX;lastScratchY;removeListeners;get canvas(){return this._canvas}constructor(t,e={}){if(this.config={...d,...e},this.container=typeof t=="string"?document.querySelector(t):t,!this.container)throw new Error("ScratchReveal: container not found");this._canvas=this.createCanvas(this.config.width,this.config.height),this.ctx=this._canvas.getContext("2d",{willReadFrequently:!0}),this.brush=new l(this.ctx,0,0),this.brushSize=this.config.brushSize,this.container.appendChild(this._canvas)}async init(){if(!this.config.brushSrc)throw new Error('ScratchReveal: "brushSrc" is required');if(!this.config.imageMaskSrc)throw new Error('ScratchReveal: "imageMaskSrc" is required');if(!this.config.imageBackgroundSrc)throw new Error('ScratchReveal: "imageBackgroundSrc" is required');const[t,e,s]=await Promise.all([f(this.config.brushSrc),f(this.config.imageMaskSrc),f(this.config.imageBackgroundSrc)]);return this.destroyed?this:(this.brushImage=t,this.maskImage=e,this.backgroundImage=s,this.drawMask(),this.setBackground(),this.bindEvents(),this)}destroy(){this.destroyed=!0,this.removeListeners?.()}getPercent(){return this.percent}createCanvas(t,e){const s=document.createElement("canvas");return s.className="sr__canvas",s.width=t,s.height=e,s.style.width="100%",s.style.height="100%",s}resize(t,e){this.destroyed||this.done||t<=0||e<=0||this._canvas.width===t&&this._canvas.height===e||(this._canvas.width=t,this._canvas.height=e,this.percent=0,this.ctx.globalCompositeOperation="source-over",this.drawMask())}setBrushSize(t){this.destroyed||!Number.isFinite(t)||t<0||(this.brushSize=t)}bindEvents(){const e=S((r,a)=>{this.percent=this.updatePercent();const u=performance.now();(!this.lastProgressEmitMs||u-this.lastProgressEmitMs>=120)&&(this.lastProgressEmitMs=u,this.config.onProgress?.(this.percent)),this.finish(r,a)}),s=S(r=>{this.updatePosition(r),this.scratch(),e(r,s)}),i=r=>{r.preventDefault(),this.updatePosition(r),this.scratch(),this._canvas.setPointerCapture(r.pointerId),this._canvas.addEventListener("pointermove",s),this.resetScratchTrail(),this.percent=this.updatePercent(),this.config.onProgress?.(this.percent),this.finish(r,s)},n=r=>{this.resetScratchTrail(),this.percent=this.updatePercent(),this.config.onProgress?.(this.percent),this.finish(r,s)};this._canvas.addEventListener("pointerdown",i),this._canvas.addEventListener("pointerup",n),this._canvas.addEventListener("pointerleave",n),this.removeListeners=()=>{this._canvas.removeEventListener("pointerdown",i),this._canvas.removeEventListener("pointerup",n),this._canvas.removeEventListener("pointerleave",n),this._canvas.removeEventListener("pointermove",s)}}updatePosition(t){const e=this._canvas.getBoundingClientRect(),s=e.width?this._canvas.width/e.width:1,i=e.height?this._canvas.height/e.height:1,n=(t.clientX-e.left)*s,r=(t.clientY-e.top)*i;this.brush.updateMousePosition(n,r)}drawMask(){this.maskImage&&(this.ctx.globalCompositeOperation="source-over",this.ctx.clearRect(0,0,this._canvas.width,this._canvas.height),this.ctx.drawImage(this.maskImage,0,0,this._canvas.width,this._canvas.height))}setBackground(){if(this.destroyed||!this.backgroundImage||!this.container.contains(this._canvas))return;const t=this.backgroundEl??document.createElement("img");t.src=this.backgroundImage.src,t.className="sr__bg",t.isConnected||this.container.insertBefore(t,this._canvas),this.backgroundEl=t}scratch(){if(!this.brushImage)return;const t=this.brushSize>0?this.brushSize:Math.max(1,Math.min(this.brushImage.width,this.brushImage.height)),e=Math.max(2,t*.4);if(this.lastScratchX!==void 0&&this.lastScratchY!==void 0){const i=this.brush.mouseX-this.lastScratchX,n=this.brush.mouseY-this.lastScratchY;if(i*i+n*n<e*e)return}const s=this.brushSize>0?this.brushSize:0;this.ctx.globalCompositeOperation="destination-out",this.ctx.save(),this.brush.brush(this.brushImage,s),this.ctx.restore(),this.lastScratchX=this.brush.mouseX,this.lastScratchY=this.brush.mouseY}resetScratchTrail(){this.lastScratchX=void 0,this.lastScratchY=void 0}updatePercent(){const e=this.ctx.getImageData(0,0,this._canvas.width,this._canvas.height).data;let s=0;for(let i=3;i<e.length;i+=4)e[i]===0&&s++;return s/(this._canvas.width*this._canvas.height)*100}finish(t,e){if(!this.done&&this.percent>this.config.percentToFinish&&(this.done=!0,this._canvas.style.pointerEvents="none",this.config.onComplete?.(),this.playCompleteEffect(),t&&e)){try{this._canvas.releasePointerCapture(t.pointerId)}catch{}this._canvas.removeEventListener("pointermove",e)}}playCompleteEffect(){if(this.destroyed||this.completing)return;this.completing=!0;const t=350,e="ease-out";this._canvas.style.transition=`opacity ${t}ms ${e}`,this._canvas.style.opacity||(this._canvas.style.opacity="1"),requestAnimationFrame(()=>{this._canvas.style.opacity="0",window.setTimeout(()=>{this.destroyed||this.clear()},t)})}clear(){this.ctx.clearRect(0,0,this._canvas.width,this._canvas.height)}}function E(h="scratch-reveal"){if(typeof window>"u"||!("customElements"in window)||customElements.get(h))return;function t(s,i,n,r){if(!s)return r;const a=s.trim();if(!a)return r;const u=Number.parseFloat(a.endsWith("%")?a.slice(0,-1):a.endsWith("px")?a.slice(0,-2):a);if(!Number.isFinite(u))return r;if(a.endsWith("px"))return Math.max(0,u);const g=Math.min(i,n);return Math.max(0,g*u/100)}class e extends HTMLElement{instance;container;styleEl=null;rebuildScheduled=!1;resizeObserver;lastErrorMessage=null;static get observedAttributes(){return["width","height","complete-percent","brush-src","brush-size","mask-src","background-src"]}constructor(){super();const i=this.attachShadow({mode:"open"});R(i)&&w?i.adoptedStyleSheets=[w]:(this.styleEl=document.createElement("style"),this.styleEl.textContent=b,i.append(this.styleEl)),this.container=document.createElement("div"),this.container.className="sr",i.append(this.container)}connectedCallback(){this.scheduleRebuild()}disconnectedCallback(){this.instance?.destroy(),this.instance=void 0,this.resizeObserver?.disconnect(),this.resizeObserver=void 0}attributeChangedCallback(i,n,r){n!==r&&this.scheduleRebuild()}scheduleRebuild(){this.rebuildScheduled||(this.rebuildScheduled=!0,queueMicrotask(()=>{this.rebuildScheduled=!1,this.isConnected&&this.rebuild()}))}rebuild(){this.container.replaceChildren(),this.instance?.destroy();const i=this.hasAttribute("width"),n=this.hasAttribute("height"),r=this.getBoundingClientRect(),a=Math.round(r.width),u=Math.round(r.height),g=i?Number(this.getAttribute("width")):a||d.width,p=n?Number(this.getAttribute("height")):u||d.height,T=Number(this.getAttribute("complete-percent")??d.percentToFinish),y=(this.getAttribute("brush-src")??"").trim(),I=t(this.getAttribute("brush-size"),g,p,d.brushSize),_=(this.getAttribute("mask-src")??"").trim(),k=(this.getAttribute("background-src")??"").trim(),m=[];if(y||m.push("brush-src"),_||m.push("mask-src"),k||m.push("background-src"),m.length){const c=`ScratchReveal: missing required attribute(s): ${m.join(", ")}`;this.renderError(c);return}i?this.container.style.width=`${g}px`:this.container.style.width="100%",n?this.container.style.height=`${p}px`:this.container.style.height="100%",this.instance=new C(this.container,{width:g,height:p,percentToFinish:T,brushSrc:y,brushSize:I,imageMaskSrc:_,imageBackgroundSrc:k,onProgress:c=>{this.dispatchEvent(new CustomEvent("progress",{detail:{percent:c}}))},onComplete:()=>{this.dispatchEvent(new CustomEvent("complete",{detail:{percent:100}}))}}),this.instance.init().catch(c=>{const v=c instanceof Error?c.message:"ScratchReveal: init failed";this.renderError(v)}),(!i||!n)&&"ResizeObserver"in window?(this.resizeObserver?.disconnect(),this.resizeObserver=new ResizeObserver(()=>{if(this.hasAttribute("width")&&this.hasAttribute("height")){this.resizeObserver?.disconnect(),this.resizeObserver=void 0;return}const c=this.getBoundingClientRect(),v=Math.round(c.width),x=Math.round(c.height);this.instance?.resize(v,x);const A=t(this.getAttribute("brush-size"),v,x,d.brushSize);this.instance?.setBrushSize(A)}),this.resizeObserver.observe(this)):(this.resizeObserver?.disconnect(),this.resizeObserver=void 0)}renderError(i){this.instance?.destroy(),this.instance=void 0,this.lastErrorMessage!==i&&(this.lastErrorMessage=i,this.dispatchEvent(new CustomEvent("error",{detail:{message:i}})))}}customElements.define(h,e)}function P(h){E(),h.config.globalProperties.$scratchReveal=!0}o.installScratchReveal=P,o.registerScratchRevealElement=E,o.scratchRevealCssText=M,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})}));
|
package/dist/internal/utils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare function loadImage(src: string): Promise<HTMLImageElement>;
|
|
2
|
-
export declare function rafThrottle<
|
|
2
|
+
export declare function rafThrottle<Args extends unknown[]>(fn: (...args: Args) => void): (...args: Args) => void;
|
|
3
3
|
export declare function getOffset(element: HTMLElement): {
|
|
4
4
|
left: number;
|
|
5
5
|
top: number;
|
package/dist/options.d.ts
CHANGED
package/dist/scratch-reveal.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export declare const scratchRevealCssText: string;
|
|
2
2
|
export declare function registerScratchRevealElement(tagName?: string): void;
|
|
3
3
|
export declare function installScratchReveal(app: {
|
|
4
|
-
config:
|
|
4
|
+
config: {
|
|
5
|
+
globalProperties: Record<string, unknown>;
|
|
6
|
+
};
|
|
5
7
|
}): void;
|
package/package.json
CHANGED