Setup
Quick setup Webflow<>GSAP notes based on Timothy Ricks’ GSAP & ScrollTrigger Crash Course.
- Use codesandbox to plug in to Webflow for temporary development experimentation (so you don’t have to constantly publish via Webflow)
- Add GSAP libraries to Webflow (in before closing body tab, page or site level)
- Add CDN helpers via GSAP install site
- Copy and paste scripts into
before closing body
tab, on page or site level
- Create an HTML + CSS sandbox in codesandbox
- Create a new file in the new project called
script.js
- Copy link in codesandbox
- Add it as a script to Webflow
Scratchpad🐾
Reading scripts in natural language
gsap.to("[.class]", { properties });
== animate this class to these properties.from
== animate this class from these properties.fromTo
== set initial states and animate from property set 1 to property set 2.set
== sets it to a certain style without a duration instant on page load- Properties can be set in any order
- typed in camel case ==
border-radius
becomesborderRadius
- Non-integers become strings, ie.,
"3rem"
- typed in camel case ==
- Ease Visualizer
stagger: { each: 0.5 }
== staggering the start time of each item with the same class- use
amount
to stagger the images within that time - example, each would be 2.5 s vs amount would only be 0.5
from: "end"
== where it staggers (end of list)middle
orrandom
are also options
- use
let [name] = gsap.timeline();
== create a sequence of animations[name].timeline
== replacegsap
with new timeline name to mark the timeline in that sequence, in the order you write itloadTl.from(".class", {...}, 0.5);
== passing a number parameter gives it a position in the timeline — like position absolute, giving it a distance between itself and the start of the timeline and offsetting it"<0.5"
== start this animation at the beginning of the previous animation and offset by 0.5s — this is like relative positioning"<-0.5"
== start this animation at the end of the previous animation, but cut into it by 0.5s
repeat
== loopyoyo: true
== let the animation go back and forthrepeat:-1
== infinite loop- If the browser isn’t rendering your animations: double check that the codesandbox is not private
Add ScrollTrigger
gsap.timeline({
scrollTrigger: {
trigger: ".element", // Element that will trigger the animation
start: "top center", // top of section reaches center of screen
end: "bottom bottom", // bottom of section reaches bottom of screen
markers: true, // visual preview of the above
}
})
- It’s possible to pass percentages instead of words like
top
,center
, andbottom
gsap.timeline({
scrollTrigger: {
trigger: ".element", // Element that will trigger the animation
start: "10% 40%", // When 10% from the top of the section reaches 40% from the top of the screen
end: "bottom 50%", // bottom of section reaches 50% from top of screen
markers: true, // visual preview of the above
toggleActions: "play none none none", //1. when enters view, 2. when it leaves view, 3. when it reenters view from the bottom, 4. when it exits at the top — values: play pause resume reset restart complete reverse none
}
})
When there’s multiples of the same section on a page
$(".section").each(function (){
// Add timeline code to this each loop
...
scrollTrigger: {
trigger: $(this) // references back to the section it's looping through
}
...
scrollTl.from($(this).find(".child-element"), {...}) // find all child elements with x class within this section
})
toggleActions
Performance
A lot of performance problems are down to how browsers and graphics rendering work. It’s very difficult to troubleshoot blind and performance is a DEEP topic, but here are some tips:
- Try setting
will-change: transform
on the CSS of your moving elements. - Make sure you’re animating transforms (like x, y) instead of layout-affecting properties like top/left.
- Definitely avoid using CSS filters or things like blend modes. Those are crazy expensive for browsers to render.
- Be very careful about using loading=“lazy” on images because it forces the browser to load, process, rasterize and render images WHILE you’re scrolling which is not good for performance.
- Make sure you’re not doing things on scroll that’d actually change/animate the size of the page itself (like animating the height property of an element in the document flow)
- Minimize the area of change. Imagine drawing a rectangle around the total area that pixels change on each tick - the bigger that rectangle, the harder it is on the browser to render. Again, this has nothing to do with GSAP - it’s purely about graphics rendering in the browser. So be strategic about how you build your animations and try to keep the areas of change as small as you can.
- If you’re animating individual parts of SVG graphics, that can be expensive for the browser to render. SVGs have to fabricate every pixel dynamically using math. If it’s a static SVG that you’re just moving around (the whole thing), that’s fine - the browser can rasterize it and just shove those pixels around…but if the guts of an SVG is changing, that’s a very different story.
- data-lag is a rather expensive effect, FYI. Of course we optimize it as much as possible but the very nature of it is highly dynamic and requires a certain amount of processing to handle correctly.
- I’d recommend strategically disabling certain effects/animations and then reload it on your laptop and just see what difference it makes (if any).
- Use
autoAlpha: 0
instead ofopacity: 0