Jump to content


  • Posts

  • Joined

  • Last visited

Recent Profile Visitors

365 profile views

jmca's Achievements


Newbie (1/14)



  1. I see your issue. The <a> element needs to be `position: relative` and you need to tween that element's `left` property. Currently you are tweening the button that is inside <a>. Refer to css docs for when "left" can be used:
  2. @Carl I see your point about the duration being the completion target and not the property value, specifically in the case of springs/bounces. I'm dealing with user-interruptible tweens/timelines, so it does look like my best bet is within onUpdate/onStart.
  3. The quickest solution I came up with so far is: onStart: tween => { if (currentOpacity === targetOpacity) { tween.progress(1) } }, onStartParams: ['{self}'], But I'm not sure I should be meddling with the tween within onStart.
  4. Depending on the user's interactions, there are times when a new `TweenLite.to()` target property is already reached, but the tween continues the full duration regardless. For instance: TweenLite.to(el, 5, {opacity: 0, onComplete: () => IMPORTANT STUFF}) Let's say the user interacted with something causing this tween to be called, but the tweened element already has an opacity of 0. I would think the tween would assume it reached it's target value and fire it's `onComplete` callback. But instead it runs through the full duration, which results in what is perceived be a pause in animation. I logged out the values via `onUpdate` and the values are indeed equal. I can think of a bunch of manual checks as a solution, but this is one of many animations that will run into this problem. Btw, the callbacks need to be fired, so I can't really bypass the tween. Is there a built in mechanism in GSAP to handle this?
  5. @Sahil I like the idea of `modifiers`. I was looking into that before but I didn't totally understand it's application in this scenario since I thought it was more for snap/clamping points. Looking at your pen, I see your direction. I have to brain-parse your `map()` function a bit so I totally understand it, but I like your idea and it gives me a good jumping off point. Thanks.
  6. I'm trying to expand an element's height from 'auto' to '100%', and reverse it. By just using `to()` percent height, there's a slight jolt in height due to percent-to-pixel rounding. So in order to circumvent that, there was another post that suggested to predetermine the heights before starting the tween. The two issues I'm having right now are: Timeline is compiled ahead of time, but I thought the whole point of a property function was that it was executed during runtime (deferred). During reverse, I would like to do the opposite, swapping the starting and ending property values, but the property function is not executed during runtime. What is the method for calculating runtime start values? I saw some posts suggesting to create a new timeline, but that seems heavy handed since one would have to cache the playback position, recreate the timeline, resume from the cached position in reverse, and possible do this multiple times if the user decides to change the window size or hide other elements affecting the height value during other parts of the tween. Is Timeline at all capable of runtime start values? Here's an excerpt of the timeline: let startHeight let toHeight return new TimelineLite({paused: true}) ...other tweens .to(this.elSpinnerWrapper, tweenDuration, {...tweenProps, opacity: 0}) .set(this.elSpinnerAndPickerWrapper, {height: '100%'}) // <--- This is the element to expand/contract .call(() => toHeight = this.elSpinnerAndPickerWrapper.offsetHeight) .set(this.elSpinnerAndPickerWrapper, {height: 'auto'}) .call(() => startHeight = this.elSpinnerAndPickerWrapper.offsetHeight) .set(this.elSpinnerAndPickerWrapper, {height: startHeight}) .to(this.elSpinnerAndPickerWrapper, tweenDuration, {...tweenProps, height: () => toHeight}) // ...other tweens Any suggestions would be appreciated.