https://codepen.io/baldax/pen/KKLLmPY
Hello, I have a problem. When I apply the following animations to my text, they don't work because they conflict with my .gradient-text class. I can't understand why. I absolutely want to keep custom CSS on my text and add the animations. Is this possible? Do you have any suggestions to help me? Thank you so much!!!!! <3
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://unpkg.com/split-type"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.11.3/ScrollTrigger.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div text-split words-slide-up>
<p class="gradient-text">Animation 1</p>
</div>
<div text-split words-rotate-in>
<p class="gradient-text">Animation 2</p>
</div>
<div text-split words-slide-from-right>
<p class="gradient-text">Animation 3</p>
</div>
<div text-split letters-slide-up>
<p class="gradient-text">Animation 4</p>
</div>
<div text-split letters-slide-down>
<p class="gradient-text">Animation 5</p>
</div>
<div text-split letters-fade-in>
<p class="gradient-text">Animation 6</p>
</div>
<div text-split scrub-each-word>
<p class="gradient-text">Animation 7</p>
</div>
<script src="script.js"></script>
</body>
</html>
body {
background-color: #000000;
}
[text-split] {
opacity: 1;
}
html.w-editor [text-split] {
opacity: 0;
}
.word,
.char {
overflow: hidden;
padding-bottom: 0.1em;
margin-bottom: -0.1em;
transform-origin: bottom;
}
.gradient-text {
font-size: 48px;
font-weight: bold;
background: linear-gradient(to bottom, #00aeff, #00ff95);
}
.gradient-text {
background: linear-gradient(to bottom, #9B9B9B 0%, #ffffff 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
window.addEventListener("DOMContentLoaded", (event) => {
console.log("DOM fully loaded and parsed");
// Split text into spans
let typeSplit = new SplitType("[text-split]", {
types: "words, chars",
tagName: "span",
});
console.log("SplitType applied");
// Link timelines to scroll position
function createScrollTrigger(triggerElement, timeline) {
console.log("Creating ScrollTrigger for", triggerElement);
// Reset tl when scroll out of view past bottom of screen
ScrollTrigger.create({
trigger: triggerElement,
start: "top bottom",
onLeaveBack: () => {
timeline.progress(0);
timeline.pause();
},
});
// Play tl when scrolled into view (60% from top of screen)
ScrollTrigger.create({
trigger: triggerElement,
start: "top 60%",
onEnter: () => timeline.play(),
});
}
// Apply the same logic to all text-split elements
function applyAnimation(selector, animation) {
const elements = $(selector);
console.log(`Found ${elements.length} elements for selector ${selector}`);
elements.each(function (index) {
let element = $(this);
element.css("will-change", "opacity, transform"); // Adding will-change to improve performance
let tl = gsap.timeline({ paused: true });
animation(tl, element);
createScrollTrigger(element, tl);
});
}
// Define the animations
const animations = {
"[words-slide-up]": (tl, element) => {
console.log("Applying words-slide-up animation to", element);
tl.from(element.find(".word"), {
opacity: 0,
yPercent: 100,
duration: 0.5,
ease: "back.out(2)",
stagger: { amount: 0.5 },
});
},
"[words-rotate-in]": (tl, element) => {
console.log("Applying words-rotate-in animation to", element);
tl.set(element.find(".word"), { transformPerspective: 1000 });
tl.from(element.find(".word"), {
rotationX: -90,
duration: 0.6,
ease: "power2.out",
stagger: { amount: 0.6 },
});
},
"[words-slide-from-right]": (tl, element) => {
console.log("Applying words-slide-from-right animation to", element);
tl.from(element.find(".word"), {
opacity: 0,
x: "1em",
duration: 0.6,
ease: "power2.out",
stagger: { amount: 0.2 },
});
},
"[letters-slide-up]": (tl, element) => {
console.log("Applying letters-slide-up animation to", element);
tl.from(element.find(".char"), {
yPercent: 100,
duration: 0.2,
ease: "power1.out",
stagger: { amount: 0.6 },
});
},
"[letters-slide-down]": (tl, element) => {
console.log("Applying letters-slide-down animation to", element);
tl.from(element.find(".char"), {
yPercent: -120,
duration: 0.3,
ease: "power1.out",
stagger: { amount: 0.7 },
});
},
"[letters-fade-in]": (tl, element) => {
console.log("Applying letters-fade-in animation to", element);
tl.from(element.find(".char"), {
opacity: 0,
duration: 0.2,
ease: "power1.out",
stagger: { amount: 0.8 },
});
},
"[letters-fade-in-random]": (tl, element) => {
console.log("Applying letters-fade-in-random animation to", element);
tl.from(element.find(".char"), {
opacity: 0,
duration: 0.05,
ease: "power1.out",
stagger: { amount: 0.4, from: "random" },
});
},
"[scrub-each-word]": (tl, element) => {
console.log("Applying scrub-each-word animation to", element);
tl = gsap.timeline({
scrollTrigger: {
trigger: element,
start: "top 90%",
end: "top center",
scrub: true,
},
});
tl.from(element.find(".word"), {
opacity: 0.2,
duration: 0.2,
ease: "power1.out",
stagger: { each: 0.4 },
});
},
};
// Apply animations to all elements
for (const [selector, animation] of Object.entries(animations)) {
applyAnimation(selector, animation);
}
// Avoid flash of unstyled content
gsap.set("[text-split]", { opacity: 1 });
console.log("Set opacity to 1 for all [text-split] elements");
});