CSS transition events extremely slow on IOS - javascript

I am developing a single-page Javascript application that runs on desktop browsers and also on mobile devices via Cordova/Phonegap.
I have a slide-out menu that is implemented using CSS transitions. I noticed that it works well on desktop browsers and android. However, on IOS there are serious performance issues. The transition does not appear to start on time, but once it starts the rendering and duration looks fine. The time between starting the transition and the transitionend event is way higher on IOS than other platforms. For example, the duration of the transition is 300ms but I'm not getting the transitionend event for 1500ms. On all other platforms, I get the transitionend event in 325-350ms.
Transitionend Event:
Expected: 350ms
Actual: 1500ms
Platforms:
Cordova 6.3.1
Xcode 8.1 GM Seed
IOS 10.1
Here is the CSS for the menu div. To slide-out the menu, I add the 'open' class. To close the menu, I remove the 'open' class. I've tried transitioning on the 'left' property and 'transform' property, but the results are identical.
/* Nav Menu */
#navmenu {
position: absolute;
top: 0;
width: 90%;
max-width: 400px;
z-index: 20;
height: auto;
background-color: white;
/*
-webkit-transform: translate3d(-100%,0,0);
-moz-transform: translate3d(-100%,0,0);
-ms-transform: translate3d(-100%,0,0);
transform: translate3d(-100%,0,0);
-webkit-transition: -webkit-transform 300ms ease;
-moz-transition: -moz-transform 300ms ease;
-ms-transition: -ms-transform 300ms ease;
-o-transition: -o-transform 300ms ease;
transition: transform 300ms ease;
*/
left: -100%;
-webkit-transition: left 300ms ease;
-moz-transition: left 300ms ease;
-ms-transition: left 300ms ease;
-o-transition: left 300ms ease;
transition: left 300ms ease;
}
#navmenu.open {
/*
-webkit-transform: translate3d(0,0,0);
-moz-transform: translate3d(0,0,0);
-ms-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
-webkit-transition: -webkit-transform 300ms ease;
-moz-transition: -moz-transform 300ms ease;
-ms-transition: -ms-transform 300ms ease;
-o-transition: -o-transform 300ms ease;
transition: transform 300ms ease;
*/
left: 0;
-webkit-transition: left 300ms ease;
-moz-transition: left 300ms ease;
-ms-transition: left 300ms ease;
-o-transition: left 300ms ease;
transition: left 300ms ease;
}
Question: What might be causing the delay in starting the transition, only on IOS platforms? Are there any known solutions to circumvent the problem or speed things up? I have other transitions in the app that take over 5s to start, making the app unusable. I'm hoping the menu solution will apply throughout the app. Thanks for any help or ideas you can provide.
Here is the instrumented Javascript code that I use to open/close the menu...
utilities.addEventListeners(navMenuButtonDiv, function () {
var start = Date.now();
var menuDiv = navMenu.getDiv();
if (menuDiv.classList.contains('open')) {
menuDiv.classList.remove('open');
} else {
menuDiv.classList.add('open');
}
var handler = function (event) {
console.log('Transition: ' + (Date.now() - start));
menuDiv.removeEventListener('webkitTransitionEnd', handler, true);
};
menuDiv.addEventListener('webkitTransitionEnd', handler, true);
};

When moving elements around the screen, you want to maximize performance. Instead of transitioning the left property, you're better off using translation. Using translation, the device will use its GPU to render the onscreen change, on a layer above the DOM. This will result in a smoother, more performant transition.
Have a look at this example. Besides using a transform instead of changing the left property, notice that I removed a bit of redundancy. You don't need to redeclare the transition on the active state.
var open = document.getElementById("open"),
close = document.getElementById("close"),
nav = document.getElementById("navmenu");
open.addEventListener("click", function() {
nav.classList.add("open");
});
close.addEventListener("click", function() {
nav.classList.remove("open");
});
#navmenu {
position: absolute;
top: 0;
left: 0;
width: 90%;
max-width: 400px;
z-index: 20;
height: auto;
background-color: white;
transform: translate3d(-100%, 0, 0);
-webkit-transition: transform 300ms ease-in-out;
-moz-transition: transform 300ms ease-in-out;
-ms-transition: transform 300ms ease-in-out;
-o-transition: transform 300ms ease-in-out;
transition: transform 300ms ease-in-out;
}
#navmenu.open {
transform: translate3d(0, 0, 0);
}
button {
margin-top: 100px;
}
<div id="navmenu">stuff in here</div>
<button id="open">Open Menu</button>
<button id="close">Close Menu</button>

Related

What do I change on JQuery Code to Click Text rather than change on Hover?

I am following the site shown below to create tabs on my Divi Site (on my localhost at the moment) but I was looking for some help in regards to changing the behaviour of the code.
https://www.elegantthemes.com/blog/divi-resources/how-to-create-custom-testimonial-tabs-with-divi-free-download
I have managed to follow the tutorial and this works exactly as shown on the site but I would like to change the behaviour from hover to clicking the blurbs (names) but not sure what part of the jquery I need to change.
The following is the jquery code:
jQuery(function($){
$(document).ready(function(){
$('#testimonial-person-1').addClass('testimonial-active');
$('[id*="testimonial-person"]').hover(function() {
var $selector = $(this).attr('id').replace('person', 'copy');
var $testimonial = $('#' + $selector);
$('[id*="testimonial-copy"]').removeClass('show-testimonial');
$testimonial.addClass('show-testimonial');
$('[id*="testimonial-person"]').removeClass('testimonial-active');
$(this).addClass('testimonial-active');
});
});
});
The CSS Code:
.show-testimonial {
visibility: visible !important;
opacity: 1 !important;
top: 0 !important;
}
.testimonial-active {
transform: translateX(-10%);
}
[id*="testimonial-person"]{
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
-ms-transition: all 0.5s ease;
transition: all 0.5s ease;
cursor: context-menu;
}
[id*="testimonial-copy"] {
-webkit-transition: all 0.3s ease;
-moz-transition: all 0.3s ease;
-o-transition: all 0.3s ease;
-ms-transition: all 0.3s ease;
transition: all 0.3s ease;
position: absolute!important;
top: -100px;
bottom: auto;
left: 0;
right: auto;
visibility: hidden;
opacity: 0;
}
I would appreciate it, if somebody could guide me in how I can make this change on my site.
Thanks in advance.
Thanks to David for pointing it out.
I have changed the following line:
$('[id*="testimonial-person"]').hover(function() {
and this does what I wanted.
Thank you so much.

Carousel loose responsive behaviour with "image in div" zooming on hoover effect

Using flickity carousel I've created the following example here in codepen.io link. Here is CSS code I've implemented:
CSS
.image-hoover {
overflow: hidden;
}
.image-hoover img {
-moz-transform: scale(1.02);
-webkit-transform: scale(1.02);
transform: scale(1.02);
-webkit-transition: all 10s ease;
-moz-transition: all 10s ease;
-o-transition: all 10s ease;
-ms-transition: all 10s ease;
transition: all 10s ease;
}
.image-hoover:hover img {
-moz-transform: scale(1.06);
-webkit-transform: scale(1.06);
transform: scale(1.06);
-webkit-transition: all 10s linear;
-moz-transition: all 10s linear;
-o-transition: all 10s linear;
-ms-transition: all 10s linear;
transition: all 10s linear;
}
The issue I can't figure out is that images loose responsive behavior only until I turn off this part:
.image-hoover img {
-moz-transform: scale(1.02);
-webkit-transform: scale(1.02);
transform: scale(1.02);
-webkit-transition: all 10s ease;
-moz-transition: all 10s ease;
-o-transition: all 10s ease;
-ms-transition: all 10s ease;
transition: all 10s ease;
}
But in this case when you unhover the image returns back to it size very fast loosing the transition effect, can you please suggest how to figure out this issue?
1. Here the responsive behavior of image is present, but zoom effect on hoover loose transition.
2. In this example you can notice that transition works great, but if you resize the window images loose their responsive behaviour.
It happens because you said for the transition to apply on all actions, so the 10s transition happens also when the images change thier when the screen changes width.
You will need to change
-webkit-transition: all 10s ease;
-moz-transition: all 10s ease;
-o-transition: all 10s ease;
-ms-transition: all 10s ease;
transition: all 10s ease;
to
-webkit-transition: -webkit-transform: 10s ease;
-moz-transition: -moz-transform 10s ease;
-o-transition: transform 10s ease;
-ms-transition: transform 10s ease;
transition: transform 10s ease;
And remove the transition from the :hover.
This will now work.
Fiddle-http://codepen.io/anon/pen/eJWQRq?editors=110

css3 transition is not smooth in safari

I'm rebuilding someone's else CSS3 transition to make it work across Safari, Chrome, and Firefox. In their version (mouse over the package images), the transition works well in Safari, but not in the other two: The elements get stuck in the "up" position. In my version, the transition runs smoothly in FF and Chrome, but is jerky in Safari (plus it's not rotating). Any ideas? My CSS is below.
.package-down {
display: block;
position: relative;
height: 100%;
float: left;
width: 33.333%;
margin: 0 0 0 0;
transform: rotate(0deg) ;
-webkit-transition: margin .1s ease, transform .25s ease;
-moz-transition: margin .1s ease, transform .25s ease;
-o-transition: margin .1s ease, transform .25s ease;
transition: margin .1s ease, transform .25s ease;
}
.package-up {
display: block;
position: relative;
height: 100%;
float: left;
width: 33.333%;
margin: -50px 0 0 0;
transform: rotate(-2deg);
-webkit-transition: margin .1s ease, transform .25s ease-out;
-moz-transition: margin .1s ease, transform .25s ease-out;
-o-transition: margin .1s ease, transform .25s ease-out;
transition: margin .1s ease, transform .25s ease-out;
}
While I agree that jQuery is not necessary for this problem, the real issue appears to be an inconsistent use of browser prefixes.
You needed to add prefixes for transform: rotate() on both .package-down and .package-up.
Also this:
-webkit-transition: margin .1s ease, transform .25s ease-out;
Should be this:
-webkit-transition: margin .1s ease, -webkit-transform .25s ease-out;
And it would be a similar adjustment for all the other prefixed transition properties.
See Codepen
$(function() {
$('.package-down').hover(function() {
$('.package-down').toggleClass('package-up');
});
});
img {
margin: 0;
max-width: 100%;
}
.main-packages-wrapper {
position: relative;
width: 80%;
min-height: 575px;
display: block;
padding-top: 80px;
z-index: 1; }
.package.original {
margin-right: -15px;
margin-left: -15px;
z-index: 2; }
.package.original img {
-webkit-transform: scale(1.2);
-moz-transform: scale(1.2);
-ms-transform: scale(1.2);
-o-transform: scale(1.2);
transform: scale(1.2);
}
.package-down {
display: block;
position: relative;
height: 100%;
float: left;
width: 33.333%;
margin: 0 0 0 0;
-webkit-transform: rotate(0deg) ;
-moz-transform: rotate(0deg) ;
-o-transform: rotate(0deg) ;
transform: rotate(0deg) ;
-webkit-transition: margin .1s ease, -webkit-transform .25s ease;
-moz-transition: margin .1s ease, -moz-transform .25s ease;
-o-transition: margin .1s ease, -o-transform .25s ease;
transition: margin .1s ease, transform .25s ease;
}
.package-up {
display: block;
position: relative;
height: 100%;
float: left;
width: 33.333%;
margin: -50px 0 0 0;
-webkit-transform: rotate(-2deg);
-moz-transform: rotate(-2deg);
-o-transform: rotate(-2deg);
transform: rotate(-2deg);
-webkit-transition: margin .1s ease, -webkit-transform .25s ease-out;
-moz-transition: margin .1s ease, -moz-transform .25s ease-out;
-o-transition: margin .1s ease, -o-transform .25s ease-out;
transition: margin .1s ease, transform .25s ease-out;
}
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<body>
<div class="primary-content">
<section class="main-packages-wrapper">
<div class="package-down multigrain">
<img src="http://www.batterworld.com/wp-content/themes/batterworld/images/package_multigrain.png">
</div>
</section>
</div><!--END PRIMARY CONTENT-->
I'm actually astonished that your jQuery hover function does work at all, because what you'd actually need is mouseenter -> addClass and mouseleave -> removeClass, but it might be me not exactly being aware of how jQuery's .hover() works.
Nonetheless, there is absolutely no need for jQuery or even Javascript to change styles on mouseover. You have the pseudo-selector :hover for exactly this purpose: Put the styles your want to transition to into
.package-down:hover { /* properties to transition to */ }
Next, do not repeat styles that the element already has and that do not change.
Last, if your problem is that not all property transition are taking an equal amount of time, don't specify so:
transition: margin .1s ease, transform .25s ease-out;
This will make the margin changes take 0.1s, but the rotation to take 0.25s.
Please describe more concisely what your transition is to look/perform like.
http://codepen.io/anon/pen/aOJmKe
Also, please be aware that you are not doing a css animation here, but a css transition. Read more about the differences here:
CSS: Animation vs. Transition
Yup, the javascript was definitely extraneous. All that was needed were CSS transitions applied to the :hover state of the elements. I did end up repeating some transition code, because that enabled the transitions to run in reverse when the cursor leaves the hovered element. Thanks! Finished codepen here.
.package.original img {
-webkit-transform: scale(1.2);
-moz-transform: scale(1.2);
-ms-transform: scale(1.2);
-o-transform: scale(1.2);
}
.package {
display: block;
position: relative;
height: 100%;
float: left;
width: 33.33%;
z-index: 1;
-webkit-transition: margin .15s ease-out;
-moz-transition: margin .15s ease-out;
-o-transition: margin .15s ease-out;
transition: margin .15s ease-out;
}
.package:hover {
display: block;
position: relative;
height: 100%;
float: left;
width: 33.33%;
z-index: 1;
margin: -50px 0 0 0;
-webkit-transform: rotate(-2deg);
-webkit-transition: margin .15s ease-out;
-moz-transition: margin .15s ease-out;
-o-transition: margin .15s ease-out;
transition: margin .15s ease-out;
}
.original:hover{
margin-left: -30px;
-webkit-transition: margin .15s ease-out;
-moz-transition: margin .15s ease-out;
-o-transition: margin .15s ease-out;
width: 33.33%;
z-index: 2;
}

change color and shape of div on click

When I click the div, I'm trying to make the div turn into a green 30x30 circle over a course of 2 seconds. And then 3 seconds after the animation is done running, I want the red area go back to its original state.
With my code so far, I'm able to click the div and change it's size to 30x30 and shape to a circle
Here's my code so far:
#blue-box {
height: 100px;
width: 100px;
background: blue;
/* transition:background-color .5s ease-in; */
transition: background-color 0.5s ease;
-webkit-transition: -webkit-transform 0.5s ease-in-out;
-webkit-transition: -webkit-transform 0.5s ease-in-out;
-webkit-transition: -webkit-transform 0.5s ease-in-out;
-webkit-transition: -webkit-transform 0.5s ease-in-out;
transition: transform 0.5s ease-in-out, background-color 2s ease 3s;
}
.box-change {
background-color: green;
border-radius: 100%;
-webkit-transform: scale(.3, .3);
-moz-transform: scale(.3, ,.3);
-o-transform: scale(.3, .3);
-ms-transform: scale(.3, .3);
transform: scale(.3, .3);
}
var box = $('#blue-box');
box.on('click', function(){
box.toggleClass('box-change');
if (box.hasClass('box-change'))
console.log("testing123");
else
console.log("testing testing!");
});
http://jsfiddle.net/gatordh7/gxes2ep3/
To the #blue-box div, I tried including: "transition:background-color .5s ease-in", and then setting the background-color to green on the .box-change class I toggled when the div was clicked, but I still can't figure this out.
What am I doing wrong?
Fixed in this one http://jsfiddle.net/gxes2ep3/3/
var box = $('.blue-box');
box.on('click', function(){
box.toggleClass('box-change');
if (box.hasClass('box-change'))
console.log("testing123");
else
console.log("testing testing!");
});
You were using id for the box, ids have a higher priority than classes. Also, the css background-color was not the same in blue box and in box-change rules. Ans you had a 3s delay for the color

Delaying child animations in a view

I'm new to AngularJS but before asking this question i've searched and searched for an answer on how to do this the Angular Way but have come up short.
What i'm looking to do:
Have child animations of a view trigger [delay] until after the view[parent] has animated in or has slightly animated in/out.
I currently have everything set up with ui-view and have the pages animating in and out without any problems. But, if I try to delay a child animation or have its animation longer than the duration of the parent animation then it just jumps instead of animating.
From what I can tell, this is because ng-enter and ng-leave get removed after the parent is done animating, as designed.
I have created a Plunker to show this: http://plnkr.co/edit/5iOb1j0l8lFaMZfrKIFh?p=preview
The animations are being done via CSS:
.ui-animate {
$enLvDur: .8s;
$delay: 1s;
&.ng-enter,
&.ng-leave {
position:absolute;
top: 100px; right: 0;
bottom: 0; left: 0;
transform: -webkit-translateX(0px);
transform: -ms-translateX(0px);
transform: translateX(0px);
}
&.ng-enter {
z-index: 2;
transform: -webkit-translateX(100%);
transform: -ms-translateX(100%);
transform: translateX(100%);
transition: -webkit-transform $enLvDur ease-in-out 0s;
transition: -ms-transform $enLvDur ease-in-out 0s;
transition: transform $enLvDur ease-in-out 0s;
.child-delay {
opacity: 0;
transition: opacity $enLvDur ease-in-out $delay;
}
}
&.ng-enter-active {
transform: -webkit-translateX(0px);
transform: -ms-translateX(0px);
transform: translateX(0px);
.child-delay {
opacity: 1;
}
}
&.ng-leave {
z-index: 1;
transform: -webkit-translateX(0px);
transform: -ms-translateX(0px);
transform: translateX(0px);
transition: -webkit-transform $enLvDur ease-in-out 0s;
transition: -ms-transform $enLvDur ease-in-out 0s;
transition: transform $enLvDur ease-in-out 0s;
}
&.ng-leave-active {
transform: -webkit-translateX(100%);
transform: -ms-translateX(100%);
transform: translateX(100%);
}
}
If you click between the pages you'll see the yellow box doesn't animate because it has a 1s delay on it while the parent has a .8s animation duration. (you can change this in the style.scss file)
So, how would I go about having a views children animate, no matter the delay or duration when a view is brought in and removed?

Categories