SHARE
How to adapt colors: Probably you want to have other hightlight or default colors:
The text for the heading widget as an example and how to use the span-tags for your highlighted words:
<span>Innovative animations</span> and <span>modern design</span> merge into an immersive experience.<br>
Static pages are a thing of the past – with every click a fresh spark is revealed that <span>makes your brand shine</span>.<br>
Let yourself be surprised by <span>dynamic content</span> and step into a future where your website actively <span>delights customers.</span>
Add this into into your HTML widget.
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.7/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.7/dist/ScrollTrigger.min.js"></script>
<script src="https://unpkg.com/split-type"></script>
<script>
// Colors
const defaultColor = "#eee"; // white
const divHighlight = "#333"; // gray
const spanHighlight = "#f39"; // pink
// Split into words
let quoteSplit = SplitType.create(".quote p", { type: "words" });
// Create timeline
let tl = gsap.timeline();
buildTimeline();
// Configure ScrollTrigger
let st = ScrollTrigger.create({
trigger: ".quote",
start: "top 80%",
end: "center 50%",
scrub: true,
animation: tl
});
// When GSAP internally refreshes, reset timeline to start
ScrollTrigger.addEventListener("refreshInit", () => {
tl.pause(0);
});
// Debounced resize handler
let resizeTO;
window.addEventListener("resize", () => {
clearTimeout(resizeTO);
resizeTO = setTimeout(() => {
// Rebuild timeline and split
tl.kill();
st.kill();
quoteSplit.revert(); // undo old split
quoteSplit = SplitType.create(".quote p", { type: "words" });
tl = gsap.timeline();
buildTimeline();
st = ScrollTrigger.create({
trigger: ".quote",
start: "top 80%",
end: "center 50%",
scrub: true,
animation: tl
});
ScrollTrigger.refresh(); // recalculate bounds
}, 150);
});
// Function that fills the timeline with calls
function buildTimeline() {
quoteSplit.words.forEach((word, i) => {
tl.call(animateWord, [word], (i * 1) + 0.01);
});
tl.set({}, {}, "+=0.01"); // small spacer at the end
}
// Color animation for each word
function animateWord(word) {
const isForward = st.direction === 1;
const targetColor = (word.parentElement.nodeName === "DIV")
? divHighlight
: spanHighlight;
gsap.to(word, {
color: isForward ? targetColor : defaultColor
});
}
</script>