ranui
Version:
A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.
78 lines (77 loc) • 4.01 kB
TypeScript
import { EventManager } from '../../utils/builder';
import { RanElement } from '../../utils';
declare class ScratchTicket extends RanElement {
scratchTicketContainer: HTMLDivElement;
scratchTicket: HTMLCanvasElement;
state: {
isScratching: boolean;
scratchedArea: number;
lastX: number;
lastY: number;
/** The one pointer currently driving the scratch — see `onScratchPointerDown`. */
activePointerId?: number;
};
scratchAward: HTMLDivElement;
_shadowDom: ShadowRoot;
_events: EventManager;
static get observedAttributes(): string[];
constructor();
get disabled(): boolean;
set disabled(value: boolean);
get sheet(): string;
set sheet(value: string);
handlerExternalCss: () => void;
syncDisabled: () => void;
/**
* Radius (canvas-space px) of the "coin" doing the scratching — scaled to the
* canvas's own resolution so it reads as the same relative size regardless of
* the element's actual display size or devicePixelRatio.
*/
private brushRadius;
/** Maps a pointer event's viewport coordinates onto the canvas's own drawing-buffer
* coordinate space — the two can differ (CSS size vs. canvas resolution / devicePixelRatio),
* so a raw `clientX - rect.left` would scratch the wrong spot on anything but a 1:1 canvas. */
private toCanvasPoint;
/**
* Erases a stroke from `(fromX, fromY)` to `(toX, toY)` — a connected line, not an
* isolated dab, so a fast drag reveals a continuous trail instead of a dotted one.
* `scratchedArea` approximates the stroked rectangle (`length × brush diameter`); it's
* a coarse heuristic (not an actual transparent-pixel count) but is honest about how
* much the user has actually swept, unlike a flat per-event increment.
*/
private scratchStroke;
/**
* Pointer Events unify mouse/touch/pen — one code path scratches on both desktop and
* mobile — but "unify" doesn't mean "identical", so a few device-specific guards:
*
* - **Mouse**: `pointerdown` fires for *every* button, not just the primary one — a
* right-click-drag (e.g. opening a browser context-menu gesture) or a middle-click
* shouldn't scratch. `e.button !== 0` on a mouse pointer bails out before arming.
* - **Touch**: a second finger touching mid-scratch fires a *second* `pointerdown`
* with a different `pointerId`, while the first finger may still be down. Without
* tracking which pointer is actually driving the stroke, that second touch would
* silently take over `lastX`/`lastY`, so `pointermove`s from *either* finger jump
* between two unrelated positions. `activePointerId` pins the interaction to
* whichever pointer started it; every other pointer's events are ignored until it
* ends (`pointerup`/`pointercancel`/`lostpointercapture`).
*/
onScratchPointerDown: (e: PointerEvent) => void;
onScratchPointerMove: (e: PointerEvent) => void;
onScratchPointerUp: (e: PointerEvent) => void;
drawScratchTicket: () => void;
/**
* Matches the canvas's internal drawing-buffer resolution to its actual rendered
* CSS size (× devicePixelRatio for crisp strokes on HiDPI screens) instead of the
* browser's fixed 300×150 default. Without this, `toCanvasPoint` still maps pointer
* coordinates correctly (it accounts for whatever scale is in effect), but the cover
* itself renders soft/blurry once CSS stretches a 300×150 buffer to the element's
* real size — and resetting the buffer always clears prior scratch progress, which
* is the correct behavior for a real resize (e.g. an orientation change).
*/
syncCanvasResolution: () => void;
private onWindowResize;
connectedCallback(): void;
disconnectedCallback(): void;
attributeChangedCallback(name: string, old: string, next: string): void;
}
export default ScratchTicket;