vault66-crt-effect
Version:
A customizable CRT visual effect component for React
638 lines (637 loc) • 18.4 kB
JavaScript
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
};