Custom Code Experiment •
SVG: Animated Glyph
Source Code View HTML / CSS / JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SVG: Animated Glyph - Glitch Edition</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
background-color: #000;
overflow: hidden;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
position: relative;
}
/* Glitch Background Effects */
.glitch-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 0;
opacity: 0.7;
}
.color-grid {
position: absolute;
width: 100%;
height: 100%;
background:
linear-gradient(90deg,
transparent 0%,
transparent 50%,
rgba(255, 0, 255, 0.1) 50%,
rgba(255, 0, 255, 0.1) 100%),
linear-gradient(0deg,
transparent 0%,
transparent 50%,
rgba(0, 255, 255, 0.1) 50%,
rgba(0, 255, 255, 0.1) 100%);
background-size: 50px 50px;
animation: gridMove 20s linear infinite;
mix-blend-mode: screen;
}
.noise {
position: absolute;
width: 100%;
height: 100%;
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='0.3'/%3E%3C/svg%3E");
opacity: 0.4;
animation: noise 0.2s steps(10) infinite;
}
.color-burst {
position: absolute;
width: 100%;
height: 100%;
background: radial-gradient(circle at 30% 50%,
rgba(255, 0, 255, 0.2) 0%,
transparent 50%),
radial-gradient(circle at 70% 20%,
rgba(0, 255, 255, 0.2) 0%,
transparent 50%),
radial-gradient(circle at 50% 80%,
rgba(255, 255, 0, 0.2) 0%,
transparent 50%);
animation: colorPulse 4s ease-in-out infinite;
mix-blend-mode: overlay;
}
.scanlines {
position: absolute;
width: 100%;
height: 100%;
background: repeating-linear-gradient(
0deg,
transparent,
transparent 2px,
rgba(0, 255, 255, 0.05) 2px,
rgba(0, 255, 255, 0.05) 4px
);
animation: scanline 10s linear infinite;
}
.glitch-overlay {
position: absolute;
width: 100%;
height: 100%;
background: linear-gradient(45deg,
#ff00ff 0%,
#00ffff 25%,
#ffff00 50%,
#ff00ff 75%,
#00ffff 100%);
opacity: 0;
mix-blend-mode: hard-light;
animation: glitchFlash 3s infinite;
}
.container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
position: relative;
z-index: 1;
}
svg {
width: 90vmin;
height: 90vmin;
max-width: 800px;
max-height: 800px;
filter:
brightness(1.2)
contrast(1.1)
drop-shadow(0 0 10px rgba(0, 255, 255, 0.3))
drop-shadow(0 0 20px rgba(255, 0, 255, 0.2));
animation: svgGlitch 5s infinite;
}
use {
stroke: #ffffff;
stroke-width: 0.5;
}
.frontCross {
animation: colorShift 2s infinite alternate;
}
.instructions {
position: absolute;
bottom: 20px;
color: #0ff;
font-family: 'Courier New', monospace;
font-size: 14px;
text-align: center;
width: 100%;
text-shadow: 0 0 10px #0ff, 0 0 20px #0ff;
z-index: 2;
animation: textGlitch 5s infinite;
}
/* Animations */
@keyframes gridMove {
0% { background-position: 0 0; }
100% { background-position: 100px 100px; }
}
@keyframes noise {
0% { transform: translate(0, 0); }
100% { transform: translate(10px, 10px); }
}
@keyframes colorPulse {
0%, 100% { opacity: 0.5; transform: scale(1); }
50% { opacity: 0.8; transform: scale(1.05); }
}
@keyframes scanline {
0% { transform: translateY(0); }
100% { transform: translateY(100px); }
}
@keyframes glitchFlash {
0%, 95%, 100% { opacity: 0; }
96%, 97%, 98%, 99% { opacity: 0.1; }
}
@keyframes svgGlitch {
0%, 100% {
transform: translate(0, 0) scale(1);
filter: brightness(1.2) contrast(1.1);
}
1% {
transform: translate(-2px, 1px) scale(1.001);
filter: brightness(1.5) contrast(1.3) hue-rotate(10deg);
}
2% {
transform: translate(2px, -1px) scale(0.999);
filter: brightness(0.9) contrast(1.4) hue-rotate(-10deg);
}
}
@keyframes colorShift {
0% { fill: rgba(255, 255, 255, 0.5); }
25% { fill: rgba(0, 255, 255, 0.5); }
50% { fill: rgba(255, 0, 255, 0.5); }
75% { fill: rgba(255, 255, 0, 0.5); }
100% { fill: rgba(0, 255, 0, 0.5); }
}
@keyframes textGlitch {
0%, 100% {
opacity: 1;
transform: translateX(0);
text-shadow: 0 0 10px #0ff, 0 0 20px #0ff;
}
1% {
opacity: 0.8;
transform: translateX(-1px);
text-shadow: 0 0 10px #f0f, 0 0 20px #f0f;
}
2% {
opacity: 0.9;
transform: translateX(1px);
text-shadow: 0 0 10px #ff0, 0 0 20px #ff0;
}
}
/* Add chromatic aberration effect */
.chromatic {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: inherit;
mix-blend-mode: screen;
animation: chromatic 4s infinite;
pointer-events: none;
}
.chromatic::before,
.chromatic::after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: inherit;
mix-blend-mode: screen;
}
.chromatic::before {
filter: blur(2px) hue-rotate(120deg);
opacity: 0.3;
animation: chromaticShift 3s infinite;
}
.chromatic::after {
filter: blur(1px) hue-rotate(240deg);
opacity: 0.2;
animation: chromaticShift 2s infinite reverse;
}
@keyframes chromatic {
0%, 100% { transform: translate(0, 0); }
25% { transform: translate(1px, 0); }
50% { transform: translate(0, 1px); }
75% { transform: translate(-1px, 0); }
}
@keyframes chromaticShift {
0%, 100% { transform: translate(0, 0); }
33% { transform: translate(0.5px, -0.5px); }
66% { transform: translate(-0.5px, 0.5px); }
}
</style>
</head>
<body>
<!-- Glitch Background Elements -->
<div class="glitch-bg">
<div class="color-grid"></div>
<div class="noise"></div>
<div class="color-burst"></div>
<div class="scanlines"></div>
<div class="glitch-overlay"></div>
<div class="chromatic"></div>
</div>
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 600">
<title>Snake on Planes - Glitch Edition</title>
<defs>
<linearGradient id="glitchGradient" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" style="stop-color:#ff00ff;stop-opacity:1" />
<stop offset="50%" style="stop-color:#00ffff;stop-opacity:1" />
<stop offset="100%" style="stop-color:#ffff00;stop-opacity:1" />
</linearGradient>
<clipPath id="plane1Mask">
<polygon id="plane1" points="465.49 307.86 538.74 282.24 538.73 374.89 465.48 400.5 465.49 307.86" fill="#ffffff"/>
</clipPath>
<clipPath id="plane2Mask">
<polygon id="plane2" points="397.42 280.28 470.67 254.66 538.74 282.24 465.49 307.86 397.42 280.28" fill="#ffffff"/>
</clipPath>
<clipPath id="plane3Mask">
<polygon id="plane3" points="397.43 187.62 470.68 162.01 470.67 254.66 397.42 280.28 397.43 187.62" fill="#ffffff"/>
</clipPath>
<clipPath id="plane4Mask">
<polygon id="plane4" points="329.35 160.05 402.61 134.43 470.68 162.01 397.43 187.62 329.35 160.05" fill="#ffffff"/>
</clipPath>
<clipPath id="plane5Mask">
<polygon id="plane5" points="261.27 225.12 334.52 199.5 402.6 227.09 329.34 252.7 261.27 225.12" fill="#ffffff"/>
</clipPath>
<clipPath id="plane6Mask">
<polygon id="plane6" points="397.4 372.92 470.66 347.31 470.65 439.95 397.39 465.57 397.4 372.92" fill="#ffffff"/>
</clipPath>
<clipPath id="plane7Mask">
<polygon id="plane7" points="397.42 372.87 470.67 347.26 538.74 374.83 465.49 400.45 397.42 372.87" fill="#ffffff"/>
</clipPath>
<clipPath id="plane8Mask">
<polygon id="plane8" points="329.35 160.05 402.61 134.43 402.6 227.09 329.34 252.7 329.35 160.05" fill="#ffffff"/>
</clipPath>
<clipPath id="plane9Mask">
<polygon id="plane9" points="261.27 225.12 334.52 199.5 334.51 292.16 261.26 317.77 261.27 225.12" fill="#ffffff"/>
</clipPath>
<clipPath id="plane10Mask">
<polygon id="plane10" points="261.26 317.77 334.51 292.16 402.58 319.74 329.33 345.35 261.26 317.77" fill="#ffffff"/>
</clipPath>
<clipPath id="plane11Mask">
<polygon id="plane11" points="329.33 345.35 402.59 319.73 402.58 412.38 329.32 437.99 329.33 345.35" fill="#ffffff"/>
</clipPath>
<clipPath id="plane12Mask">
<polygon id="plane12" points="329.32 437.99 402.58 412.38 470.65 439.95 397.39 465.57 329.32 437.99" fill="#ffffff"/>
</clipPath>
</defs>
<g class="whole">
<g clip-path="url(#plane10Mask)">
<polygon id="line10" points="315.81 298.7 383.95 326.18 347.95 338.77 279.81 311.29 315.81 298.7" fill="url(#glitchGradient)"/>
</g>
<g clip-path="url(#plane12Mask)">
<polygon id="line12" points="383.95 418.9 452.09 446.38 416.09 458.97 347.94 431.49 383.95 418.9" fill="url(#glitchGradient)"/>
</g>
<use xlink:href="#plane12" opacity="0.8"/>
<g clip-path="url(#plane11Mask)">
<polygon id="line11" points="383.95 326.18 383.95 418.83 347.95 431.42 347.95 338.77 383.95 326.18" fill="url(#glitchGradient)"/>
</g>
<use xlink:href="#plane11" opacity="0.6"/>
<use xlink:href="#plane10" opacity="0.82"/>
<use xlink:href="#plane7"/>
<use xlink:href="#plane5"/>
<use xlink:href="#plane6" opacity="0.8"/>
<use xlink:href="#plane3"/>
<use xlink:href="#plane8" opacity="0.5"/>
<g clip-path="url(#plane7Mask)">
<polygon id="line7" points="451.97 353.82 520.11 381.3 484.11 393.89 415.96 366.41 451.97 353.82" fill="url(#glitchGradient)"/>
</g>
<g clip-path="url(#plane8Mask)">
<polygon id="line8" points="383.82 141.07 383.82 233.72 347.82 246.31 347.82 153.66 383.82 141.07" fill="url(#glitchGradient)" opacity="0.8"/>
</g>
<g clip-path="url(#plane9Mask)">
<polygon id="line9" points="315.74 206.15 315.74 298.8 279.74 311.39 279.74 218.73 315.74 206.15" fill="url(#glitchGradient)"/>
</g>
<use xlink:href="#plane9" opacity="0.51"/>
<use xlink:href="#plane4" opacity="0.8"/>
<use xlink:href="#plane1" opacity="0.8"/>
<use xlink:href="#plane2"/>
<g clip-path="url(#plane5Mask)">
<polygon id="line5" points="315.8 206.04 383.94 233.52 347.94 246.11 279.8 218.63 315.8 206.04" fill="url(#glitchGradient)" opacity="1"/>
</g>
<g clip-path="url(#plane1Mask)">
<polygon id="line1" points="520.11 288.75 520.11 381.39 484.11 393.98 484.11 301.34 520.11 288.75" fill="url(#glitchGradient)"/>
</g>
<g clip-path="url(#plane3Mask)">
<polygon id="line3" points="451.97 168.55 451.97 261.2 415.97 273.79 415.97 181.14 451.97 168.55" fill="url(#glitchGradient)"/>
</g>
<g clip-path="url(#plane6Mask)">
<polygon id="line6" points="451.97 353.82 451.97 446.47 415.97 459.06 415.97 366.41 451.97 353.82" fill="url(#glitchGradient)"/>
</g>
<g clip-path="url(#plane2Mask)">
<polygon id="line2" points="451.97 261.2 520.11 288.68 484.11 301.27 415.96 273.79 451.97 261.2" fill="url(#glitchGradient)"/>
</g>
<g clip-path="url(#plane4Mask)">
<polygon id="line4" points="383.82 141.07 451.97 168.55 415.97 181.14 347.82 153.66 383.82 141.07" fill="url(#glitchGradient)"/>
</g>
<polygon id="frontCross" class="frontCross" points="397.43 187.62 397.42 280.28 465.49 307.86 465.48 400.5 397.4 372.92 397.39 465.57 329.32 437.99 329.33 345.35 261.26 317.76 261.27 225.12 329.34 252.7 329.35 160.05 397.43 187.62" fill="#ffffff" stroke="url(#glitchGradient)"/>
</g>
</svg>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<script>
var xmlns = "http://www.w3.org/2000/svg",
xlinkns = "http://www.w3.org/1999/xlink",
select = function(s) {
return document.querySelector(s);
},
selectAll = function(s) {
return document.querySelectorAll(s);
},
mainTl,
line1Tl,
line2Tl,
line3Tl,
line4Tl,
line5Tl,
line6Tl;
// Make the SVG visible immediately
TweenMax.set('svg', {
visibility: 'visible',
scale: 1.2,
transformOrigin: "center center"
});
// Scale up the entire animation
TweenMax.set('.whole', {
scale: 1.3,
transformOrigin: "center center"
});
// Add random glitch effect to SVG
function randomGlitch() {
TweenMax.to('svg', 0.05, {
x: (Math.random() - 0.5) * 20,
y: (Math.random() - 0.5) * 20,
scale: 1.2 + (Math.random() - 0.5) * 0.1,
rotation: (Math.random() - 0.5) * 5,
onComplete: function() {
TweenMax.to('svg', 0.1, {
x: 0,
y: 0,
scale: 1.2,
rotation: 0
});
}
});
}
// Trigger random glitches
setInterval(randomGlitch, 3000);
mainTl = new TimelineMax({repeat: -1, repeatDelay: 0}).timeScale(2);
var line1Tl = new TimelineMax();
line1Tl.fromTo('#line1', 1, {
y: 100
}, {
y: -100,
ease: Linear.easeNone
})
.fromTo('#line7', 0.5, {
x: -0,
y: -0
}, {
x: 69,
y: 28,
ease: Linear.easeNone
}, '-=1');
var line2Tl = new TimelineMax();
line2Tl.fromTo('#line2', 1, {
x: 69,
y: 28
}, {
x: -69,
y: -28,
ease: Linear.easeNone
});
var line3Tl = new TimelineMax();
line3Tl.fromTo('#line3', 1, {
y: 100
}, {
y: -100,
ease: Linear.easeNone
});
var line4Tl = new TimelineMax();
line4Tl.fromTo('#line4', 1, {
x: 69,
y: 28
}, {
x: -69,
y: -28,
ease: Linear.easeNone
});
var line5Tl = new TimelineMax();
line5Tl.fromTo('#line5', 1, {
x: 69,
y: 28
}, {
x: -69,
y: -28,
ease: Linear.easeNone
});
var line6Tl = new TimelineMax();
line6Tl.fromTo('#line6', 1, {
y: 100
}, {
y: -100,
ease: Linear.easeNone
});
var line7Tl = new TimelineMax();
line7Tl.fromTo('#line7', 0.5, {
x: -69,
y: -28
}, {
x: 0,
y: 0,
ease: Linear.easeNone
});
var line8Tl = new TimelineMax();
line8Tl.fromTo('#line8', 1, {
y: -100
}, {
y: 100,
ease: Linear.easeNone
});
var line9Tl = new TimelineMax();
line9Tl.fromTo('#line9', 1, {
y: -100
}, {
y: 100,
ease: Linear.easeNone
});
var line10Tl = new TimelineMax();
line10Tl.fromTo('#line10', 1, {
x: -69,
y: -28
}, {
x: 69,
y: 28,
ease: Linear.easeNone
});
var line11Tl = new TimelineMax();
line11Tl.fromTo('#line11', 1, {
y: -100
}, {
y: 100,
ease: Linear.easeNone
});
var line12Tl = new TimelineMax();
line12Tl.fromTo('#line12', 1, {
x: -69,
y: -28
}, {
x: 69,
y: 28,
ease: Linear.easeNone
});
mainTl.add(line1Tl)
.add(line2Tl, '-=0.5')
.add(line3Tl, '-=0.5')
.add(line4Tl, '-=0.5')
.add(line8Tl, '-=0.5')
.add(line5Tl, '-=0.5')
.add(line9Tl, '-=0.5')
.add(line10Tl, '-=0.5')
.add(line11Tl, '-=0.5')
.add(line12Tl, '-=0.5')
.add(line6Tl, '--=0.5')
.add(line7Tl, '-=0.5');
TweenMax.set('.whole', {
rotation: 0,
svgOrigin: '400 300'
});
// Add color cycling to the gradient
var gradient = document.querySelector('#glitchGradient');
var stops = gradient.querySelectorAll('stop');
function cycleColors() {
TweenMax.to(stops[0], 2, {
attr: { 'stop-color': getRandomColor() },
ease: Power1.easeInOut
});
TweenMax.to(stops[1], 2, {
attr: { 'stop-color': getRandomColor() },
ease: Power1.easeInOut,
delay: 0.5
});
TweenMax.to(stops[2], 2, {
attr: { 'stop-color': getRandomColor() },
ease: Power1.easeInOut,
delay: 1
});
}
function getRandomColor() {
var colors = ['#ff00ff', '#00ffff', '#ffff00', '#ff0000', '#00ff00', '#0000ff'];
return colors[Math.floor(Math.random() * colors.length)];
}
setInterval(cycleColors, 3000);
cycleColors();
</script>
</body>
</html>