Frontend Forever App
We have a mobile app for you to download and use. And you can unlock many features in the app.
Get it now
Intall Later
Run
HTML
CSS
Javascript
Output
Document
SVG link effects with GSAP
Click me
Click me
Click me
Click me
Click me
Click me
Click me
@charset "UTF-8"; @import url(https://fonts.googleapis.com/css?family=Nunito+Sans:300,400,600,700,800); *, :after, :before { box-sizing: border-box; padding: 0; margin: 0; } @import url("https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap"); @import url("https://fonts.googleapis.com/css2?family=Lexend+Deca:wght@300&display=swap"); html, body { height: 100%; } body { background-color: #3d3e4a; color: #b6bbc2; display: flex; justify-content: center; font-family: "IBM Plex Mono", monospace; font-weight: 300; font-style: normal; font-size: 12px; flex-direction: column; margin: 0; } header { display: flex; flex-direction: column; align-items: center; background-color: rgba(0, 0, 0, 0.5); padding: 20px 15px; margin-bottom: 25px; width: 100%; } h1 { color: #76b3fa; font-size: 24px; font-family: "Lexend Deca", sans-serif; font-weight: 300; margin-top: 0; margin-bottom: 5px; } .wrapper { display: flex; flex-wrap: wrap; justify-content: center; margin: 25px 0; } svg { rect { fill: #ff4066; transition: fill 300ms ease-in-out; } } a { align-items: center; background-color: rgba(118, 180, 250, 0.2); border-radius: 5px; color: #ffffff; display: flex; justify-content: center; font-family: "Bebas Neue", sans-serif; font-size: 28px; font-style: normal; font-weight: 400; height: 44px; margin: 10px 5px; overflow: hidden; position: relative; text-decoration: none; user-select: none; width: 111px; span { display: inline-block; top: 50%; left: 50%; transform: translate(-50%, -50%); margin-top: 2px; position: absolute; white-space: nowrap; } }
console.log("Event Fired") class SvgLinkEffect { constructor(effect) { if (effect.config.random) { this.randomizeArray(effect.nodes); } effect.element.addEventListener("click", () => { let reverse = effect.element.classList.contains("active") ? true : false; effect.element.classList.toggle("active"); effect.handler(effect.nodes, effect.config, reverse); }); } randomizeArray(array) { for (let i = array.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [array[i], array[j]] = [array[j], array[i]]; } } } const svgBounceEffect = (nodes, config, reverse) => { nodes.forEach((node, index) => { const { duration, ease, y1, y2, offset } = config; setTimeout(() => { if (reverse) { gsap.to(node, { duration: duration, ease: ease, y: y1 }); } else { gsap.to(node, { duration: duration, ease: ease, y: y2 }); } }, index * offset); }); }; const svgAlertnatingEffect = (nodes, config, reverse) => { nodes.forEach((node, index) => { const { duration, ease, offset } = config; setTimeout(() => { if (reverse) { gsap.to(node, { duration: duration, ease: ease, y: index % 2 === 0 ? -44 : 44 }); } else { gsap.to(node, { duration: duration, ease: ease, y: index % 2 === 0 ? 44 : -44 }); } }, index * offset); }); }; document.addEventListener("DOMContentLoaded", (event) => { const waveLink = document.getElementById("wave-link"); const waveLinkEffect = { element: waveLink, handler: svgBounceEffect, nodes: [...waveLink.querySelectorAll("rect")], config: { offset: 10, duration: 1, random: false, ease: "elastic.out(0.8, 0.3)", y1: -20, y2: 44 } }; const randomElasticLink = document.getElementById("random-elastic-link"); const randomElasticLinkEffect = { element: randomElasticLink, handler: svgBounceEffect, nodes: [...randomElasticLink.querySelectorAll("rect")], config: { offset: 10, duration: 1, random: true, ease: "elastic.out(0.8, 0.3)", y1: -20, y2: 44 } }; const cascadeLink = document.getElementById("cascade-link"); const cascadeLinkEffect = { element: cascadeLink, handler: svgBounceEffect, nodes: [...cascadeLink.querySelectorAll("rect")], config: { offset: 10, duration: 1, random: true, ease: "expo.out", y1: -20, y2: 44 } }; const randomStepLink = document.getElementById("random-step-link"); const randomStepLinkEffect = { element: randomStepLink, handler: svgBounceEffect, nodes: [...randomStepLink.querySelectorAll("rect")], config: { offset: 10, duration: 0.8, random: true, ease: "steps(5)", y1: -20, y2: 44 } }; const stepLinkHorizontal = document.getElementById("step-link-horizontal"); const stepLinkHorizontalEffect = { element: stepLinkHorizontal, handler: svgBounceEffect, nodes: [...stepLinkHorizontal.querySelectorAll("rect")], config: { offset: 5, duration: 0.25, random: false, ease: "steps(10)", y1: -20, y2: 44 } }; const alternatingLink = document.getElementById("alternating-link"); const alternatingLinkEffect = { element: alternatingLink, handler: svgAlertnatingEffect, nodes: [...alternatingLink.querySelectorAll("rect")], config: { offset: 5, duration: 1, random: false, ease: "expo.out" } }; const alternatingElasticLink = document.getElementById( "alternating-elastic-link" ); const alternatingElasticLinkEffect = { element: alternatingElasticLink, handler: svgAlertnatingEffect, nodes: [...alternatingElasticLink.querySelectorAll("rect")], config: { offset: 10, duration: 1, random: false, ease: "elastic.out(0.8, 0.3)" } }; new SvgLinkEffect(waveLinkEffect); new SvgLinkEffect(randomElasticLinkEffect); new SvgLinkEffect(cascadeLinkEffect); new SvgLinkEffect(randomStepLinkEffect); new SvgLinkEffect(stepLinkHorizontalEffect); new SvgLinkEffect(alternatingLinkEffect); new SvgLinkEffect(alternatingElasticLinkEffect); });