16Glitch

Glitch

GSAPCyberpunkDigitalRetro

Digital distortion effect with RGB split, scanlines, and rapid position shifts. Cyberpunk aesthetic perfect for tech and gaming sites.

Quick Start

  • 📦npm install next-transition-router gsap
  • ⚡Use ease: 'steps(1)' for instant jumps
  • 🎨hue-rotate + saturate for color glitch
  • 📺Scanlines via repeating-linear-gradient

Installation

Terminal
1npm install next-transition-router gsap

Provider Setup

app/providers.tsx
1'use client'
2
3import { useRef } from 'react'
4import { TransitionRouter } from 'next-transition-router'
5import gsap from 'gsap'
6
7export default function GlitchProvider({ children }: { children: React.ReactNode }) {
8 const wrapperRef = useRef<HTMLDivElement>(null)
9 const overlayRef = useRef<HTMLDivElement>(null)
10 const scanlineRef = useRef<HTMLDivElement>(null)
11
12 return (
13 <>
14 <TransitionRouter
15 auto
16 leave={(next) => {
17 const tl = gsap.timeline({ onComplete: next })
18 const wrapper = wrapperRef.current
19
20 // Show scanlines
21 tl.to(scanlineRef.current, { opacity: 0.3, duration: 0.1 })
22
23 // Glitch - rapid position shifts
24 tl.to(wrapper, {
25 x: () => gsap.utils.random(-10, 10),
26 duration: 0.05,
27 repeat: 8,
28 yoyo: true,
29 ease: 'steps(1)',
30 })
31
32 // Color distortion
33 tl.to(wrapper, {
34 filter: 'saturate(2) hue-rotate(90deg)',
35 duration: 0.1,
36 }, '-=0.3')
37
38 // Flash
39 tl.to(overlayRef.current, {
40 opacity: 1,
41 duration: 0.15,
42 ease: 'steps(3)',
43 })
44
45 tl.set(wrapper, { opacity: 0 })
46 }}
47 enter={(next) => {
48 const tl = gsap.timeline({ onComplete: next })
49 const wrapper = wrapperRef.current
50
51 gsap.set(wrapper, { opacity: 0, x: 0, filter: 'none' })
52
53 tl.to(overlayRef.current, {
54 opacity: 0,
55 duration: 0.15,
56 ease: 'steps(3)',
57 })
58
59 tl.set(wrapper, { opacity: 1 })
60
61 tl.to(wrapper, {
62 x: () => gsap.utils.random(-8, 8),
63 duration: 0.05,
64 repeat: 6,
65 yoyo: true,
66 ease: 'steps(1)',
67 })
68
69 tl.to(wrapper, { x: 0, filter: 'none', duration: 0.1 })
70 tl.to(scanlineRef.current, { opacity: 0, duration: 0.2 })
71 }}
72 >
73 <div ref={wrapperRef}>{children}</div>
74 </TransitionRouter>
75
76 {/* Scanlines */}
77 <div ref={scanlineRef} style={{
78 position: 'fixed', inset: 0,
79 background: `repeating-linear-gradient(0deg,
80 rgba(0,0,0,0.15), rgba(0,0,0,0.15) 1px,
81 transparent 1px, transparent 2px)`,
82 zIndex: 9998, opacity: 0, pointerEvents: 'none',
83 }} />
84
85 {/* Flash overlay */}
86 <div ref={overlayRef} style={{
87 position: 'fixed', inset: 0,
88 background: '#0a0a0a', zIndex: 9999,
89 opacity: 0, pointerEvents: 'none',
90 }} />
91 </>
92 )
93}