Why doesn't Isotope use 3d transforms for performance? - css

I'm using Isotope (isotope.metafizzy.co) with a Masonry Horizontal layout. Example:
http://codepen.io/desandro/pen/oCiAD
It works just fine, but I'm curious as to why the library sets the left/right and top/bottom properties instead of using transforms. It's my understanding that using 3D such as
transform: translateZ(0);
or
transform: translate3d(0,0,0);
will force the element onto another layer, triggering GPU rendering and better performance. I realize this is probably done intentionally, but I'm not clear as to why.
Have browsers improved and is this no longer necessary? If not, is there a way to enable 3d transforms in Isotope?
Thanks in advance.

I think one of the reasons could be that Webkit treats 3d transformed elements as textures instead of vectors in order to provide hardware 3d acceleration which could cause a blurry text or anti-aliasing issues.
Example:
http://jsfiddle.net/gibbok/ccw7vvvg/
-webkit-transform: translate3d(0px, 100px, 0px);

Related

How to GPU accelerate CSS transform?

I know that sometimes browsers will GPU accelerate a CSS transform. But when does that happen, and is there a way to force GPU acceleration for a smooth animation?
this article
Most modern browsers support GPU acceleration, but they only use it when they think a DOM element will benefit from it. The strongest indication is that a 3D transformation is being applied. So use the 3D-equivalent transform. For example, instead of transform: translateX(50px), use transform: translate3d(50px, 0, 0). See this article for more information.
You can use the css "will-change" property:
will-change: transform;
Some css properties which are GPU accelerated (not always):
filter
opacity
transform

ThreeJS CSS3DRenderer / CSS Animation Issue

i was looking for a way to display plain text ( 2d or 3d ) in a threeJS Scene , and apply some css effects to them , i looked around for a while and i came across this . probably what i wanted ..
now the problem is that when i aplly a animate.css ( well knows css animation library ) class to html element , the position of my CSS3D Object is reseted and fliped ( can't explain why )
'http://jsfiddle.net/kd9Tc/4/'
note :
-i think this code example illustrates pretty well what i am trying to do , apply css text effects in webGL Scene ( i need all the camera movement and tweening ) .
i tried THREE.TextGeometry first , but i wanted the text to be in a language other than english and converting the font properly let to nowhere ( displayd ' ?????? ' in all my tests ) and beside that , i've been using css transforms for a while now and i'm pretty comfortable with them , and working with them is much easier for me .
overall the main reason i'm using threeJS is camera movement capability .
i'm glad that i used threeJS beacuse it open's the door to many other features as well , but yet , i'm not sure i;m using ther right tool here :-?
thanks
When you apply a CSS transform on an element drawn by ThreeJS' CSS3DRenderer, it overrides an initial translation and rotation originally set by the renderer itself.
After looking at your fiddle and then looking at the CSS3DRenderer in GitHub I can assess that the renderer does some toying around with the CSS translation and rotation of the elements within, before drawing them, in order to show what you'd expect out of the box (versus what's logical taking into account the way TheeJS handles its coordinates).
Here are the specific lines which I'm referring to. (ThreeJS GitHub)
In order to apply CSS transforms effectively across CSS3DRenderer be sure to not override the translation and rotation transforms. Simply put, take the following into account as the relative origin to every transform:
translate3d(-50%, -50%, 0) rotateX(180deg) rotateY(180deg)
For example this:
-webkit-transform: none;
transform: none;
Would become this:
-webkit-transform: translate3d(-50%, -50%, 0) rotateX(180deg) rotateY(180deg);
transform: translate3d(-50%, -50%, 0) rotateX(180deg) rotateY(180deg);
Here's a modified version of your fiddle which now works somewhat as expected.
(I didn't take the time to correct the X-axis translates, but you should get the gist of what I'm saying.)
Another way of working around this problem would be to somehow extend the CSS3DRenderer so that it corrects the rotate transforms on the fly instead of only at instantiation.
Why is the renderer doing this?
My best guess is that when the renderer was coded, they were expecting transforms to be applied via JavaScript and not CSS.
If you're truly more comfortable with CSS transforms I'd say go right ahead with what you are using. On the other hand if you feel a little more adventurous I'd suggest using TweenJS for animations with ThreeJS. They play quite well together. I use them on my website (link on my profile).
P.S.
#KianP Kudos on the fiddle you've put up. I can honestly say you are working on some pretty interesting stuff and you're using a set of tools that I wouldn't have thought of using together (Animate.css and ThreeJS) but seem to work quite well (Taking into account you correct the positioning as explained above).

CSS3 Animations and best performance on mobile

I am making an app and realised that it is best to hardware accelerate animations.
I wanted to use jQuery animate enhanced, which works but I feel I want a better grasp on the whole idea of hardware acceleration:
When moving a div using top/left positioning for example using jQuery, will it automatically be hardware accelerated by adding transform: translate3d(0, 0, 0); ?
Will this hardware accelerate anything? Also, what about animation keyframes? Will you need to add a transform to an animation for it to be hardware accelerated?
Paul Irish wrote a great, in-depth breakdown of this very thing.
Usually 3d translation will trigger the GPU, if it doesn't, it's no big deal, it still works. Using translate over left/top coordinates is usually better performance-wise as well. I'm not sure about the animation keyframes part of the question though.

List of hardware accelerated CSS properties for mobile safari

I went across change logs of MobileSafari in iOS 6 where it states:
WebKit no longer always creates hardware-accelerated layers for
elements with the -webkit-transform: preserve-3d option. Authors
should stop using this option as a way to get hardware acceleration
Does there exist any list of hardware accelerated CSS properties ?
These aspects of your document can be accelerated by the GPU:
General layout compositing
CSS3 transitions
CSS3 3D transforms
Canvas Drawing
WebGL 3D Drawing
More on this here http://www.html5rocks.com/en/tutorials/speed/html5/
Maybe this article will help toohttp://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/
And this one http://mobile.smashingmagazine.com/2012/06/21/play-with-hardware-accelerated-css/
Paul Lewis & Paul Irish have a really good article about High Performance Animations.
"We’re going to cut straight to the chase. Modern browsers can animate four things really cheaply: position, scale, rotation and opacity. If you animate anything else, it’s at your own risk, and the chances are you’re not going to hit a silky smooth 60fps."
4 things a browser can animate cheaply
Position - transform: translate(n px, n px);
Scale - transform: scale(n);
Rotation - transform: rotate(n deg);
Opacity - opacity: 0..1;
TranslateZ() or Translate3D() may be required.
Source: http://www.html5rocks.com/en/tutorials/speed/high-performance-animations/

How to force re-render after a WebKit 3D transform in Safari

I'm using CSS 3D transformations to zoom a div, for example:
-webkit-transform: scale3d(2,2,1);
The scaling itself works fine in any WebKit browser. However, when using this on Safari (mobile or Windows), the content of the div is not re-rendered. The result is that the content gets blurred after scaling.
This effect only occurs when using 3D transformations. Everything works fine when using
-webkit-transform: scale(2);.
In order to exploit hardware acceleration on iPhone/iPad, it would be nice to use the 3D transformations.
Does anybody know how to tell Safari to re-render a div with the new scale?
The reason why the text is blurry is because Webkit is treating the text as an image, I guess it's the price of being hardware accelerated. I'm assuming you are using transitions or animation keyframes in your ui, otherwise the performance gains are negligible and you should switch to non-3d transforms.
You can either:
• Add an eventlistener for transitionend and then replace the 3d transform for a standard transform, such as...
element.addEventListener("transitionend", function() {
element.style.webkitTransform = 'scale(2,2)'
},false);
• Since Webkit treats stuff as an image, it's better to start big and scale down. So, write your css in your "end state" and scale it down for your normal state...
#div {
width: 200px; /*double of what you really need*/
height: 200px; /*double of what you really need*/
webkit-transform: scale3d(0.5, 0.5, 1);
}
#div:hover {
webkit-transform: scale3d(1, 1, 1);
}
And you get a crispy text on hover. I made a demo here (works on iOS too):
http://duopixel.com/stack/scale.html
I found when trying to force a redraw of a div in safari for other reasons (recalculate text-overflow on hover), that is simple:
selector {
/* your rules here */
}
selector:hover {
/* your rules here */
}
selector:hover:after {
content:"";
}
I did something on hover that changes the padding to accommodate some buttons, but in safari/chrome it doesn't recalculate the content correctly, adding the :after pseudo-class did the trick.
I'm trying to do the same thing. I think what's happening here is that Safari is just scaling pixels. That is, it does all its "normal" browser rendering and then scales the pixels of the result.
Example: Place a relatively high quality image (say 1000x1000 pixels) in a small div (200x200 pixels) and set the image to 100% width and height. When you 3D transform the div to scale 5 times, the result will be blurry in Safari and crisp in Chrome. Use a 2D transform and the image will appear crisp in both.
A workaround is to convert to a 2D transform after you are done with the 3D. However, I've found there is a slight delay when converting between transforms so this isn't working too well for me.
I couldn't find a fix for making zoom-ins not blur in Safari (desktop v7.0.2 and the one included in iOS 6.1.3 and 7.0.6) but I did at some point, notice that I got a sharp png when I set the scale to 5. I don't know why, since that version of my code is lost in all the subsequent changes I made. All other scale factors were blurry.
Since the iPhone and iPad are target devices for this project I ended up abandoning scale transform and animating image height instead. I'm disappointed that the Safari team decided to implement transforms in a way that make them an unviable option in so many cases.
Hmmm... I'm getting the same issue trying to scale up google maps images (hidpi) with Chrome 53.
The only solution I've found so far is to hide the image (or a div that contains the images) and then show it again. Can be with opacity=0 or visibility=hidden, but it actually has to be invisible for at least a frame or two.
This, BTW, isn't even a 3d transform. Just 2D stuff.
Hmmm... I'm getting the same issue trying to scale up google maps images (hidpi) with Chrome 53.
One solution is to hide (opacity, visibility) the image for a few frames (or a container wrapping the image/images/whatever it is)... the better solution which I found in another post on SO was this (issued on the containing DIV):
e.style.transform = 'translateZ(0) scale(1.0, 1.0)'
BTW, my stuff was just ordinary 2d stuff, the translateZ seems to make the difference though, even though I never touched anything 3d.

Resources