scratch-reveal
v2.0.1
Published
Scratch & reveal Web Component: mask + background with brush-only reveal, Vue-friendly, shadow-styled.
Maintainers
Readme
scratch-reveal
Web Component for scratch-to-reveal: canvas mask, background beneath it, and a custom brush. Works in plain browsers and Vue 3.
- Registers
<scratch-reveal>with shadow DOM and constructable stylesheet fallback. - Canvas mask scratched away by a custom brush image; reveals a background layer underneath.
- Configurable completion threshold, brush size (percent or pixels), and auto-size mode.
- Dispatches
progress,complete, anderrorevents (bubbles+composedfor shadow DOM). - Ships
scratchRevealCssTextand a CSS sidecar; optional Vue 3 plugin helper.
Installation
npm install scratch-revealOptional stylesheet (sidecar):
import 'scratch-reveal/scratch-reveal.css';Quick Start
Register the custom element, then use it in markup:
import { registerScratchRevealElement } from 'scratch-reveal';
registerScratchRevealElement();<scratch-reveal
width="300"
height="300"
complete-percent="60"
show-status
brush-size="15"
brush-src="/assets/brush.png"
mask-src="/assets/scratch-reveal.png"
background-src="/assets/scratch-reveal-background.svg"
></scratch-reveal>Auto-size (follow parent/container)
<div style="width: 420px; height: 240px;">
<scratch-reveal
style="width: 100%; height: 100%;"
complete-percent="60"
show-status
brush-size="12"
brush-src="/assets/brush.png"
mask-src="/assets/scratch-reveal.png"
background-src="/assets/scratch-reveal-background.svg"
></scratch-reveal>
</div>If width / height attributes are omitted, the component observes its own size and resizes the canvas accordingly.
API
registerScratchRevealElement(tagName?)— defines<scratch-reveal>(or a custom tag name). Safe to call multiple times.installScratchReveal(app)— Vue 3 plugin helper; callsregisterScratchRevealElement()and setsapp.config.globalProperties.$scratchReveal.scratchRevealCssText— minified default CSS text shipped with the package.
Options
| Attribute | Type | Default | Description |
|:----------|:-----|:--------|:------------|
| width / height | number | 300 | Container/mask size in px. If omitted, size follows layout (auto-size). |
| complete-percent | number | 60 | Percent cleared to consider done. |
| brush-src | string | — | Brush image (required). |
| 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. |
| mask-src | string | — | Top mask (scratched away) (required). |
| background-src | string | — | Background beneath the mask (required). |
| show-status | boolean | — | Optional: render status message for missing attrs / errors (useful in development). |
Events
Listen on the element (events bubble and cross shadow boundaries):
const el = document.querySelector('scratch-reveal');
el.addEventListener('progress', (event) => {
console.log(event.detail.percent);
});
el.addEventListener('complete', () => {
console.log('done!');
});
el.addEventListener('error', (event) => {
console.error(event.detail.message);
});| Event | Detail | Description |
|:------|:-------|:------------|
| progress | { percent: number } | Fired while scratching (throttled). |
| complete | { percent: 100 } | Fired once when the threshold is reached. |
| error | { message: string } | Fired on load or configuration errors. |
Styling
Shadow styles use constructable stylesheets with a <style> fallback for older browsers.
Reuse the shipped CSS text:
import { scratchRevealCssText } from 'scratch-reveal';
// apply wherever you needOr import the sidecar:
import 'scratch-reveal/scratch-reveal.css';Vue 3.5+
import { createApp } from 'vue';
import { installScratchReveal } from 'scratch-reveal';
const app = createApp(App);
installScratchReveal(app);
app.mount('#app');For Volar/templates in a Vite app, mark the tag as a custom element in your vite.config.ts:
import vue from '@vitejs/plugin-vue';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag === 'scratch-reveal',
},
},
}),
],
});Or add a local module augmentation (for example scratch-reveal.d.ts):
import type { ComponentPublicInstance } from 'vue';
declare module 'vue' {
export interface GlobalComponents {
'scratch-reveal': ComponentPublicInstance;
}
}License
MIT
