Skip to main content
GSAP Animation TutorialArticle 05

Understanding gsap.fromTo(): Control the Start and End States

Define both endpoints of an animation for predictable entrances, transitions, progress visuals, and replayable interactions.

GSAP fromTo() Start and End Animation Tutorial - NavTechSolution

gsap.to() tells GSAP where an element should finish. gsap.from() tells it where an element should begin. gsap.fromTo() explicitly defines both ends.

Both endpoints
gsap.fromTo(
  ".box",
  { x: -100 },
  {
    x: 200,
    duration: 1
  }
)
GSAP fromTo custom start and custom end state diagram
Both animation endpoints are defined explicitly: the first object supplies the starting values and the second supplies the ending values.

1. What is gsap.fromTo()?

gsap.fromTo() accepts a target, a starting object, and an ending object. It does not need to infer either endpoint:

Explicit start and finish
gsap.fromTo(
  ".box",
  {
    x: -150,
    opacity: 0
  },
  {
    x: 0,
    opacity: 1,
    duration: 1
  }
)
  • ".box" is the target.
  • The first object defines x -150 and opacity 0 as starting values.
  • The second object defines x 0 and opacity 1 as ending values.

Playback controls such as duration and ease normally belong in the third argument because they configure the tween traveling toward the destination.

2. Anatomy of gsap.fromTo()

gsapAnimation library
.fromTo()Control both ends
targetElement or elements
fromVarsStarting properties
toVarsEnding properties and settings
Card reveal syntax
gsap.fromTo(
  ".card",
  { y: 60, opacity: 0 },
  {
    y: 0,
    opacity: 1,
    duration: 1,
    ease: "power2.out"
  }
)

3. to() versus from() versus fromTo()

gsap.to()

Current → custom end

gsap.to(".box", { x: 200 })

Use the current state as the start.

gsap.from()

Custom start → current

gsap.from(".box", { x: -200 })

Use the current state as the finish.

gsap.fromTo()

Custom start → custom end

gsap.fromTo(".box", { x: -200 }, { x: 200 })

Control both endpoints explicitly.

Visual comparison of gsap.to, gsap.from and gsap.fromTo animation states
to() controls the end, from() controls the start, and fromTo() controls both.

4. Your first fromTo() animation

First controlled tween
<div class="fromto-demo-box"></div>

gsap.fromTo(
  ".fromto-demo-box",
  { x: -120, opacity: 0, scale: 0.8 },
  {
    x: 120,
    opacity: 1,
    scale: 1,
    duration: 1.3,
    ease: "power2.out"
  }
)
FROM
TO

Ready at the neutral state.

5. Control position

Negative x is left and positive x is right. Because both values are explicit, the motion is independent of the element’s previous x value.

Horizontal and vertical endpoints
gsap.fromTo(".box", { x: -100 }, {
  x: 100,
  duration: 1
})

gsap.fromTo(".box", { y: 50 }, {
  y: -50,
  duration: 1
})
Box-100px
0
Box+100px

6. Control opacity

Invisible to visible
gsap.fromTo(".message", { opacity: 0 }, {
  opacity: 1,
  duration: 1
})

gsap.fromTo(".message", { opacity: 0.2 }, {
  opacity: 1,
  duration: 1
})

The first tween explicitly fades from transparent to visible. The second begins partially visible, which can create a quieter change.

7. Control scale

Scale endpoints
gsap.fromTo(".card", { scale: 0.7 }, {
  scale: 1,
  duration: 0.8,
  ease: "power2.out"
})

gsap.fromTo(".card", { scale: 1 }, {
  scale: 1.2,
  duration: 0.8
})
From 70%
To 100%

8. Control rotation

Explicit rotation range
gsap.fromTo(".icon", { rotation: -45 }, {
  rotation: 45,
  duration: 1
})

The icon travels through a known 90-degree range. This differs from relying on whatever rotation happens to exist before the tween begins.

9. Combine multiple properties

Controlled feature-card transition
gsap.fromTo(
  ".feature-card",
  {
    x: -100,
    y: 40,
    opacity: 0,
    scale: 0.85,
    rotation: -5
  },
  {
    x: 0,
    y: 0,
    opacity: 1,
    scale: 1,
    rotation: 0,
    duration: 1.2,
    ease: "power2.out"
  }
)
Startx: -100
y: 40
opacity: 0
scale: .85
rotation: -5
Endx: 0
y: 0
opacity: 1
scale: 1
rotation: 0

10. Why use fromTo()?

Explicit endpoints help with exact entrances, replayable transitions, progress indicators, loaders, sliders, hero reveals, controlled card transitions, timeline sequences, and ScrollTrigger scenes. Use it when the element’s current state would make either endpoint unclear.

Choose the simplest suitable method

fromTo() is not automatically better. When the current state is already the correct start, to() is clearer. When current CSS is the desired finish, from() may express the intent more directly.

11. Hero text reveal

NavTechSolution

Motion With Purpose

Build modern interfaces with predictable animation states.

Hero content is at its ending state.
Explicit hero reveal
gsap.fromTo(".fromto-hero-title",
  { y: 60, opacity: 0 },
  {
    y: 0,
    opacity: 1,
    duration: 1,
    ease: "power2.out"
  }
)

12. Card reveal example

Web Development

Fast, responsive and modern web experiences.

The service card is at its ending state.
Card endpoints
gsap.fromTo(".demo-service-card",
  { y: 50, opacity: 0, scale: 0.9 },
  {
    y: 0,
    opacity: 1,
    scale: 1,
    duration: 0.9,
    ease: "power2.out"
  }
)

13. Button interaction example

Hover or focus this isolated button
Mix methods when appropriate
button.addEventListener("mouseenter", () => {
  gsap.fromTo(button, { scale: 1 }, {
    scale: 1.06,
    duration: 0.2,
    ease: "power2.out"
  })
})

button.addEventListener("mouseleave", () => {
  gsap.to(button, { scale: 1, duration: 0.2 })
})

Real projects can mix GSAP methods. Full endpoint control is useful for the entrance, while a simple to() can be clearer for returning to normal.

14. Use fromTo() with multiple elements

Shared card endpoints
gsap.fromTo(".fromto-card",
  { y: 40, opacity: 0 },
  { y: 0, opacity: 1, duration: 0.8 }
)
HTML
CSS
JavaScript

Every match receives the same from/to configuration and begins together. Blog #6 will make multiple elements start at different times using GSAP stagger.

15. Interactive fromTo() playground

START
& END

Select a start-and-end pair.

16. Understand animation configuration

Settings live in toVars
gsap.fromTo(".box", { x: -100 }, {
  x: 100,
  duration: 1,
  delay: 0.2,
  ease: "power2.out",
  repeat: 1,
  yoyo: true
})

duration controls time, delay waits before starting, ease shapes speed, repeat adds runs after the first, and yoyo reverses alternating repeats.

17. fromTo() with repeat and yoyo

Explicit repeated range
gsap.fromTo(".indicator", { x: -80 }, {
  x: 80,
  duration: 1,
  repeat: -1,
  yoyo: true,
  ease: "power1.inOut"
})
From
To, then reverse
GSAP repeat and yoyo forward and reverse animation diagram
repeat runs the tween again, while yoyo alternates its direction between the explicit FROM and TO states.

Infinite decorative animation should be used carefully and skipped for reduced-motion visitors.

18. Advanced note: immediateRender

Advanced note

From and fromTo tweens can apply starting values when created. immediateRender becomes especially relevant in timelines or when several tweens target the same properties. Most standalone beginner examples do not need to change it.

19. Current state versus explicit state

gsap.to()Current stateExplicit end
gsap.from()Explicit startCurrent state
gsap.fromTo()Explicit startExplicit end

Explicit endpoints can make a replay easier to reason about because the same values are prepared every time.

20. Practical loading indicator

Visual progress is at zero.

Visual progress endpoints
gsap.fromTo(".progress-fill", { scaleX: 0 }, {
  scaleX: 1,
  transformOrigin: "left center",
  duration: 2,
  ease: "power2.inOut"
})

This is a visual teaching demo, not a measurement of real loading progress. The explicit endpoints represent 0% and 100% visual fill.

21. Common fromTo() mistakes

The second object is missing

fromTo() requires target, fromVars, and toVars.

Duration is placed in fromVars

Put playback settings in the destination object.

Start and end are reversed

Read the objects in order: from first, then to.

Both endpoints are identical

{ x: 100 } to { x: 100 } produces no visible x movement.

Distances create overflow

Constrain stages and calculate smaller mobile-safe values.

The selector is incorrect

Verify the target within the isolated component.

GSAP is unavailable

Load GSAP before the custom demo script.

The DOM is not ready

Wait for DOMContentLoaded when needed.

Replay state is inconsistent

Kill the active tween and explicitly prepare the new endpoints.

CSS transforms compete

Review other code changing the target’s transform.

Reduced motion is ignored

Skip large or infinite decorative movement.

fromTo() adds unnecessary detail

Prefer to() when the existing state is already the right start.

22. When should you use each method?

Do you need to control the start?
Nogsap.to()
Yes
Do you need to control the end explicitly?
Nogsap.from()
Yesgsap.fromTo()
Decision guide for choosing gsap.to, gsap.from or gsap.fromTo
Choose the smallest GSAP method that gives you the endpoint control your animation needs.

Use to() when current state is a good start, from() when current CSS is the desired finish, and fromTo() when both sides must be explicit.

23. Performance tips

When they fit the design, prefer x, y, scale, rotation, and opacity. Transform and opacity are commonly suitable for interface animation, but results still depend on target size, count, effects, device capability, and other work.

24. Accessibility

Check prefers-reduced-motion. When reduction is requested, skip large movement, stop infinite decorative loops, and show the ending content state immediately. All information and controls must remain available without animation.

25. Mini challenge

Product card
<div class="challenge-product">
  <span class="challenge-badge">New</span>
  <h3>GSAP Animation</h3>
  <p>Build smooth interactive experiences.</p>
</div>

Animate from y 60, opacity 0, scale 0.85, and rotation -3 to y 0, opacity 1, scale 1, and rotation 0. Use one second and power2.out.

Show one possible solution
Challenge solution
gsap.fromTo(".challenge-product",
  { y: 60, opacity: 0, scale: 0.85, rotation: -3 },
  {
    y: 0,
    opacity: 1,
    scale: 1,
    rotation: 0,
    duration: 1,
    ease: "power2.out"
  }
)

26. Quick reference

MethodStartEndBest for
gsap.to()CurrentCustomMoving to a known destination
gsap.from()CustomCurrentEntrance animations
gsap.fromTo()CustomCustomFull endpoint control
PropertyFrom exampleTo example
x-100100
y500
opacity01
scale0.81
rotation-200

27. Remember the fromTo() mental model

Remember: you control both sides
Custom startx: -150
opacity: 0
scale: .8
gsap.fromTo()
Custom endx: 0
opacity: 1
scale: 1

28. Preview: stagger

HTMLStart
0.2s ↓
CSSNext
0.2s ↓
JavaScriptNext
GSAP stagger preview showing HTML CSS and JavaScript cards starting one after another
A stagger offsets matching animations in time—here each card begins 0.2 seconds after the previous card.

Right now, three matching cards begin together. When they begin one after another with a timing gap, that pattern is called stagger. The next lesson develops it fully.

Frequently asked questions

What does gsap.fromTo() do?

gsap.fromTo() animates one or more targets between explicitly supplied starting and ending values.

What is the difference between gsap.from() and gsap.fromTo()?

gsap.from() supplies only the start and finishes at the current state. gsap.fromTo() supplies both start and finish.

What is the difference between gsap.to() and gsap.fromTo()?

gsap.to() begins from the current state. gsap.fromTo() does not rely on that starting state because you define it explicitly.

When should I use gsap.fromTo()?

Use it when both endpoints must be predictable, especially for replayable transitions, progress indicators, loaders, and controlled sequences.

Can gsap.fromTo() animate multiple properties?

Yes. Both objects can include movement, rotation, scale, opacity, color, and other supported values.

Can gsap.fromTo() animate multiple elements?

Yes. A selector, NodeList, or array can provide several targets that share the same start and end configuration.

Where does duration go in gsap.fromTo()?

Duration and other playback settings normally belong in the third argument, the destination or toVars object.

Can I use gsap.fromTo() on a PHP website?

Yes. PHP renders the HTML, and the browser runs GSAP against that rendered markup.

Both endpoints are under control

You can now choose between current-state tweens and explicit endpoints. Revisit the GSAP introduction, targeting elements, gsap.to(), or gsap.from() whenever you need the earlier foundations.