-webkit translate3d stutters with large elements - javascript

I'm animating elements using -webkit-transform: translate3d(x,y,z) and the cubic beizer timing function combined with touch-events for the iPhone to make a custom scrollmethod type thing.
Trouble is, the animations stutter (element stops for half a second) if the elements (in this case page div's) are above a certain size. If I have width 320px and height of 1000px, this all works just fine, but if I make the height 2000px I get a nasty stutter. Note that it only stutters once in the beginning, almost like it's loading and then it's fine.
Are there any known work-arounds?

Two possible workarounds.
First turn off other CSS properties, namely position (top, left, right, bottom), and opacity. Mixing them, especially if they are animating, can cause performance issues.
You could try experimenting with turning off as much as possible, and seeing if the issue is then fixed. If so, then turn them back on one by one, until the problem property is found.
Second, wrap your content within an iframe. Even if the iframe is set to fill the view, it can give a significant performance improvement, when it contains very large images.

Related

How to make a whole webpage fit whatever window it is on like a scaled image and be unzoomable?

We used to have a silverlight page that used canvas to scale the page, this resulted in a page that would always be the size of the window it was on, making the whole page smaller if the window was smaller (it does preserve aspect ratio), as if the page was a single png but it isn't, it has dynamic elements. Also when one tries to zoom in or out, it does nothing, it just makes a scroll appear to the right and bottom without affecting the page.
We are migrating the page to HTML 5 with CSS, and we haven't been able to replicate this behavior. It is a page that has 10 small tables and each has 10 "messages" that can appear. When zooming in stuff starts to overlap in addition to change size, when resizing the window,stuff overlaps too but without changing size. Most of the positions are absolute but have % in their position onscreen. However we don't want it to be responsive, we want the behavior of the silverlight version. At least that's what the bosses want.
We have been researching how to do this but so far haven't really found a good solution, especially with messing the zoom functionality of browsers. most pages/forums say this shouldn't be done.
Edit:
For now I have added a bunch of max-width and max-height in the html style and body style, as well as added a media query for switching % left to px left for an absolutely positioned group of objects. However this is by no means whay I seek to accomplish. We need the whole page to behave like an bgimage, scaling every element with the size of the window.

Parent DIV's CSS interferes with SVG animation

We've moved an SVG/JS animation created with the Adobe After Effects Bodymovin plugin from one Wordpress site to another. On the old site (which I unfortunately can't show you), the animation works flawlessly. On the new site, depending on the size of the browser window, the animation contains glitches that appear to be caused by some sort of rounding error in the animation mask.
On one or more edges of the globe, you can occasionally (depending on viewport width) see a one pixel-wide bit of the scrolling background graphic appear. See image.
I've isolated the animation in CodePen. It works fine here, no matter what size the viewport is set to.
However, when I introduce this tiny bit of CSS such as this...
margin: 0 auto;
width: 70%;
... into the style of the parent DIV, the glitch starts happening. See here.
On the original animation, the mask extends a lot further than the edges of the globe, so I suspect the fact that the mask now just reaches to the edges of the globe is some sort of Bodymovin optimization.
Given that this doesn't happen on the old site, I suspect there is some sort of CSS, or perhaps a setting in Bodymovin, that stops this from happening.
The Wordpress site is built with Divi, and the animation sits in a DIV nested inside many other DIVs (ie a module sitting in a column sitting in a row sitting in a section), and most of these DIVs have the width set to various percentages. So I don't think the solution will lie in simplifying the CSS.
Has anyone experienced a problem like this before? Or have suggestions that might help eliminate it?
I have also created an Issue in the Bodymovin GitHub page, but the response times there seem to vary greatly.
I have made some testning on the codepen and was able to make it work when i removed
transform: translate3d(0px, 0px, 0px);
so removing this line of the script should fix the problem
this.svgElement.style.transform="translate3d(0,0,0)")
Why are you trying to transform the svg, when its already transforming automaticly.
This is a possible fix if you still want to retain the settings with margin and width %.
You can avoid this issue by giving a width in pixels to #container the responsiveness of percentages sometimes causes pixels to be just slightly off. Use media-queries if you need to have different sizes for other screen dimensions.
#container {
margin: 0 auto;
width: 400px;
}

Image Decode times from Chrome Timeline dev tool

I'm building a parallax scrolling website (aren't we all) that amongst other things, reveals an image as the user scrolls.
I've done the 'reveal' by putting the image in the background, and placing a solid filled div on top. I then animate this div from 100% height to 0% height based on the scroll position, thus revealing the background image.
I'm doing this kind of thing multiple times and unfortunately I'm getting slow down.
Using Chrome's built in Timeline feature, I can see that most of this slow down is from Image Decodes. For the above reveal, it's re-Decoding the image every frame, which takes 22ms per image per frame.
Does anyone know when the browser needs to do Image Decode and when it doesn't? It seems obviously to me that it would need to if I resized the image, but not that it would need to when I just half cover the image?
Thanks for your help.
I've battled with this problem a lot also. As yet I have not found anything concrete and my proposed solution does not seem to work in ALL cases and I have not been able to ascertain why.
Anyway...
It appears that when you animate a solid element over the top of an image, chrome forces a recode of the image.
There are two things I have tried and for the most part they have been successful.
If you add -webkit-transform : translate3d(0,0,0) to the covering element, you should find most, if not all of the image decodes disappear.
If adding the above CSS to the covering element itself does not help, try adding it to the image instead, or indeed try adding it to both elements.
My understanding is that using the 3d css property pushing the image into its own composite layer which is cached and handled by the GPU rather than the browsers software renderer.
90% of the time I have found one of the above combinations successful. I hope it helps.
How do you animate the property? I think you may have plenty of alternatives to just animating the height (which is some sort of resize of the container).
Maybe it's less intensive to just 'clip' the background image with another element. I found a thread about it on StackOverflow with some suggestions. If you animate with javascript, unfortunately pseudo elements are no option...
Clip/Crop background-image with CSS

Stutter when animating / moving sprite with JavaScript

I'm attempting to create an animation by moving a sprite image across a div. The sprite image contains each frame of the animation. The size of the "canvas" is 600px by 624px. Each frame on the sprite sheet is positioned every 600px and I'm moving the image 600px at a time.
Here is what I have so far...
voyced.com/crownacre/www/demo/sprite.html
I'm using the following JavaScript to move the image across the screen...
(function myLoop(i) {
setTimeout(function() {
defImg.css({
right: '-=600'
});
if(--i) myLoop(i); // decrement i and call myLoop again if i > 0
}, 60) // delay ms
})(114); // number of frames in the sprite
I've used several sprites all floated left as the total width of sprite sheets in 69000px, which causes even more issues if I use just one image! Hence why I have 4 at the moment.
So... The problem I am having is that the animation pauses briefly several times. It seems fine in Firefox (for me), but you notice it in Chrome and you can't miss it in IE.
It also always stutters every 16200px, making me think this is related to moving 1 sprite into the next on the screen.
Ideas please people?
Thanks in advance!
Have you tried using a sprite animation plugin?
http://www.spritely.net/
Does what you want, seems to run well on their demo.
Let me first say: The huge images you're trying to display as a sprite isn't exactly what sprites/animations are used for. You can better look into a real <canvas> solution (especially when looking at your animation), but that would require some more complex JavaScript skills.
Anyway, the problem with the stutter is because you're using several images that are all floated to the left, and position the slider with the right property. Each time another image needs to be displayed, a stutter can be noticed. This might have something to do with the browser engine, needing to paint the actual image (which is hard, since they're pretty big).
So, instead of using several images, you could also use one (take note, you might want to make this a .JPG or .GIF since they tend to be more compact than .PNG) and use actual CSS sprites with background-position.
Here's an example that uses your code, and one single image. Good luck!
Thanks again for the feedback guys. I used a combination of your tips that have helped me solve the issue I was having.
Spritely has helped immensely. Essentially it is doing the same as what #marcoK suggested, and adjusting the background-position property. This plugin also provides a fool proof way of controlling each frame of the sprite, as well as creating callbacks when it reaches a specified frame - awesome!
The other issue was the huge sprite. Mobile safari won't allow anything larger than 3MP so the max size I could make the image was 4800x624. I have 15 of these each as a separate animation that calls the next when it reaches the last frame. I was very sceptical about this working smoothly, but it does, and in all browsers.
I'm not overly happy with the number of request it makes but after optimising the pngs the file size isn't too bad if I add a pre-loader.
Really pleased with the outcome... http://www.crownacre.voyced.com/ and one more reason not to use Flash!

Animate page reflow?

I am switching the contents of divs (fading old contents out, then fading new contents in) and because they are slightly different contents, the moment they change there is a jarring reorganization of everything below them.
My question is, is there a way to make this movement smooth?
I suspect that pretty much the only feasible way to do this is to use javascript to determine ahead of time what the heights (in my case I only deal with blocks where the vertical alignment shifts) of the starting and ending elements are, and assign these values directly. Once I do this I am sure CSS3 transition will apply a pleasant animation.
Is there perhaps a way to get this without specifying explicit dimensions? I seem to recall at some point having experienced items getting moved around the page in an animated fashion. This gives me hope that it could be done using just CSS.
I'd normally create a temporary (invisible) element holding new content so as to calculate its height. After that, the original element can be animated from its current height to the newly calculated height.
It is important that the temporary element created is an identical sibling of the original element so that all the necessary styles cascade and get inherited correctly (for instance, calculating new content height is useless if it doesn't have correct font-size applied)
While animating between different heights set explicitly (i.e. with JS as described above) can be accomplished with CSS3 (transition: height .5s ease;), it will not work for different heights set implicitly (i.e. modifying element content with height:auto)

Categories

Resources