Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
jpeacock

360 image sequence (not sprites), easing in chosen image

Recommended Posts

Hi all,

 

I'm trying to figure out a way through this. I have a product that is photographed as a 360 degree image sequence. Using an older TimelineMax topic from the forum, I was able to build out a simple spinning image sequence. The images will be large, so a sprite approach seems to be out of the equation, so I'm going ahead with basic images. I'm looking to be able to target a destination image in the sequence, animate to that and ease into place, but my onComplete seems to not coincide with when the destination is reached (though, I think it's because it's actually called when the whole cycle is complete, not my midway destination image). 

 

Thoughts on how to approach this? Or, is there a more modern approach than the forum topic I found from 2014? 

 

See the Pen QWyaEzr by jpeacock (@jpeacock) on CodePen

Link to post
Share on other sites

Sorry, after I posted I realize that I was misunderstanding what you were wanting. I thought you were wanting a different randomly start value each time it does a full rotation :) 

 

To get easing I'd set it up differently. You can actually use a tweens ease if you do this approach. Here I animate to the given frame and then start a linear infinitely rotating animation:

See the Pen MWKrJeQ?editors=0010 by GreenSock (@GreenSock) on CodePen

 

That should be more along the lines of what you're wanting. Happy tweening!

Link to post
Share on other sites

Wow, that's exactly what I was going for, even with the "shortest path" idea built into it. Thank you so much!

  • Like 1
Link to post
Share on other sites

@ZachSaucier

I did have a few questions about how the gs utils work as modifiers...

 

I made a simplified pen with 4 buttons that would ideally take the animation to specific frames (it animates to that frame on first press, but the frames change with each press, which is not intended). Does wrap() shift the images array so that the destination is always at the end ([1,2,3,4,5] might become [4,5,1,2,3]) or does it work some other way? Is the modifiers plugin part of core gsap?

 

I have console.log(lastFrame, newFrame); in onUpdate and each press calculates a different destination.

 

See the Pen MWKrpRw by jpeacock (@jpeacock) on CodePen

Link to post
Share on other sites

That actually has nothing to do with the modifiers or utils. It has to do with the += that I have in the target i value :) Remove that and it works:

See the Pen VweybzG?editors=0010 by GreenSock (@GreenSock) on CodePen

 

35 minutes ago, jpeacock said:

Does wrap() shift the images array so that the destination is always at the end ([1,2,3,4,5] might become [4,5,1,2,3]) or does it work some other way?

The .wrap() documentation will provide a more thorough explanation than me :) Feel free to ask if you have questions.

 

36 minutes ago, jpeacock said:

Is the modifiers plugin part of core gsap?

Yep! It's one of the core plugins. You can see an overview of what is and isn't in GSAP's core on the docs homepage.

  • Like 1
Link to post
Share on other sites

One other note: Currently there's a fixed duration. That's fine but if you click on the same button half way through an animation it will stop the previous animation and do another one at half the speed. If this is all you're doing you might check to see if the index the same, and if it is then check if the animation is active. If it is active, return so it doesn't kill the animation.

  • Like 1
Link to post
Share on other sites

Thanks! There are a lot of possibilities, for sure. 

Link to post
Share on other sites

I'm integrating this into a React project and am somewhat stuck. Getting the error:

Cannot add property _gsap, object is not extensible

I'm adding images into an ImagesLoaded component in this manner: (this is somewhat pseudo-code since I trimmed out a lot of other bits that weren't related)

class Stage extends Component {
  constructor(props) {
    super(props)
    this.AuroraContainer = React.createRef()
    this.images = []
  }
  
  componentDidMount() {
    this.animToFrame()
  }
  
  setRef = (ref) => {
	this.myRefs.push(ref)
  }
  
  animToFrame = () => {
    this.distance = this.getShortDistance(
        this.currFrame.i,
        this.nextFrame,
        this.myRefs
    )
    if (
        this.currFrame.i == this.distance + 1 ||
        this.currFrame.i == this.distance - 1 ||
        this.currFrame.i == this.distance
    ) {
        return
    }

    if (this.animation) {
        this.clearVals()
    }

    if (this.distance !== 0) {
        // this is where the error occurs
        this.animation = gsap.to(this.currFrame, {
            i: this.distance,
            modifiers: {
                i: gsap.utils.pipe(
                    gsap.utils.snap(1),
                    gsap.utils.wrap(
                        0,
                        this.myRefs.length - 1
                    )
                ),
            },
            onStart: () => {
                console.log(this.distance)
            },
            onUpdate: () => {
                const newFrame = this.currFrame.i
                gsap.set(
                    this.myRefs[this.lastFrame],
                    {
                        visibility: "hidden",
                    }
                )
                gsap.set(this.myRefs[newFrame], {
                    visibility: "visible",
                })
                this.lastFrame = newFrame
            },
            //onComplete: () => gsap.delayedCall(1, rotate360),

            ease: "power1.inOut",
            duration: 0.7,
        })
    }
  }

  render() {
  this.images = [...Array(144).keys()].map((image, index) => {
      var file = `${image.toString().padStart(5, "0")}`
      return (
          <img
              ref={this.setRef}
              key={`image_${index}`}
              src={`my-image-url.png`}
              className="rotator-image"
          />
      )
  })
  return (
      <div className="animatedImageWrapper">
          <ImagesLoaded
              ref={this.AuroraContainer}
          >
              {this.images}
          </ImagesLoaded>
      </div>
  )
}

Any idea as to where the error stems from? 

Link to post
Share on other sites

I'm not a React guy either, but that error sounds like you're trying to animate something that's not an object. GSAP adds a _gsap property to any target(s) in order to cache some values and improve performance. Whatever you're tweening is basically saying "Dude, you can't do that...I'm not an object you can add a property to". JavaScript objects, from my understanding, are virtually all extensible except for primitive values like a boolean or null or undefined, etc. 

 

Maybe try to console.log() the objects you're attempting to tween right before each tween so you can verify they're valid objects. 

  • Like 1
Link to post
Share on other sites

Not really a gsap or React error. You're not providing a valid target... or at least not one that can be modified. Console.log your targets to make sure they are what you think they are.

 

const obj = {
  prop: 42
};

Object.freeze(obj);

// Cannot add property _gsap, object is not extensible
gsap.to(obj, {
  prop: 0
}) 

 

  • Like 3
Link to post
Share on other sites

Thanks everyone! I got it working by dynamically settings refs on each image. In the code above, I was thinking it had grabbed the children of the ImagesLoaded class, but it was null. I ended up setting refs on each image and pushing them into an array, then using that array as the elements to animate. I edited the code in the post above to point future seekers in the right direction. 

  • Like 1
Link to post
Share on other sites

jpeacock

Can you show me how your ImagesLoaded Component looks like ?

Thanks !!!

Handy

Link to post
Share on other sites

@jpeacock

Just another question, can you show me how did you set the array with the ref on each image ?

Thanks indeed

Link to post
Share on other sites
4 minutes ago, Andy1708 said:

@jpeacock

Just another question, can you show me how did you set the array with the ref on each image ?

Thanks indeed

I just edited the post above to show it. Basically, it's where I reference the setRefs function and the array is this.myRefs to access the children. 

  • Like 1
Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×