vault66-crt-effect
Version:
A customizable CRT visual effect component for React
2 lines (1 loc) • 6.39 kB
CSS
/*! 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)}@keyframes 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%}/*! ANIMATION EFFECTS */.crt-effect-wrapper.flicker-on{animation:crt-flicker var(--flicker-speed, .8s) infinite}@keyframes 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}@keyframes 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}@keyframes 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}@keyframes 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 */@media (prefers-reduced-motion: reduce){.crt-noise{animation:none}.crt-inner.glitch-on.chromatic-on{animation:none;filter:none}.crt-effect-wrapper.sweep-on:before,.crt-effect-wrapper.sweep-soft:before{animation:none;display:none}.crt-effect-wrapper.flicker-on{animation:none;opacity:1}.crt-inner.glitch-on{animation:none;transform:none}}