Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

clearProps causes the MutationObserver API to be notified of a removed node #375

Closed
chadwickellis opened this issue Apr 14, 2020 · 4 comments

Comments

@chadwickellis
Copy link

chadwickellis commented Apr 14, 2020

I frequently make use of the MutationObserver API to bind Javascript functions to nodes, initialising or destroying them based on whether they have been injected in or removed from the DOM.

With reference to this JSFiddle test case, if I were to animate a fixed position element's transform property using the CSSPlugin and call clearProps, the MutationObserver API receives a notification that the element has been removed.

I can see that in its simplest form clearProps sets the elements cssText property to null; however, if I were to call this manually as opposed to using clearProps the MutationObserver API is no longer notified that the element has been removed. Unfortunately this means that, to my knowledge, the CSS transformations remain cached and upon resizing the viewport any xPercent or yPercent tween will no longer be accurate.

@chadwickellis chadwickellis changed the title clearProps causes the MutationObserver API to be notified of a removed node clearProps causes the MutationObserver API to be notified of a removed node Apr 14, 2020
@jackdoyle
Copy link
Member

Ah, I think I see what you mean, but it has nothing to do with the transformation cache. If you think something is becoming inaccurate, please provide details but the MutationObserver was getting triggered because CSSPlugin sensed that there was no offsetParent on the target, and no transform applied which often means it's not in the DOM, so CSSPlugin temporarily added it to the documentElement in order to ensure accurate measurements. It's a cross-browser compatibility thing. For example, if display: none is set on an element, the transforms won't be reported accurately, so GSAP handles that under the hood for you.

Anyway, in your case it wasn't really necessary to do that temporary swap into the DOM. I improved the code to exclude a case like that. You can see a preview of the upcoming release at https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js.

Thanks for letting us know. And again, if you're having issues with a transform cache being inaccurate, I'd love to hear more details about that. Of course if you clearProps: "all", that'd clear the transforms too, so I wouldn't expect them to be cached. I may have misunderstood your comment though.

@chadwickellis
Copy link
Author

Thank you for getting back to me on this one Jack, I have replaced my local v3.2.6 with the v3.0.0@beta version you sent across. I can confirm that this beta version resolves the issues I was facing with the MutationObserver API. Are you able to forecast when you are likely to take this version of out of beta and publish it to npm?

I will continue to test this beta version over the coming days before getting back to you regarding any possible issues that I might be facing with the transform cache.

@jackdoyle
Copy link
Member

I can't provide a specific date for the 3.3.0 release, but I'd guess maybe a couple of weeks. We're working on something pretty cool that'll be in that release :)

@chadwickellis
Copy link
Author

No worries at all, I'll keep an eye out for the release and revisit this thread if necessary. Thank you for your time again on this!

jackdoyle added a commit that referenced this issue May 31, 2020
- NEW: ScrollTrigger plugin that empowers you to create jaw-dropping scroll-based animations with minimal code. You can define a scrollTrigger directly in any GSAP animation (Tween or Timeline). See https://greensock.com/scrolltrigger

- IMPROVED: if you set a yoyoEase on a timeline (or a tween with a stagger), it will propagate down through its children accordingly on yoyo.

- IMPROVED: you can now use an alias (like "rotate" instead of "rotation") in a gsap.quickSetter().

- IMPROVED: lots of TypeScript definition additions.

- IMPROVED: you can now pass an Array as the motionPath with properties other than the recognised x/y ones (x, translateX, left, marginLeft, y, translateY, top, marginTop). There's also a helper function available to reproduce the type: "soft" from the old BezierPlugin here: https://greensock.com/forums/topic/24052-how-to-do-soft-bezier-with-motionpath/

- IMPROVED: if you have MotionPathPlugin plot a smooth path through points that you provide and the starting and ending points are basically on top of each other, it'll essentially "close" the path, making the curvature smooth at that point (where the start and end meet).

- IMPROVED [possible breaking change, though very unlikely]: onReverseComplete gets called when the playhead returns to 0 after having been elsewhere even if the animation instance isn't technically in "reversed" mode. This is much more handy because previously it was very cumbersome to try to discern when a child animation (in a timeline) has its playhead hits the start when the parent's playhead is going backwards. If you need to only call the function when in reverse, you can simply add conditional logic in the callback, like if (this.reversed()) {...}.

- FIXED: issue with the "sine" ease could cause the final value to be 0.999999999999 instead of 1, thus "tweens" of the "display" property (that should just toggle at the very end) wouldn't toggle properly.

- FIXED: PixiPlugin now works around the fact that PixiJS returns a string hexidecimal formatted like "0xFF52CC" instead of "#FF52CC" or numeric 0xFF52CC for things like fillColor. See https://greensock.com/forums/topic/23574-gsap-v3-pixijs-v5-pixiplugin-w-stagger-issue-with-graphics-fill/

- FIXED: if you define a "resolution" in your pixi:{} object for PixiPlugin, it doesn't throw a warning about "resolution" not being a valid property.

- FIXED: if you called invalidate() on a from() or fromTo() tween whose playhead is at 0 and then tried rendering at exactly 0, the starting values wouldn't be rendered properly.

- FIXED: if you clear() a timeline that's paused, it would remember the playhead position from before it was cleared so that when it resumes, it starts from that place. See https://greensock.com/forums/topic/23681-timelineinvalidate-doesnt-seem-to/

- FIXED: killTweensOf() failed to completely remove a tween from its parent timeline if that tween had a stagger applied (basically if it had an internal timeline). See https://greensock.com/forums/topic/23729-how-to-createinterrupt-a-repeating-idle-animation/?tab=comments#comment-112523

- FIXED: when a transform-related value is animated and the target didn't have an offsetParent, it could get temporarily appended to the documentElement (and immediately swapped back) for accurate measurement on the first render even when it wasn't necessary. This wouldn't cause any visual problems, but it could cause a MutationObserver to fire. See #375

- FIXED: if you set a tween's duration to a string of exactly "0", it wouldn't render the end values.

- FIXED: if you set the timeScale of an infinitely-repeating animation to a small negative number, it could cause odd behavior.

- FIXED: a zero-duration tween (or callback) that's positioned at the very start of a yoyo-ing timeline may not get called on each yoyo cycle. See #7 (comment)

- FIXED:an addPause() at the very beginning of a repeating timeline may intermittently cause rendering problems in that timeline if the timing conditions were just right. See https://greensock.com/forums/topic/23823-closing-nav-animation-not-working-on-ie-and-iphone-6-maybe-other-older-browser/?tab=comments#comment-113005

- FIXED: if a .from() tween had css-related values wrapped in a css:{} object, the initial state wasn't rendered properly with those values (of course it's typically wasteful to wrap them anyway). See https://greensock.com/forums/topic/24008-inital-states-problem/

- FIXED: if you declare a function-based end value in InertiaPlugin, that function would get called twice. See https://greensock.com/forums/topic/23986-inertia-plugin-end-prop-double-firing/

- FIXED: if you set a Draggable to only allow one direction, like type: "x" or type: "y" but you drag on the opposite axis initially, it could ignore that drag (thinking it was locked on the other axis initially, thus ignoring the movement).

- FIXED: overwrite: "auto" didn't properly kill overlapping AttrPlugin values

- FIXED: setting box-sizing: border-box on a Draggable target could cause its bounds not to include the border correctly.

- FIXED: Draggable wasn't completely preventing the context menu on long-press on Android devices

- FIXED: on some touch devices, Draggable wasn't preventing scroll and the touch event would get cancelled prematurely.

- FIXED: some of the coordinate conversion (and alignment) functionality in MotionPathPlugin didn't work properly if both elements were SVG and had different ownerSVGElements. See https://greensock.com/forums/topic/23592-align-one-svg-to-a-child-element-of-another-svg/

- FIXED: in some cases (due to a rounding issue internally), a set() call may not have immediateRender: true (it'd wait one tick)

- FIXED: in some very rare cases, a tween's repeatRefresh would use the starting values rather than the ending values after invalidating/refreshing.

- FIXED: if a <rect> has an rx attribute defined but not an ry, browsers use the same value as rx but MorphSVGPlugin.convertToPath() didn't accommodate that.

- FIXED: if motionPath tween with an align defined was aligning an element that had an ancestor element with a scale of 0, it wouldn't align properly.
jackdoyle added a commit that referenced this issue Jun 14, 2020
- NEW: ScrollTrigger accommodates pinning the same element multiple times! Just make sure you create the ScrollTriggers in the order they'll be pinned. See https://greensock.com/forums/topic/24429-scrolltrigger-pinning-element-both-top-and-bottom and https://greensock.com/forums/topic/24421-issues-with-multiple-pins-in-a-row/

- IMPROVED: if a pinned ScrollTrigger's animation affects the pin element's transform, it now gets factored in to the final positioning of that pin.

- IMPROVED: if you set up a toggleClass on a ScrollTrigger that has once: true, it will no longer toggle that class back onLeave (it will only happen onEnter because that's more intuitive).

- FIXED: if you kill() a ScrollTrigger when it's in the middle of scrubbing or snapping, it wouldn't kill the in-progress scrubbing or snapping.

- FIXED: if a tween with a stagger is overwritten, the staggered (nested) tweens that haven't started yet may render for one tick when they're scheduled to start

- FIXED: a zero-duration tween (a set()) at the very beginning of a timeline may not render correctly in certain circumstances. See https://greensock.com/forums/topic/24358-scrolltrigger-set/

- FIXED: regression in 3.3.0 could cause initial transform-related values not to be parsed correctly if an ancestor element had dispaly: none. See #388 (this reverts the change made for #375)

- FIXED: the pre-"from" values in a fromTo() may not render when the parent timeline's playhead rewinds past the beginning of that tween.

- FIXED: gsap.utils.wrapYoyo() would return NaN if the start and end values matched. See https://greensock.com/forums/topic/24403-wrapyoyo00x-nan/

- FIXED: if you defined a toggleClass on a ScrollTrigger and that class affected positioning, a refresh() could miscalculate positions because the class wasn't removed for the measurements. See https://greensock.com/forums/topic/24412-scrolltriggerrefresh-help/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants