This template uses the new GSAP animations, but also a few custom ones to complete the premium look and feel. This guide will go over which custom animations are available and how you can use and customize them.
Sienna offers 2 custom animations:blur-fade
fade-up-scroll
The blur-fade
animation fades text in with a blur effect word by word.
The fade-up-scroll
animation fades in text line by line. This is best used for animating paragraphs. But since this is a scroll-based animation, the parenting div needs the data-scroll-trigger
attribute. If not, the animation will not work.
There are several attributes available to control the animations
data-scroll-trigger
is used to trigger a scroll-based animation.data-start
is the ScrollTrigger's starting scroll position. default value is data-start="top 80%"
. When you don't specify data-start
parameters, it will fall back to using the default values. data-end
is the ScrollTrigger's ending scroll position. default value is data-end="bottom 20%"
. When you don't specify data-end
parameters, it will fall back to using the default values. data-gsap-delay
is used to control the delay before the blur-fade
animation get's played. Default value is delay: 0.4;
. When the data-gsap-delay
attribute isn't used, it will fall back to that value. Units are in seconds. so 0.4 = 400ms, 2 = 2000ms or 2 sec, and so on... . We deliberately chose data-gsap-delay
over data-delay
as it interferes with Webflow animations.
To add the blur-fade
animation to a text element, you simply need the add this custom attribute: data-animation="blur-fade"
To add the fade-up-scroll
animation to a text or paragraph element, you simply need the add this custom attribute: data-animation="fade-up-scroll"
. But remember to add data-scroll-trigger=""
to the parent or the animation will not trigger. Although not neccessary in most cases, it's a good idea to fine-tune this type of animation with the data-start
attribute.
Here you can see an example of how the blur-fade
animation is added to a title and controlled by using the data-gsap-delay
attribute.
Example of the fade-up-scroll
animation being used on a paragraph. First image shows how to trigger this scroll-based animation and control it by add the data-start
attribute.
Below is the code used for these animations. In case something goes wrong, you can copy-paste this code in the "custom code" section of the site settings. Make sure to paste it in the bottom "Footer code" text field.
<script>
gsap.registerPlugin(SplitText, ScrollTrigger);
// Unified init: wait for DOM & fonts
Promise.all([
document.fonts.ready,
new Promise(res => {
if (document.readyState === 'complete' || document.readyState === 'interactive') res();
else window.addEventListener('DOMContentLoaded', res, { once: true });
})
]).then(() => {
fadePerWord('[data-animate="blur-fade"]');
fadeUpPerLineOnScroll('[data-scroll-trigger]', '[data-animate="fade-up-scroll"]');
});
// Blur Fade In Animation
function fadePerWord(selector) {
document.querySelectorAll(selector).forEach(el => {
const split = SplitText.create(el, { type: "words" });
const start = el.getAttribute("data-start") || "top 80%";
const end = el.getAttribute("data-end") || "bottom 20%";
const delay = el.hasAttribute("data-gsap-delay")
? parseFloat(el.getAttribute("data-gsap-delay")) || 0
: 0.4;
gsap.from(split.words, {
delay: delay,
duration: 0.6,
autoAlpha: 0,
stagger: 0.09,
filter: "blur(12px)",
ease: "power1.out",
scrollTrigger: {
trigger: el,
start: start,
end: end || undefined,
once: true
}
});
});
}
// Scrolling Fade In Animation
function fadeUpPerLineOnScroll(containerSelector, textSelector) {
gsap.set(textSelector, { opacity: 1 });
document.querySelectorAll(containerSelector).forEach(container => {
const texts = container.querySelectorAll(textSelector);
if (!texts.length) return;
texts.forEach(text => {
const start = container.getAttribute("data-start") || "top 80%";
const end = container.getAttribute("data-end") || "bottom 20%";
SplitText.create(text, {
type: "lines",
linesClass: "line",
autoSplit: true,
onSplit: instance => {
gsap.from(instance.lines, {
yPercent: 120,
stagger: 0.05,
autoAlpha: 0,
ease: "power1.out",
scrollTrigger: {
trigger: container,
scrub: true,
start: start,
end: end,
markers: false // Only used for debugging scrolling animations
}
});
}
});
});
});
}
// Firefox/lazy images fix: refresh triggers after all resources loaded
window.addEventListener('load', () => {
ScrollTrigger.refresh();
});
</script>