vault66-crt-effect
Version:
A customizable CRT (retro monitor) visual effect for React, Vue, and Web Components
3 lines (2 loc) • 9.65 kB
JavaScript
"use strict";var v=Object.defineProperty;var w=(n,r,e)=>r in n?v(n,r,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[r]=e;var o=(n,r,e)=>w(n,typeof r!="symbol"?r+"":r,e);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const E=require("./core.cjs"),x=`/*! SWEEP LINE EFFECTS*/.crt-effect-wrapper.sweep-on:before{content:"";position:absolute;top:-30%;left:0;width:100%;height:var(--sweep-thickness, 10px);pointer-events:none;background:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.4) 40%,rgba(0,0,0,.6) 50%,rgba(8,8,8,.5) 50%,transparent 100%);animation:sweep-line var(--sweep-duration, 7s) linear infinite;z-index:9999;filter:blur(1.5px)}.crt-effect-wrapper.sweep-soft:before{content:"";position:absolute;top:-30%;left:0;width:100%;height:var(--sweep-thickness, 10px);pointer-events:none;background:linear-gradient(to bottom,transparent 0%,rgba(0,0,0,.15) 40%,rgba(0,0,0,.1) 50%,rgba(0,0,0,.08) 55%,transparent 100%);animation:sweep-line var(--sweep-duration, 7s) linear infinite;z-index:9999;filter:blur(5px)}.crt-effect-wrapper.sweep-colored.sweep-on:before,.crt-effect-wrapper.sweep-colored.sweep-soft:before{background:linear-gradient(to bottom,transparent 0%,var(--sweep-color, rgba(0, 255, 128, .5)) 50%,transparent 100%);mix-blend-mode:screen;filter:blur(8px)} sweep-line{0%{top:-30%}to{top:130%}}/*! SCANLINES EFFECT */.crt-effect-wrapper.scanlines-on:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;pointer-events:none;background-image:repeating-linear-gradient(var(--scanline-gradient-direction, to bottom),rgba(var(--scanline-color-rgb, 91, 179, 135),calc(var(--scanline-opacity, .035))) 0px,rgba(var(--scanline-color-rgb, 18, 58, 39),calc(var(--scanline-opacity, .2))) var(--scanline-thickness, 2px),transparent var(--scanline-thickness, 2px),transparent calc(var(--scanline-thickness, 2px) + var(--scanline-gap, 3px)));z-index:9998;mix-blend-mode:screen}/*! GLOW EFFECTS */.crt-edge-glow{pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0;box-shadow:inset 0 0 var(--edge-glow-size, 30px) var(--edge-glow-color, rgba(0, 255, 128, .2));z-index:9998}.crt-vignette{pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0;background:radial-gradient(ellipse at center,#0000 60%,rgba(0,0,0,var(--vignette-intensity, .4)));mix-blend-mode:multiply;z-index:9997}/*! CONTAINER ELEMENTS */.crt-inner{width:100%;height:100%}.crt-inner.tint-text-on{color:var(--crt-text-color, rgb(91, 179, 135));text-shadow:0 0 4px var(--crt-text-color, rgb(91, 179, 135))}/*! ANIMATION EFFECTS */.crt-effect-wrapper.flicker-on{animation:crt-flicker var(--flicker-speed, .8s) infinite} crt-flicker{0%,to{opacity:1}10%{opacity:calc(1 - var(--flicker-intensity, .15) * .53)}20%{opacity:calc(1 - var(--flicker-intensity, .15) * .13)}30%{opacity:calc(1 - var(--flicker-intensity, .15) * .8)}40%{opacity:calc(1 - var(--flicker-intensity, .15) * .33)}50%{opacity:calc(1 - var(--flicker-intensity, .15) * .67)}60%{opacity:1}70%{opacity:calc(1 - var(--flicker-intensity, .15) * 1)}80%{opacity:calc(1 - var(--flicker-intensity, .15) * .27)}90%{opacity:1}}.crt-inner.glitch-on{animation:glitch-fuzz var(--glitch-speed, .6s) ease-in-out infinite;will-change:transform} glitch-fuzz{0%,to{transform:translate(0) skew(0)}10%{transform:translate(calc(-2px * var(--glitch-intensity, 1)),calc(1px * var(--glitch-intensity, 1))) skew(calc(-.5deg * var(--glitch-intensity, 1)))}20%{transform:translate(0) skew(0)}30%{transform:translate(calc(3px * var(--glitch-intensity, 1)),calc(-1px * var(--glitch-intensity, 1))) skew(calc(.8deg * var(--glitch-intensity, 1)))}40%{transform:translate(0) skew(0)}50%{transform:translate(calc(-1px * var(--glitch-intensity, 1)),calc(2px * var(--glitch-intensity, 1))) skew(calc(-.3deg * var(--glitch-intensity, 1)))}60%{transform:translate(0) skew(0)}70%{transform:translate(calc(2px * var(--glitch-intensity, 1)),calc(-2px * var(--glitch-intensity, 1))) skew(calc(.6deg * var(--glitch-intensity, 1)))}80%,90%{transform:translate(0) skew(0)}}/*! CURVED SCREEN (GLASS) EFFECT */.crt-curvature{pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0;background:radial-gradient(ellipse 75% 75% at 30% 25%,rgba(255,255,255,.05) 0%,transparent 55%),radial-gradient(ellipse 100% 100% at 50% 50%,transparent 0%,transparent 42%,rgba(0,0,0,calc(var(--curvature-intensity, .5) * .35)) 72%,rgba(0,0,0,calc(var(--curvature-intensity, .5) * .9)) 100%);z-index:9995}/*! GLARE (SCREEN REFLECTION) EFFECT */.crt-glare{pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0;background:linear-gradient(115deg,transparent 0%,rgba(255,255,255,calc(var(--glare-intensity, .1) * .15)) 22%,rgba(255,255,255,calc(var(--glare-intensity, .1) * .45)) 42%,rgba(255,255,255,calc(var(--glare-intensity, .1) * .55)) 50%,rgba(255,255,255,calc(var(--glare-intensity, .1) * .45)) 58%,rgba(255,255,255,calc(var(--glare-intensity, .1) * .15)) 78%,transparent 100%),linear-gradient(180deg,rgba(255,255,255,calc(var(--glare-intensity, .1) * .4)) 0%,transparent 42%);z-index:9997}/*! NOISE (STATIC / SNOW) EFFECT */.crt-noise{pointer-events:none;position:absolute;top:-50%;left:-50%;width:200%;height:200%;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='turbulence' baseFrequency='0.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");background-size:180px 180px;background-repeat:repeat;opacity:var(--noise-opacity, .08);mix-blend-mode:screen;z-index:9996;animation:crt-noise .5s steps(4) infinite;will-change:transform} crt-noise{0%{transform:translate(0)}25%{transform:translate(-3%,2%)}50%{transform:translate(2%,-3%)}75%{transform:translate(-2%,-2%)}to{transform:translate(0)}}/*! CHROMATIC ABERRATION (RGB SPLIT) GLITCH */.crt-inner.glitch-on.chromatic-on{animation:glitch-fuzz var(--glitch-speed, .6s) ease-in-out infinite,glitch-chroma var(--glitch-speed, .6s) ease-in-out infinite} glitch-chroma{0%,to{filter:none}10%{filter:drop-shadow(calc(2px * var(--glitch-intensity, 1)) 0 rgba(255,0,60,.5)) drop-shadow(calc(-2px * var(--glitch-intensity, 1)) 0 rgba(0,255,255,.5))}30%{filter:drop-shadow(calc(-3px * var(--glitch-intensity, 1)) 0 rgba(255,0,60,.5)) drop-shadow(calc(3px * var(--glitch-intensity, 1)) 0 rgba(0,255,255,.5))}50%{filter:hue-rotate(40deg)}70%{filter:drop-shadow(calc(2px * var(--glitch-intensity, 1)) 0 rgba(255,0,60,.5)) drop-shadow(calc(-2px * var(--glitch-intensity, 1)) 0 rgba(0,255,255,.5))}}/*! ACCESSIBILITY */ (prefers-reduced-motion: reduce){.crt-noise{animation:none!important}.crt-inner.glitch-on.chromatic-on{animation:none!important;filter:none!important}.crt-effect-wrapper.sweep-on:before,.crt-effect-wrapper.sweep-soft:before{animation:none!important;display:none}.crt-effect-wrapper.flicker-on{animation:none!important;opacity:1!important}.crt-inner.glitch-on{animation:none!important;transform:none!important}}`,p="crt-effect",g=["enabled","fill","enable-scanlines","enable-sweep","enable-glow","enable-edge-glow","enable-flicker","enable-glitch","glitch-chromatic","enable-vignette","enable-curvature","enable-glare","enable-noise","tint-text"],d=["sweep-duration","sweep-thickness","scanline-opacity","scanline-thickness","scanline-gap","edge-glow-size","vignette-intensity","curvature-intensity","glare-intensity","noise-opacity"],f=["preset","theme","sweep-style","scanline-orientation","scanline-color","glow-color","edge-glow-color","text-color","sweep-color"],h=["flicker-intensity","flicker-speed","glitch-intensity","glitch-speed"],k=[...g,...d,...f,...h],s=n=>n.replace(/-([a-z])/g,(r,e)=>e.toUpperCase()),S=n=>n.startsWith("--")?n:n.replace(/[A-Z]/g,r=>`-${r.toLowerCase()}`),l=n=>Object.entries(n).map(([r,e])=>`${S(r)}:${e}`).join(";"),C=`:host{display:block}:host([hidden]){display:none}
`;class c extends HTMLElement{constructor(){super();o(this,"root");o(this,"mount");o(this,"connected",!1);this.root=this.attachShadow({mode:"open"});const e=C+x;if(typeof CSSStyleSheet<"u"&&"replaceSync"in CSSStyleSheet.prototype&&"adoptedStyleSheets"in this.root){const t=new CSSStyleSheet;t.replaceSync(e),this.root.adoptedStyleSheets=[t]}else{const t=document.createElement("style");t.textContent=e,this.root.appendChild(t)}this.mount=document.createElement("div"),this.mount.style.display="contents",this.root.appendChild(this.mount)}static get observedAttributes(){return k}connectedCallback(){this.connected=!0,this.render()}attributeChangedCallback(){this.connected&&this.render()}readOptions(){const e={};for(const t of g)this.hasAttribute(t)&&(e[s(t)]=this.getAttribute(t)!=="false");for(const t of d)if(this.hasAttribute(t)){const i=parseFloat(this.getAttribute(t)??"");Number.isNaN(i)||(e[s(t)]=i)}for(const t of f)this.hasAttribute(t)&&(e[s(t)]=this.getAttribute(t));for(const t of h)if(this.hasAttribute(t)){const i=this.getAttribute(t)??"",a=Number(i);e[s(t)]=i!==""&&!Number.isNaN(a)?a:i}return e}render(){const{enabled:e,wrapper:t,inner:i,overlays:a}=E.computeCrt(this.readOptions());if(!e){this.mount.innerHTML="<slot></slot>";return}const m=i.style?` style="${l(i.style)}"`:"",u=a.map(y=>`<div class="${y}"></div>`).join("");this.mount.innerHTML=`<div class="${t.className}" style="${l(t.style)}"><div class="${i.className}"${m}><slot></slot></div>`+u+"</div>"}}function b(n=p){typeof customElements<"u"&&!customElements.get(n)&&customElements.define(n,c)}b();exports.CRTEffectElement=c;exports.CRT_EFFECT_TAG=p;exports.default=c;exports.defineCrtEffect=b;