CSS3 Animations slow on IOS devices - ios

I'm currently in the process of building a new mobile responsive site for my company that uses a number of CSS3 transitions on scroll to make images pop into focus. The effect is very striking and works great on modern browsers as well as my Google Nexus devices.
The problem I have is that the animations themselves are really slow on Apple Devices. I've tried them on a 1st Generation Ipad and an IPhone 5. On the Nexus you can scroll to the area of the page the animations are on and they will pop in straight away. On Apple devices however you have to wait for several seconds for the animations to trigger.
I have used the following library to achieve these animations:
http://www.justinaguilar.com/animations/scrolling.html
If you browse to this url on an Apple device, you will see what I mean with regards to the animations taking a while to load. After some research online I found that many suggest it could be due to the graphics processor not kicking in on these devices meaning everything is rendered (slowly) using the processor. To get around this it is suggested that the following is added to the animations to ensure the graphics processor kicks in:
-webkit-transform: translateZ(0);
However, I have already tried this to no avail. After some further research I have found that many suggest to replace translateX or translateY with translate3D but I have not tried this method yet as I do not understand how I would convert the following example:
/*
==============================================
fadeIn
==============================================
*/
.fadeIn{
animation-name: fadeIn;
-webkit-animation-name: fadeIn;
-webkit-transform: translateZ(0);
animation-duration: 1.5s;
-webkit-animation-duration: 1.5s;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
visibility: visible !important;
}
#keyframes fadeIn {
0% {
transform: scale(0);
opacity: 0.0;
}
60% {
transform: scale(1.1);
}
80% {
transform: scale(0.9);
opacity: 1;
}
100% {
transform: scale(1);
opacity: 1;
}
}
#-webkit-keyframes fadeIn {
0% {
-webkit-transform: scale(0);
opacity: 0.0;
}
60% {
-webkit-transform: scale(1.1);
}
80% {
-webkit-transform: scale(0.9);
opacity: 1;
}
100% {
-webkit-transform: scale(1);
opacity: 1;
}
}
My question therefore is twofold:
How would I convert the code above so that it uses the supposedly faster transform3d or scale3d syntax?
Are there any other methods I could use to improve the performance on these (Apple) devices so that they match the performance on more standards compliant devices such as the Nexus range?
Any help would be greatly appreciated.

Related

How to set opacity animation working on Iphones?

I want to create a simple animation on ::after and ::before elements and on Desktop everything works well but on iOS, on Chrome I'm getting no opacity effects.
#keyframes sunshine {
from {
opacity: 30%;
transform: scale(0);
}
to {
opacity: 0%;
transform: scale(4);
}
}
This opacity is not working on iPhones and instead of opacity effect, I'm getting 100% background-color.
Is there any way to turn on the Alpha channel on iPhones ??
Try to give opacity value in floating-point numbersopacity: .3 instead of percentage values. Safari browser won't allow percentage value.
https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html

CSS animation bug on Safari

I have a CSS animation bug on Safari where the wave animation I created does not behave as expected.
below is my animation keyframe:
#keyframes wave {
20% {
transform: translateY(-18px);
}
0%,
40%,
100% {
transform: initial;
}
}
I created a pen for it - https://codepen.io/ikhazen/pen/BXdqrN
it behaves as expected in other browsers but not on Safari iPhone 6s.
To explain what was happening on my iPhone.
The first three dots animate at once, followed by the 4th and 5th dots. it seems like the animation-delay property isn't working very well.
and sometimes, I noticed that all dots animate at once. which is weird.
Thanks
I can see a similar problem on Safari on Mac OS, except the first dot goes on it's own, followed by the rest together. I have created a working pen here.
The problem is with the following css in your pen
#-webkit-keyframes wave {
20% {
transform: translateY(-18px);
}
0%,
40%,
100% {
transform: initial;
}
}
Changing it so that the percentages are in order fixes it:
#-webkit-keyframes wave {
0% {
transform initial;
}
20% {
transform: translateY(-18px);
}
40% {
transform: initial;
}
100% {
transform: initial;
}
}
If I am interpreting the specification correctly when it says
To determine the set of keyframes, all of the values in the selectors are sorted in increasing order by time
then this would seem to a bug in Safari, as the order in which you specifiy the keyframes should not matter.
If anyone stumble upon this, try using a negative value in your animation-delay property.
here's the link https://codepen.io/ikhazen/pen/BXdqrN
&-6 {
background: #c73e2c;
animation-delay: -150ms;
-webkit-animation-delay: -150ms;
}
&-5 {
background: #ac3c3f;
animation-delay: -300ms;
-webkit-animation-delay: -300ms;
}
&-4 {
background: #903a51;
animation-delay: -450ms;
-webkit-animation-delay: -450ms;
}
&-3 {
background: #733866;
animation-delay: -600ms;
-webkit-animation-delay: -600ms;
}
&-2 {
background: #573678;
animation-delay: -750ms;
-webkit-animation-delay: -750ms;
}
&-1 {
background: #3c348a;
animation-delay: -900ms;
-webkit-animation-delay: -900ms;
}
This part:
&-1 {
background: #3c348a;
animation-delay: 150ms;
}
is missing -webkit-animation-delay: 150ms;
Working code:
&-1 {
background: #3c348a;
animation-delay: 150ms;
-webkit-animation-delay: 150ms;
}
Advice: use css autoprefixer to avoid such errors.

WebKit Transform Wrong Transition

I'm trying to animate two images from a fixed position to side-do-side, using transition and transform/translation code.
It works right on Firefox / Chrome but on WebKit devices like iPhone and Safari it acts oddly. Basically the animation ends on the right place, but the transition don't.
.anim div{
transition: ease all 1s;
}
.anim div.transformed.a{
transform: translate(150%, -11%);
}
.anim div.transformed.b {
transform: translate(50%, -110%);
}
Here's a demo:
https://jsfiddle.net/0o8L1jg2/1/
On Safari the image goes all the away across and then suddenly sticks to the final position (which happens to be right). Any way to make the transition acts correctly on here?
Add the webkit prefix for webkit devices.
.anim div{
transition: ease all 1s;
-webkit-transition: ease all 1s;
}
.anim div.transformed.a{
transform: translate(150%, -11%);
-webkit-transform: translate(150%, -11%);
}
.anim div.transformed.b {
transform: translate(50%, -110%);
-webkit-transform: translate(50%, -110%);
}

iOS6 UIwebView CSS3D transforms are not HW accelerated

I have problems with poor scrolling performance in iOS6 UIWebView component..In iOS5 scrolling was really fluid, though. So I have searched the web little bit and found this (part of iOS6 beta changelog).
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.
That could be the reason, since the html site my app displays uses lots of css3 transformations..
Please have anyone a solution or advice how to force webview switch back to accelerated rendering model?
Besides the already mentioned change of the CSS-properties that are(or are not) triggering hardware acceleration I have noticed another change on iOS6 that did not persist as heavily on iOS5 (or at least I did not really notice it before):
Overlapping between hardware-accelerated elements and non-accelerated elements will slow down rendering and the app A LOT.
If you have any overlappings between accelerated and non-accelerated elements, make sure that you add hardware-acceleration to those other elements even if they are not animated or so, because they will be re-rendered as well which will completely supress or in some cases revert the acceleration-effect.
I have also written an short article about this if you want to check it out:
http://indiegamr.com/ios6-html-hardware-acceleration-changes-and-how-to-fix-them/
UIWebView still does hardware acceleration if you use a 3D transform (e.g. -webkit-transform: translateZ(0)). It just no longer does if you only use -webkit-transform-style: preserve-3d.
If you have an example that is doing 3D transforms, but got slower with iOS 6, you should report it at Apple's Bug Reporter.
I've attached a simple test case which reproduces this bug in iOS6, and which runs perfectly fine on iOS5.1 (on both iPhone 4 and 4S). The iOS Chrome app is a good place to run this test, since it embeds a UIWebView. I have a video which I'll attach once it uploads of two iPhone 4's (the top one running iOS 5.1, the other running iOS 6) running this example script inside a PhoneGap 2.0 UIWebView.
Right now, it seems like these elements ARE being hardware accelerated, but that there's a bug in Apple's low-level pipeline which kills performance. We've tried a number of workarounds for hardware acceleration, and it certainly seems that anything which invokes the GPU on iOS5.1 causes a massive slowdown on iOS6.
I would love to find a fix, since the app we're building relies pretty heavily on this working properly. If someone can point out an error in this example, that would also be extremely appreciated.
EDIT: The bug persists even if you modify the animate function as follows.
function animate(node) {
node.style.webkitAnimation = 'sample 5s infinite';
node.style.webkitPerspective = 1000;
node.style.webkitBackfaceVisibility = 'hidden';
}
This seems to reinforce that invoking the GPU causes this slowdown.
EDIT 2: There's an additional example hosted at http://bvgam.es/apple/ which runs smoothly on iOS 5.1, and gets 1-2 FPS on iOS 6.
<!DOCTYPE html>
<html>
<head>
<title>Animation Playground</title>
<style>
#-webkit-keyframes sample {
0% { -webkit-transform: translate3d(0px, 0px, 0px); opacity: 1; }
10% { -webkit-transform: translate3d(0px, 0px, 0px); opacity: 0; }
20% { -webkit-transform: translate3d(10px, 0px, 0px); opacity: 1; }
40% { -webkit-transform: translate3d(10px, 10px, 0px); opacity: 0; }
50% { -webkit-transform: translate3d(10px, 20px, 0px); opacity: 1; }
80% { -webkit-transform: translate3d(20px, 20px, 0px); opacity: 0; }
100% { -webkit-transform: translate3d(0px, 0px, 0px); opacity: 1; }
}
</style>
<script type="text/javascript">
function fib(node, a, b) {
node.innerHTML = a;
setTimeout(function() {
fib(node, a + b, b);
}, 0);
}
function animate(node) {
node.style.webkitAnimation = 'sample 5s infinite';
}
function createNode(row, column) {
var node = document.createElement('div');
node.style.width = '7px';
node.style.height = '7px';
node.style.position = 'absolute';
node.style.top = 30 + (row * 9) + 'px';
node.style.left = (column * 9) + 'px';
node.style.background = 'green';
return node;
}
function run() {
for (var row = 0; row < 20; ++row) {
for (var column = 0; column < 20; ++column) {
var node = createNode(row, column);
document.body.appendChild(node);
animate(node);
}
}
var output = document.getElementById('output');
fib(output, 0, 1);
}
</script>
</head>
<body onload="run()">
<div id="output" style="font-size: 40px; position: absolute; left: 220px;"></div>
</body>
</html>
Try replacing all instances of -webkit-transform: translate3d(0,0,0);
With
-webkit-transform: translate3d(0,0,0) scale3d(1,1,1);
It did work for me
CSS Transforms are indeed a lot slower in iOS 6, at least in my application on iPhone 4.
I set basic translate() to element, instead of translate3d(), and performance stayed the same, so I think even translate3d() no longer triggers GPU acceleration. That sounds like a bug.
As a workaround, I tried setting a different CSS properties (like rotate3d(), scale3d(), perspective, ...) on element, but neither of them seems to trigger hardware acceleration.
Try replacing all instances of -webkit-transform: translate3d(0,0,0); with -webkit-perspective: 1000; -webkit-backface-visibility: hidden;. This worked for me. It's seems that -webkit-transform: translate3d(0,0,0); no longer invokes hardware acceleration.
Could those reporting that -webkit-transform: translate3d(0,0,0); is slower in iOS 6, please provide a URL to some sample content that shows this.
Just to let some know, that -webkit-transform-origin was previously hardware accelerated if used together with hardware accelerated transformations, like translateZ(0), but it no longer is.

CSS3 Infinite Rotation animation on iOS5

So I'm trying to infinitely rotate a png on my webapp for iOS but having a hard time getting it to work in the simulator. Here my CSS:
#spinner { -webkit-animation: spinner 1s infinite linear; }
#-webkit-keyframes spinner {
0% { -webkit-transform: rotate3d(0,0,1,0deg); }
100% { -webkit-transform: rotate3d(0,0,1,360deg); }
}
it works perfectly on latest Chrome.. however, mobile safari doesn't seem to like 0-360. I tried 0 to 180 and that works for some strange reason... how can i go all 360 degrees?
Thanks!
as YuriAlbuquerque said, you can do it like this
#-webkit-keyframes spinner {
0% { -webkit-transform: rotate3d(0,0,1,0deg); }
25% { -webkit-transform: rotate3d(0,0,1,90deg); }
50% { -webkit-transform: rotate3d(0,0,1,180deg); }
75% { -webkit-transform: rotate3d(0,0,1,270deg); }
100% { -webkit-transform: rotate3d(0,0,1,360deg); }
}
Removing 25% and 75% in keyframes also works but only in less than ios6. In ios6, if you don't add 25% and 75%, than it will rotate clockwise 180deg and than anticlockwise from 180deg to 360deg.

Resources