UNPKG

ranui

Version:

A framework-agnostic Web Components UI library built on native custom elements, with TypeScript types, light/dark theming, SSR and PWA support.

106 lines (105 loc) 5.95 kB
import { _ as n, i as r, p as o } from "./factory-WDxu11V0.js"; import { t as d } from "./events-Cqz3ramM.js"; import "./builder-EH76YCFS.js"; import { i as l, l as u, n as b, o as p, t as k } from "./utils-U-9uH7EX.js"; import { a as v, n as g } from "./ssr-BzykYefm.js"; var w = ":host{position:relative;display:block;--ran-scratch-cover-background: var(--ran-color-text-secondary, #6b6b6b)}:host([hidden]){display:none}:host([disabled]){cursor:var(--ran-scratch-disabled-cursor, not-allowed);opacity:var(--ran-scratch-disabled-opacity, .6)}:host([disabled]) .ran-scratch-ticket-canvas{pointer-events:none}.ran-scratch-ticket{position:relative;display:block;width:100%;height:100%}.ran-scratch-ticket-award{position:absolute;top:0;left:0;display:block;width:100%;height:100%;background:var(--ran-scratch-award-background, var(--ran-color-bg-elevated, #fff));z-index:1}.ran-scratch-ticket-canvas{position:absolute;top:0;left:0;display:block;width:100%;height:100%;z-index:2;cursor:var(--ran-scratch-cursor, pointer);touch-action:none;-webkit-tap-highlight-color:transparent}", T = 0.35, f = class extends g { scratchTicketContainer; scratchTicket; state; scratchAward; _shadowDom; _events = new d(); static get observedAttributes() { return ["disabled", "sheet"]; } constructor() { super(), this._shadowDom = k(this, w); const t = n("canvas").class("ran-scratch-ticket-canvas").style("width", "100%").style("height", "100%").build(), e = r().class("ran-scratch-ticket-award").part("award").children(o()).build(), i = r().class("ran-scratch-ticket").children(t, e).build(); this._shadowDom.appendChild(i), this.scratchTicketContainer = i, this.scratchAward = e, this.scratchTicket = t, this.state = { isScratching: !1, scratchedArea: 0, lastX: 0, lastY: 0, activePointerId: void 0 }; } get disabled() { return u(this); } set disabled(t) { t ? this.setAttribute("disabled", "") : this.removeAttribute("disabled"); } get sheet() { return b(this, "sheet"); } set sheet(t) { l(this, "sheet", t); } handlerExternalCss = () => { p(this, this._shadowDom, "sheet", null, this.sheet); }; syncDisabled = () => { this.setAttribute("aria-disabled", this.disabled ? "true" : "false"); }; brushRadius = () => Math.max(14, Math.min(this.scratchTicket.width, this.scratchTicket.height) * 0.09); toCanvasPoint = (t, e) => { const i = this.scratchTicket.getBoundingClientRect(), s = i.width > 0 ? this.scratchTicket.width / i.width : 1, a = i.height > 0 ? this.scratchTicket.height / i.height : 1; return { x: (t - i.left) * s, y: (e - i.top) * a }; }; scratchStroke = (t, e, i, s) => { const a = this.scratchTicket.getContext("2d"); if (!a) return; const c = this.brushRadius(); a.globalCompositeOperation = "destination-out", a.lineCap = "round", a.lineJoin = "round", a.lineWidth = c * 2, a.beginPath(), a.moveTo(t, e), a.lineTo(i, s), a.stroke(); const h = Math.max(Math.hypot(i - t, s - e), 1); this.state.scratchedArea += h * c * 2; }; onScratchPointerDown = (t) => { if (this.disabled || this.state.isScratching || t.pointerType === "mouse" && t.button !== 0) return; t.preventDefault(), this.state.isScratching = !0, this.state.activePointerId = t.pointerId, this.scratchTicket.setPointerCapture?.(t.pointerId); const { x: e, y: i } = this.toCanvasPoint(t.clientX, t.clientY); this.state.lastX = e, this.state.lastY = i, this.scratchStroke(e, i, e, i); }; onScratchPointerMove = (t) => { if (this.disabled || !this.state.isScratching || t.pointerId !== this.state.activePointerId) return; const { x: e, y: i } = this.toCanvasPoint(t.clientX, t.clientY); this.scratchStroke(this.state.lastX, this.state.lastY, e, i), this.state.lastX = e, this.state.lastY = i; }; onScratchPointerUp = (t) => { if (t.pointerId !== this.state.activePointerId || (this.state.isScratching = !1, this.state.activePointerId = void 0, this.disabled)) return; const { width: e, height: i } = this.scratchTicket, s = this.scratchTicket.getContext("2d"); s && this.state.scratchedArea > e * i * T && (this.state.scratchedArea = 0, s.clearRect(0, 0, e, i)); }; drawScratchTicket = () => { const t = this.scratchTicket.getContext("2d"); if (!this.scratchTicketContainer || !t) return; const { width: e, height: i } = this.scratchTicket, s = getComputedStyle(this).getPropertyValue("--ran-scratch-cover-background").trim(); t.globalCompositeOperation = "source-over", t.fillStyle = s || "#6b6b6b", t.fillRect(0, 0, e, i); }; syncCanvasResolution = () => { const t = this.scratchTicketContainer.getBoundingClientRect(); if (t.width <= 0 || t.height <= 0) return; const e = window.devicePixelRatio || 1, i = Math.max(1, Math.round(t.width * e)), s = Math.max(1, Math.round(t.height * e)); this.scratchTicket.width === i && this.scratchTicket.height === s || (this.scratchTicket.width = i, this.scratchTicket.height = s, this.state.scratchedArea = 0, this.drawScratchTicket()); }; onWindowResize = () => { this.syncCanvasResolution(); }; connectedCallback() { this.handlerExternalCss(), this.syncDisabled(), this._events.on(this.scratchTicket, "pointerdown", this.onScratchPointerDown, { passive: !1 }).on(this.scratchTicket, "pointermove", this.onScratchPointerMove).on(this.scratchTicket, "pointerup", this.onScratchPointerUp).on(this.scratchTicket, "pointercancel", this.onScratchPointerUp).on(this.scratchTicket, "lostpointercapture", this.onScratchPointerUp).on(window, "resize", this.onWindowResize), this.syncCanvasResolution(); } disconnectedCallback() { this._events.abort(); } attributeChangedCallback(t, e, i) { e !== i && (t === "disabled" && this.syncDisabled(), t === "sheet" && this.handlerExternalCss(), this.drawScratchTicket()); } }; v("r-scratch", f); export { f as t };