Javascript and CSS animations - javascript

I have site with infinite animating (sliding) background and dynamically updating charts (flot.js). Charts are updating every 200ms, background is sliding via CSS animation (infinite translate3d). Trouble is performance on Android: when chart is redrawing, css animation is stopping for several milliseconds, so it looks like game with 8-10 fps :) Is there any tricks, which can solve this problem?

Instead of using setInterval to animate the charts every 200ms try using
window.requestAnimationFrame() in browsers which can support it. The function allows the browser to decide the best time to continue the animation.
https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame?redirectlocale=en-US&redirectslug=DOM%2Fwindow.requestAnimationFrame

Related

Chrome Css Animations break when Web Audio is playing

In Chrome, when the website audio is playing, the label's css animation on the web form fails, even though the JS to fire the addClass function works. However, as soon as I turn off the audio by clicking the sound bars in the bottom right corner, the animations work as expected.
Why would the audio effect the css animation?
https://www.taliscreative.com/contact/
The transition of your sound bars has a duration that might be longer than the "duration" of a frame. This means that every frame you ask for an animation that might take longer than a frame. Things start malfunctioning.
You're already animating them on a "frame-by-frame" basis, so you could just set the sound-bar transition duration to 0s and it'll still look smooth!

Can I force the browser to rasterize elements before they become visible?

Call me crazy, but I'm working on a game using vanilla DOM and TypeScript. It's not action-heavy, but there are some animations going on, which are driven from JavaScript (too complex to do in CSS).
I'm already applying the common trick of translateZ(0) (called null transform hack or less accurately silver bullet) to pull animated elements into their own rendering layer, and I'm animating nothing besides compositor-only properties (transform and opacity). This works beautifully: during the game, everything feels buttery smooth, even on older mobile devices.
The problem is during the start of the game. At that moment, about 70 individually transformed and animated elements enter the page one by one over the space of a few seconds, by animating their opacity from 0 to nonzero. This is causing visible stutter during the animation.
My guess was that Chrome is being too clever here, and will only rasterize each element at the moment it first becomes visible. A quick check with the dev tools confirms this, as there's a lot of rasterization going on even during the animation:
I would prefer to rasterize all these elements once, before the animation starts, and only then trigger the animation. But how can I force rasterization of elements that aren't yet visible, without showing a flash of them to the user?
I'd be happy with a Chrome-only approach, but cross-browser would be even better.

Drawing a SVG with d3.js while tab is in background

Context: I am working on a webapp that has to display some fairly complicated and constantly updating (multiple times per second) SVG images. The updates stem from a seperate server and the SVG is updates as soon as an update is received by the web frontend. The webapp is written in Scala.js and the image is created using the d3js library (see also: scala-js-d3). We currently only support Google Chrome.
Problem: Once the webapp has been in a background tab for a while, the whole site gets unresponsive once navigated to again. Depending on how long the app was in the background, it sometimes takes up to 20 seconds for the application to be responsive again. Is there any way I can solve this?
The solution that works best for me is a pretty simple one:
Once the application is in a background tab or minimized (can be detected using the Page Visibility API), I only update my model without drawing anything. Then, once the application is put into the foreground again, I re-draw everything. This fixed all of my performance problems.
I came across the same problem which I worked around by not doing transitions in background tabs.
mbostock shows a nice snippet for doing this at https://github.com/d3/d3-transition/issues/93#issuecomment-516452828
Helper method…
d3.selection.prototype.maybeTransition = function(duration) {
return duration > 0 ? this.transition().duration(duration) : this;
};
…to be used the following way:
selection
.maybeTransition(document.visibilityState === "visible" ? my_duration : 0)
.attr(…
Capturing the page visibility events one could then even adapt the transition time in such a manner that the transition time is reduced (thus the transition sped up) in such a way that it ends in about the same time had the page not been in a background tab.
If you are using setInterval() at the moment the browser might be 'punishing' you for running setInterval() in an inactive browser-tab.
You can fix this by either using requestAnimationFrame() or by monitoring the tab visibility and only using setInterval() when the tab is active.

JQuery .animate Really Choppy in Chrome Extension

I have a JQuery .animate function.
It switches between two forms.
It toggles height and opacity.
When the two forms are the same height (and the popup does not resize) the animation is smooth. When the popup has to resize, the animation becomes choppy and a thick black border appears around the popup for a couple of seconds.
Is there anyway of smoothing the animation or should I switch to CSS for my animations?
Right now, the extension is that when a label is clicked a new form appears on top of the old one.
Most likely your jQuery animate function uses 2D animations. Look into using 3D translate and transform instead.
Why would 3D be faster than 2D you ask?
Because 3D gets accelerated and rendered using the GPU, 2D does not.
I did the same thing myself not long ago and the results are vastly superior.
It is 2017. You definitely should switch to CSS transitions.
1) Don't use jQuery in Chrome extensions. It's a browser standardisation framework and you're using it in a component that only works in one browser. Instead use advanced features (such as passive events) that Chrome supports but jQuery does not.
2) Avoid changing the height of elements where that will change the size/position of other elements (or the extension pop-up).
Instead use just opacity and transform CSS elements on an absolutely positioned element to ensure that the entire animation can be handled by the GPU without reflow.

When resizing a div containing floats with javascript the floats don't reflow

I have a container div that holds about 20 more divs that float left. When I resize the parent div with a javascript animation using Tween.js the floats don't reflow to the new size unless I mouse over one of the divs.
It seems like something is preventing the page from refreshing.
I'm thinking maybe there is a way through javascript to force the display to update?
UPDATE:
I've put it on JS Fiddle:
http://jsfiddle.net/mattlundstrom/fNUhn/
Click any thumbnail to toggle the animation.
This version uses TweenLite to animate the "Left" CSS of the #project-container. Notice how you must move your mouse after the animation to get the container's contents to reflow.
I get this result in Safari 5+ OSX and Chrome 20+ OSX. Works as expected in Firefox 13.0 OSX.
UPDATE 2
Video of what I'm seeing:
http://f.cl.ly/items/1R1n2s0U3I3c1M3s2K0T/lundstrom_float_issue.mov
I was able to recreate your issue just as you said. It seems that it is an issue with webkit redrawing or measuring the elements after an animation or transition.
This isn't the best solution by any means, but for the time being at least it will work and hopefully what I found will help other people to be able to find out more.
If you add an onComplete to the animation, and trigger the .project mouseleave, it looks to work fine:
function completeAnimate(){
$('.project').trigger('mouseleave');
}
function contract(){
// PROJECTS CONTRACT RIGHT
TweenLite.to($('#projects-container'), .5, {css:{left:"300px", opacity:".5"}, ease:Expo.easeInOut, onComplete: completeAnimate});
}
So here is my jsfiddle which has a few tests and other animation tests so that you can see some of what I tried.
jQuery animate() and css keyframe animations have the same result as the Tween code you are using, HOWEVER, a straight style update works fine.
$('#projects-container').css('left','300px');
No issues with that at all, but of course, no animation either.
Some other things I noticed was that if you take out the .project event bindings, it still doesn't redraw correctly, however if you move you mouse it still doesn't. It simply stays that way.
I also tried forcing an element redraw using a few tricks you can usually use to force a redraw. I tried this oncomplete and at intervals after the animation begins, but had no luck with any of it.
You can also combine the two tweens into one with the properties on both, just an FYI.
Hopefully this will help someone find the true issue that's going on with the webkit transitions.

Categories

Resources