UNPKG

vault66-crt-effect

Version:

A customizable CRT visual effect component for React

638 lines (637 loc) 18.4 kB
import te from "react"; var z = { exports: {} }, _ = {}; /** * @license React * react-jsx-runtime.production.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var K; function ae() { if (K) return _; K = 1; var c = Symbol.for("react.transitional.element"), d = Symbol.for("react.fragment"); function f(g, l, i) { var m = null; if (i !== void 0 && (m = "" + i), l.key !== void 0 && (m = "" + l.key), "key" in l) { i = {}; for (var w in l) w !== "key" && (i[w] = l[w]); } else i = l; return l = i.ref, { $$typeof: c, type: g, key: m, ref: l !== void 0 ? l : null, props: i }; } return _.Fragment = d, _.jsx = f, _.jsxs = f, _; } var O = {}; /** * @license React * react-jsx-runtime.development.js * * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ var ee; function le() { return ee || (ee = 1, process.env.NODE_ENV !== "production" && function() { function c(e) { if (e == null) return null; if (typeof e == "function") return e.$$typeof === k ? null : e.displayName || e.name || null; if (typeof e == "string") return e; switch (e) { case E: return "Fragment"; case j: return "Profiler"; case U: return "StrictMode"; case B: return "Suspense"; case X: return "SuspenseList"; case y: return "Activity"; } if (typeof e == "object") switch (typeof e.tag == "number" && console.error( "Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue." ), e.$$typeof) { case W: return "Portal"; case J: return (e.displayName || "Context") + ".Provider"; case q: return (e._context.displayName || "Context") + ".Consumer"; case N: var n = e.render; return e = e.displayName, e || (e = n.displayName || n.name || "", e = e !== "" ? "ForwardRef(" + e + ")" : "ForwardRef"), e; case H: return n = e.displayName || null, n !== null ? n : c(e.type) || "Memo"; case A: n = e._payload, e = e._init; try { return c(e(n)); } catch { } } return null; } function d(e) { return "" + e; } function f(e) { try { d(e); var n = !1; } catch { n = !0; } if (n) { n = console; var r = n.error, t = typeof Symbol == "function" && Symbol.toStringTag && e[Symbol.toStringTag] || e.constructor.name || "Object"; return r.call( n, "The provided key is an unsupported type %s. This value must be coerced to a string before using it here.", t ), d(e); } } function g(e) { if (e === E) return "<>"; if (typeof e == "object" && e !== null && e.$$typeof === A) return "<...>"; try { var n = c(e); return n ? "<" + n + ">" : "<...>"; } catch { return "<...>"; } } function l() { var e = b.A; return e === null ? null : e.getOwner(); } function i() { return Error("react-stack-top-frame"); } function m(e) { if (h.call(e, "key")) { var n = Object.getOwnPropertyDescriptor(e, "key").get; if (n && n.isReactWarning) return !1; } return e.key !== void 0; } function w(e, n) { function r() { F || (F = !0, console.error( "%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)", n )); } r.isReactWarning = !0, Object.defineProperty(e, "key", { get: r, configurable: !0 }); } function M() { var e = c(this.type); return $[e] || ($[e] = !0, console.error( "Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release." )), e = this.props.ref, e !== void 0 ? e : null; } function L(e, n, r, t, o, s, T, R) { return r = s.ref, e = { $$typeof: I, type: e, key: n, props: s, _owner: o }, (r !== void 0 ? r : null) !== null ? Object.defineProperty(e, "ref", { enumerable: !1, get: M }) : Object.defineProperty(e, "ref", { enumerable: !1, value: null }), e._store = {}, Object.defineProperty(e._store, "validated", { configurable: !1, enumerable: !1, writable: !0, value: 0 }), Object.defineProperty(e, "_debugInfo", { configurable: !1, enumerable: !1, writable: !0, value: null }), Object.defineProperty(e, "_debugStack", { configurable: !1, enumerable: !1, writable: !0, value: T }), Object.defineProperty(e, "_debugTask", { configurable: !1, enumerable: !1, writable: !0, value: R }), Object.freeze && (Object.freeze(e.props), Object.freeze(e)), e; } function C(e, n, r, t, o, s, T, R) { var a = n.children; if (a !== void 0) if (t) if (P(a)) { for (t = 0; t < a.length; t++) x(a[t]); Object.freeze && Object.freeze(a); } else console.error( "React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead." ); else x(a); if (h.call(n, "key")) { a = c(e); var p = Object.keys(n).filter(function(Z) { return Z !== "key"; }); t = 0 < p.length ? "{key: someKey, " + p.join(": ..., ") + ": ...}" : "{key: someKey}", V[a + t] || (p = 0 < p.length ? "{" + p.join(": ..., ") + ": ...}" : "{}", console.error( `A props object containing a "key" prop is being spread into JSX: let props = %s; <%s {...props} /> React keys must be passed directly to JSX without using spread: let props = %s; <%s key={someKey} {...props} />`, t, a, p, a ), V[a + t] = !0); } if (a = null, r !== void 0 && (f(r), a = "" + r), m(n) && (f(n.key), a = "" + n.key), "key" in n) { r = {}; for (var G in n) G !== "key" && (r[G] = n[G]); } else r = n; return a && w( r, typeof e == "function" ? e.displayName || e.name || "Unknown" : e ), L( e, a, s, o, l(), r, T, R ); } function x(e) { typeof e == "object" && e !== null && e.$$typeof === I && e._store && (e._store.validated = 1); } var v = te, I = Symbol.for("react.transitional.element"), W = Symbol.for("react.portal"), E = Symbol.for("react.fragment"), U = Symbol.for("react.strict_mode"), j = Symbol.for("react.profiler"), q = Symbol.for("react.consumer"), J = Symbol.for("react.context"), N = Symbol.for("react.forward_ref"), B = Symbol.for("react.suspense"), X = Symbol.for("react.suspense_list"), H = Symbol.for("react.memo"), A = Symbol.for("react.lazy"), y = Symbol.for("react.activity"), k = Symbol.for("react.client.reference"), b = v.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE, h = Object.prototype.hasOwnProperty, P = Array.isArray, S = console.createTask ? console.createTask : function() { return null; }; v = { "react-stack-bottom-frame": function(e) { return e(); } }; var F, $ = {}, Y = v["react-stack-bottom-frame"].bind( v, i )(), D = S(g(i)), V = {}; O.Fragment = E, O.jsx = function(e, n, r, t, o) { var s = 1e4 > b.recentlyCreatedOwnerStacks++; return C( e, n, r, !1, t, o, s ? Error("react-stack-top-frame") : Y, s ? S(g(e)) : D ); }, O.jsxs = function(e, n, r, t, o) { var s = 1e4 > b.recentlyCreatedOwnerStacks++; return C( e, n, r, !0, t, o, s ? Error("react-stack-top-frame") : Y, s ? S(g(e)) : D ); }; }()), O; } var ne; function se() { return ne || (ne = 1, process.env.NODE_ENV === "production" ? z.exports = ae() : z.exports = le()), z.exports; } var u = se(); const ie = { /** * FALLOUT */ fallout: { theme: "green", enableScanlines: !0, scanlineOpacity: 0.25, scanlineThickness: 2, scanlineGap: 3, enableSweep: !0, sweepDuration: 12, sweepThickness: 10, sweepStyle: "classic", enableGlow: !1, enableEdgeGlow: !0, edgeGlowColor: "rgba(91, 179, 135, 0.5)", edgeGlowSize: 40, enableFlicker: !0, flickerIntensity: 0.05, flickerSpeed: 1.5, enableVignette: !0, vignetteIntensity: 0.3, enableGlitch: !1, enableCurvature: !0, curvatureIntensity: 0.6, enableNoise: !0, noiseOpacity: 0.2 }, /** * DOS - Classic DOS/Hercules monitor */ dos: { theme: "custom", scanlineColor: "rgba(255, 100, 0, 0.3)", enableScanlines: !0, scanlineOpacity: 0.2, scanlineThickness: 2, scanlineGap: 4, enableSweep: !1, enableGlow: !1, enableEdgeGlow: !1, enableFlicker: !1, enableVignette: !0, vignetteIntensity: 0.25, enableGlitch: !1, enableCurvature: !0, curvatureIntensity: 0.55 }, /** * CYBERPUNK */ cyberpunk: { theme: "custom", scanlineColor: "rgba(255, 0, 255, 0.3)", enableScanlines: !0, scanlineOpacity: 0.35, scanlineThickness: 2, scanlineGap: 2, enableSweep: !0, sweepDuration: 5, sweepThickness: 15, sweepStyle: "classic", enableGlow: !0, glowColor: "rgba(255, 0, 200, 0.5)", enableEdgeGlow: !0, edgeGlowColor: "rgba(200, 0, 255, 0.6)", edgeGlowSize: 50, enableFlicker: !0, flickerIntensity: 0.08, flickerSpeed: 0.8, enableVignette: !0, vignetteIntensity: 0.4, enableGlitch: !0, glitchIntensity: 0.3, glitchSpeed: 1, glitchChromatic: !0, enableCurvature: !0, curvatureIntensity: 0.7, enableGlare: !0, glareIntensity: 0.25, enableNoise: !0, noiseOpacity: 0.18 }, /** * COMMODORE 64 - 8-bit computer */ commodore64: { theme: "custom", scanlineColor: "rgba(160, 160, 255, 0.35)", enableScanlines: !0, scanlineOpacity: 0.35, scanlineThickness: 3, scanlineGap: 2, enableSweep: !0, sweepDuration: 10, sweepThickness: 12, sweepStyle: "classic", enableGlow: !1, enableEdgeGlow: !1, enableFlicker: !0, flickerIntensity: 0.05, flickerSpeed: 1.5, enableVignette: !0, vignetteIntensity: 0.35, enableGlitch: !1, enableCurvature: !0, curvatureIntensity: 0.6, enableNoise: !0, noiseOpacity: 0.15 }, /** * APPLE II - Vintage Apple computer terminal */ apple2: { theme: "custom", scanlineColor: "rgba(120, 220, 80, 0.3)", enableScanlines: !0, scanlineOpacity: 0.3, scanlineThickness: 1, scanlineGap: 2, enableSweep: !1, enableGlow: !1, enableEdgeGlow: !1, enableFlicker: !1, enableVignette: !0, vignetteIntensity: 0.2, enableGlitch: !1, enableCurvature: !0, curvatureIntensity: 0.55 }, /** * ARCADE - Retro arcade cabinet monitor */ arcade: { theme: "custom", scanlineColor: "rgba(0, 255, 100, 0.4)", enableScanlines: !0, scanlineOpacity: 0.4, scanlineThickness: 3, scanlineGap: 3, enableSweep: !0, sweepDuration: 4, sweepThickness: 15, sweepStyle: "classic", enableGlow: !0, glowColor: "rgba(0, 255, 100, 0.5)", enableEdgeGlow: !0, edgeGlowColor: "rgba(0, 255, 100, 0.6)", edgeGlowSize: 45, enableFlicker: !0, flickerIntensity: 0.08, flickerSpeed: 0.8, enableVignette: !0, vignetteIntensity: 0.45, enableGlitch: !1, enableCurvature: !0, curvatureIntensity: 0.7, enableGlare: !0, glareIntensity: 0.3 }, /** * VT100 - Classic DEC terminal */ vt100: { theme: "custom", scanlineColor: "rgba(220, 255, 235, 0.2)", enableScanlines: !0, scanlineOpacity: 0.15, scanlineThickness: 2, scanlineGap: 4, enableSweep: !1, enableGlow: !1, enableEdgeGlow: !1, enableFlicker: !1, enableVignette: !0, vignetteIntensity: 0.15, enableGlitch: !1, enableCurvature: !0, curvatureIntensity: 0.45 }, /** * MINIMAL - Subtle CRT effect */ minimal: { theme: "green", enableScanlines: !0, scanlineOpacity: 0.1, scanlineThickness: 1, scanlineGap: 4, enableSweep: !1, enableGlow: !1, enableEdgeGlow: !1, enableFlicker: !1, enableVignette: !0, vignetteIntensity: 0.2, enableGlitch: !1 } }; //! CRT EFFECT COMPONENT PROPS //! MAIN CRT EFFECT COMPONENT const ue = (c) => { const { preset: d, children: f, ...g } = c, l = d ? ie[d] : {}, m = { ...{ enabled: !0, sweepDuration: 10, sweepThickness: 10, sweepStyle: "classic", scanlineOpacity: 0.2, scanlineColor: "rgba(91, 179, 135, 0.2)", scanlineThickness: 2, scanlineGap: 3, enableScanlines: !0, enableSweep: !0, theme: "green", enableGlow: !1, glowColor: "rgba(0, 255, 128, 0.3)", enableEdgeGlow: !1, edgeGlowColor: "rgba(0, 255, 128, 0.2)", edgeGlowSize: 30, enableFlicker: !1, scanlineOrientation: "horizontal", glitchIntensity: 1, glitchSpeed: 0.6, flickerIntensity: 0.08, flickerSpeed: 0.8, enableGlitch: !1, enableVignette: !1, vignetteIntensity: 0.4, enableCurvature: !1, curvatureIntensity: 0.5, enableGlare: !1, glareIntensity: 0.18, enableNoise: !1, noiseOpacity: 0.15, glitchChromatic: !1 }, ...l, ...g }, { enabled: w, sweepDuration: M, sweepThickness: L, sweepStyle: C, scanlineOpacity: x, scanlineColor: v, scanlineThickness: I, scanlineGap: W, enableScanlines: E, enableSweep: U, theme: j, enableGlow: q, glowColor: J, enableEdgeGlow: N, edgeGlowColor: B, edgeGlowSize: X, enableFlicker: H, scanlineOrientation: A, glitchIntensity: y, glitchSpeed: k, flickerIntensity: b, flickerSpeed: h, enableGlitch: P, enableVignette: S, vignetteIntensity: F, enableCurvature: $, curvatureIntensity: Y, enableGlare: D, glareIntensity: V, enableNoise: e, noiseOpacity: n, glitchChromatic: r } = m; if (!w) return /* @__PURE__ */ u.jsx(u.Fragment, { children: f }); //! COLOR PROCESSING UTILITIES const t = (Z) => { const Q = Z.match(/rgba?\(\s*([\d\s.,]+)\)/); return Q ? Q[1].split(",").map((re) => re.trim()).slice(0, 3).join(", ") : "91, 179, 135"; }, o = { green: "91, 179, 135", // Classic CRT green amber: "255, 200, 100", // Vintage amber monitor blue: "100, 200, 255" // Retro blue terminal }, s = j !== "custom" ? o[j] ?? o.green : t(v); //! CSS CLASS NAME COMPOSITION const T = [ "crt-effect-wrapper", // Base wrapper class E && "scanlines-on", // Add scanlines if enabled U && (C === "classic" ? "sweep-on" : "sweep-soft"), // Add sweep style N && "edge-glow-on", // Add edge glow if enabled H && "flicker-on" // Add flicker if enabled ].filter(Boolean).join(" "); //! ANIMATION SPEED AND INTENSITY PROCESSING const R = typeof b == "number" ? b : b === "low" ? 0.05 : b === "high" ? 0.12 : 0.08, a = typeof h == "number" ? `${h}s` : h === "low" ? "1.5s" : h === "high" ? "0.4s" : "0.8s", p = typeof y == "number" ? y : y === "low" ? 0.3 : y === "high" ? 0.9 : 0.6, G = typeof k == "number" ? `${k}s` : k === "low" ? "1s" : k === "high" ? "0.3s" : "0.6s"; //! MAIN COMPONENT RENDER return /* @__PURE__ */ u.jsxs( "div", { className: T, style: { position: "relative", // Enable positioning for pseudo-elements overflow: "hidden", // Clip sweep and scanlines to container // CSS custom properties for dynamic styling "--sweep-duration": `${M}s`, "--sweep-thickness": `${L}px`, "--scanline-opacity": x, "--scanline-color-rgb": s, "--scanline-thickness": `${I}px`, "--scanline-gap": `${W}px`, "--glow-color": J, "--edge-glow-color": B, "--edge-glow-size": `${X}px`, // Convert orientation to CSS gradient direction "--scanline-gradient-direction": A === "horizontal" ? "to bottom" : "to right", "--glitch-speed": G, "--glitch-intensity": p, "--flicker-speed": a, "--flicker-intensity": R, "--vignette-intensity": F, "--curvature-intensity": Y, "--glare-intensity": V, "--noise-opacity": n, // Outer glow using filter (not clipped by overflow) filter: q ? "drop-shadow(0 0 6px var(--glow-color)) drop-shadow(0 0 12px var(--glow-color)) drop-shadow(0 0 20px var(--glow-color))" : void 0 }, children: [ /* @__PURE__ */ u.jsx( "div", { className: [ "crt-inner", P ? "glitch-on" : "", P && r ? "chromatic-on" : "" ].filter(Boolean).join(" "), children: f } ), $ && /* @__PURE__ */ u.jsx("div", { className: "crt-curvature" }), e && /* @__PURE__ */ u.jsx("div", { className: "crt-noise" }), D && /* @__PURE__ */ u.jsx("div", { className: "crt-glare" }), N && /* @__PURE__ */ u.jsx("div", { className: "crt-edge-glow" }), S && /* @__PURE__ */ u.jsx("div", { className: "crt-vignette" }) ] } ); }; export { ue as default, ie as presets };