(React Spring) How to chain an animation in a child component after a parent component transistion completes? - react-spring

(1) I have a standard page transition animation wrapping my Switch / in App /. That page transition applies on each Route /.
(2) I then have animations inside specific components. For example I have a multi-stage transition inside of LandingPage / that also triggers on mount.
The problem is that the animation for the standard page transition in (1) happens at the same time as the specific animation inside a specific component (2).
I can't use useChain because the transitions aren't in the same component.
Is there a way to make sure that animation (2) only occurs after animation (1) completes (even though (1) is in a parent component)?
Cheers

I would introduce a state to the App component. For example routeAnimating. I would set it true at the beginning of each route change. And I would set it false at the onRest callback of the main useTransition. You can pass routeAnimating down to each page as a property. And it can trigger the animation in the page.
I hope it works. Let me know if you try it.

Related

css animation equivalent of the SVG/SMIL begin="scroll" (stc) events (no javascript)

I am converting svg/smil animations to use svg/css to take advantage of some better animation capabilities in css in a situation where there is no javascript.
Svg/Smil animations have a begin attribute which can be a named event (https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/begin) which allows interaction events like click, scroll, loaded, resize and so on to trigger the start of the animation (these listed are my most common required cases).
I've poured over a few css psuedoselector lists and found little, but there are always interesting tricks and hacks people have devised for capturing properties without javascript that I'm hoping someone might point me in a direction here. Of particular interst is if the svg element is in view (e.g. scrolled in / unoccluded / made visible), or if the document (or the svg) has been interacted with (clicked/tapped).

Are offscreen infinitely-looped CSS animations optimized by the browser?

Are there any in-browser optimizations for off-screen infinitely-running CSS animations (infinite animations which are applied to Elements that are present/displayed within the Document, just not in-view at a certain time)?
For the sake of a more straight-forward discussion, I will refer to CSS animations that involve only composition: using only transforms and/or opacity.
If we have a CSS animation, that has animation-timing-function: infinite;, how is it handled if the animated element is not actually on the screen / in-view?
There are some known scenarios regarding animations, which are irrelevant to this use case:
The animation will pause if the browser tab is pushed into the background. MDN
The animation is ignored if the element is removed from the Document, with something like display: none; (can't find a quotable source atm);
If the element is simply 'beyond the scroll', and the user can reach it at anytime, during the time the element is off-screen :
Does the animation run as normal, and has the same consumption, regardless if the element is visible or not?
Does it run as normal, but because it is not painted, the process itself becomes less expensive? - would make more sense.
Is the animation paused entirely? - would assume not, as the browser must know what the 'current progress' would have been at the moment the element needs to be painted again.
Or are there any other in-browser processes which optimize this, when these conditions are met?
Any documented answer, or any redirect to some resource, which could shed some light on the matter would be greatly appreciated.
This discussion would be relevant in determining if : manually removing infinite animations (for elements that are off-screen) would be a thing to consider, to achieve better performance.
TLDR
As long as the properties we want to animate do not trigger reflow/repaint, the animation can be optimized by the browser, which means better performance.
See off main thread animation.

Android fragment transition callbacks

is there a way to detect that a fragment has started transition (in or out). What I am trying to acheve:
I have a fragment whcih has a SurfaceView with complex graphics in it. When I click on a button I want this fragment to slide away from the screen. But we all know, that SurfaceView can't be animated. So I want to replace it with a drawing cache bitmap before I start the transition.
There fore I need to know when the fragment starts transition. This is especially important for open transitions, because I call replace with image routine manually before out transition, but I need to know when the open transition was complete. Is there a better way than a timer (which seems awful to me).
Thanks.
P. S. compatibility lib
Off the top of my head I'd say attach an animation listener to the animations you are using (see Animation Listeners in the Android docs) ..depending on your situation this might mean you need to create and attach the animations in code, or you may be able to retrieve the animation and attach the listener when you create the component (activity/fragment). It depends on how your current implementation works, but the basic idea is to attach a listener to the animation that is about to run. The animation listener will tell you when the animation actually starts and actually finishes..

Is there a proper way to dynamically update parts of transforms and transitions programmatically? e.g. transform-origin or duration

I am building an iOS Safari touch-based app and find CSS transitions and transforms work great.
But I have two things I can't seem to achieve using just JavaScript and CSS.
Usually I want the element to translate with a duration of 0.2s. But in code I occasionally want to instantly translate (initial positioning). If I update the duration to 0 or remove the transition style entirely, it doesn't seem to have an effect (acts as if the 0.2s is immutable)
When zooming I want to update the transform-origin property. This also does not seem to work, and seems stuck at my original stylesheet-set value. Specifically I am trying to do this on the gesturestart and gestureend events
Hopefully there is an approach to making this work. Maybe setTimeout async processing?
Update:
I have a js fiddle example to better illustrate my problem in #1, and it turns out that setTimeout fixes it, but it's a strange solution that I'd be interested in improving:
http://jsfiddle.net/w9E7t/
It seems like I'm unable to do these steps synchronously:
set appropriate classes for an instant transition
apply transition style
reset classes to their default (with transition) state
You can accomplish this by using two CSS classes, one which sets the timing-duration to 0s and the other which sets it to 200ms and then applying the classes programmatically in JS. Take a look at this JSFiddle for an example.
One of Web development's best practices is to separate your document's parts into structure/content (HTML), presentation (CSS), and interaction/behavior (JS). In the example above, the presentation of the content (a timed translation) stays defined in CSS while JS is used only to respond to an interaction (a MouseClick event).
You should be able to change an element's transform-origin using the WebkitTransformOrigin style property in JS. Here is an example JSFiddle. I tested this on my iPhone4 and it correctly logged the new transform-origins in the console. Again, this can also be achieved by using JS only to listen for the gesture events and updating the element's class, while keeping the style rules of the class defined in your presentation logic (CSS).
Note well: In my examples, I am updating the element's .className. Since it is possible that your elements already have many classes, you may need to implement addClass/removeClass functions to properly set the correct classes, several examples of which can found on the Web.
Update:
Sorry for the delay... There are two ways you can approach this problem and the first you have already discovered.
Another way to handle switching back the class name is to use the webkitTransitionEnd property. This fires whenever a transition on the element finishes. It would look like this:
document.getElementById('puck').addEventListener('webkitTransitionEnd', function() {
puck
.removeClass('without_transition')
.addClass('with_transition')
}, false);
Unfortunately, when the transition-duration property is set to 0, this event is not fired :( I'm not sure if that is by design or a bug, but that's just how it's currently implemented (though I'm guessing it's by design since at this point the browser is not really doing a transition but rather just applying the transformation). The workaround in this approach is to set the transition-duration to 1ms (which will essentially look instant).
While the setTimeout approach looks hackish, many mobile framework groups use it throughout their code since the function will fire after the transition that occurs from switching classes (similar to transitionEnd). Take a look at Sencha Touch and you will find it numerous times.
I've forked your JSfiddle to show my example here.

Adobe Flex: How can I cancel an effect during a start delay?

I've got a Glow effect (glowIn) being applied to an object on the roll over which has a startDelay applied. I have another glow effect (glowOut) on roll out. If the user mouses out of the control during the startDelay of glowIn, I want to cancel the effect. How do I do this?
In this instance, I'm using a glow effect with a startDelay of 300ms. I want a short pause before the item actually shows the effect, but I don't want the effect playing if the user mouses out during this time. I'm setting the properties as follows:
component.setStyle("rollOverEffect", glowIn);
component.setStyle("rollOutEffect", glowOut);
I don't think it matters much, but the component in question is a Series within a chart that gets created at runtime so I would prefer a solution in actionscript rather than mxml if possible.
I was unable to find a perfect solution to this issue so what I ended up doing was setting up a mouse-event handler for MouseOver and MouseOut on the control, setting up the effects globally and checking effect.isPlaying() within the mouse event handler.
There are some inconsistencies, however, in interrupting the effect while the start delay is playing and there are some weird results. I set up a basic Resize effect and found that if I mouse out during the start delay, the effect is correctly cancelled. But if I mouseOut when the effect has started, the control continues to grow out of control.

Resources