I have an AngularJS animation set up for sliding in panels of an ng-switch directive using the latest version of Angular (1.2.9). I am noticing curious behavior if I try to animate the position using "transform: translate(0,0);" instead of just the "left" attribute. When using translate, the animation sometimes works properly and sometimes not (I'd say it's about 50/50). However, if I animate the left attribute, it works correctly 100% of the time.
The CSS for the animation I am using is
.slide-animation.ng-enter,
.slide-animation.ng-leave {
position: absolute;
-webkit-transition: all ease-in-out 1s;
-moz-transition: all ease-in-out 1s;
-o-transition: all ease-in-out 1s;
transition: all ease-in-out 1s;
}
.slide-animation.ng-enter {
-webkit-transform: translate(-125%, 0);
-ms-transform: translate(-125%, 0);
transform: translate(-125%, 0);
}
.slide-animation.ng-enter.ng-enter-active,
.slide-animation.ng-leave {
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
transform: translate(0, 0);
}
.slide-animation.ng-leave.ng-leave-active {
-webkit-transform: translate(125%, 0);
-ms-transform: translate(125%, 0);
transform: translate(125%, 0);
}
Here is a fiddle to demonstrate the issue I am having: http://jsfiddle.net/HXACU/5/
I wanted to use translate because it gives significantly better performance than animating the left attribute on mobile devices. Do I have something wrong, is this a bug in Angular, or should I give up and just animate with "left"?
I think it's a rendering time race - caused by the 125%. I don't think it knows what 125% is until it's rendered, I've seen similar things before.
For argument sakes I replaced all % with px equivalents here: http://jsfiddle.net/27te5/1/ and it appears to be more stable (i can't break it)
.slide-animation, .slide-animation-transform {
width: 96px;
}
.slide-animation.RL.ng-enter, .slide-animation.LR.ng-leave.ng-leave-active {
left:150px;
}
/*etc. etc.*/
I'm sure you would rather % values but i hope it helps in any case.
Related
An element has class slider-item:
.slider-item{
transform: translateY(100%);
transition: transform 100s ease;
transition-delay: 800ms;
}
When i click on a button ,i want the element to transition between translateY(-100%) and translateY(0).
I add classes prev-version and next by javascript respectively:
.slider-item.prev-version{
transform: translateY(-100%);
transition: none;
}
.slider-item.next{
transform: translateY(0);
transition: transform 100s ease;
transition-delay: 800ms;
}
But i see transition happens between translateY(100%) and translateY(0). next class overrides transform: translateY(-100%); in prev-version class. Please help me what should i do?
The best thing to try would probably be to use Vanilla JavaScript, jQuery, or some other type of framework to directly edit and change the CSS attributes.
So for example the jQuery version would be:
$("#slider-item.next").css("transform:translateY(0)");
Keep in mind you would need to add logic so that if the attribute was 100 it would change it back to 0 and then if it was 0 it would change it back to 100.
w3schools.com/jquery/jquery_css.asp
I might didn't understand your question but seems that you can use css animation for this:
document.querySelector('button').addEventListener('click', function () { document.querySelector('.slider-item').classList.add('example'); });
button {position: fixed; bottom: 10vh} /* just for demo */
.slider-item{
transform: translateY(100%);
transition: transform 100s ease;
transition-delay: 800ms;
}
.example {
animation: example 3s ease-in-out;
}
#keyframes example {
from {transform: translateY(-100%);}
to { transform: translateY(100%);} /* should be the same as the value declared initial on .slider-item */
}
<div class="slider-item">Slider Item</div>
<button>Click</button>
This JQuery animation looks very choppy, can I fix it? If not, how can I use CSS to do it? Maybe I use JQuery to edit the CSS?
<h1>Test</h1>
<button onclick="anim()">Start Animation</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js" charset="utf-8"></script>
function anim() {
$("h1").animate({fontSize: '50px'});
}
h1 {
font-size: 30px;
}
This is the example code
Here's the project (you can also go to j0rdan.me)
With CSS3 you can use transitions to animate the font-size:
h1 {
font-size: 30px;
transition: font 1s ease;
}
h1.bigger {
font-size:50px;
}
fiddle: https://jsfiddle.net/z6ztfgcg/3/
But to me it's not looking choppy with javascript from your example.
if you want to use only CSS then try this
h1 {
-webkit-transition: all 1.5s ease;
-moz-transition: all 1.5s ease;
-ms-transition: all 1.5s ease;
transition: all 1.5s ease;
}
h1:hover {
-webkit-transform: scale(1.5); /* Safari and Chrome */
-moz-transform: scale(1.5); /* Firefox */
-ms-transform: scale(1.5); /* IE 9 */
-o-transform: scale(1.5); /* Opera */
transform: scale(1.5);
}
There are a few reasons why the animation is "choppy"
Animating structural properties such as font-size are generally choppy
Because the structure is changing, elements around the animated element will also be affected
jQuery animations aren't as smooth as css animations
I recommend animating with css not jQuery by using transform: scale(1.5) as this will not affect surrounding elements and gives a smoother animation.
h1 {
font-size: 30px;
transition: all 0.4s ease;
}
h1.larger {
transform: scale(1.5);
}
If this is not possible and you want to animate the font-size I recommend setting the line-height to the size of the end animation size and having a fixed margin. This will hopefully prevent the surrounding elements from being affected.
h1 {
font-size: 30px;
transition: all 0.4s ease;
line-height: 50px; // Matches end animation size
margin: 20px 0;
}
h1.larger {
font-size: 50px;
}
Working examples of both solutions:
https://jsfiddle.net/z6ztfgcg/4/
Animating font-size will always be choppy because the transformation will skip keyframes. Best way would be to use CSS3 transition but with scale. This will ensure a smooth animation as you pretend.
<button onclick="anim()">Start Animation</button>
<h1 class="title">Test</h1>
<style>
.title {
position: absolute;
transform: scale(1);
transform-origin: 0 0;
-moz-transform-origin: 0 0;
transition: all 5s;
font-size: 30px;
}
.title.animate {
transform: scale(2);
}
</style>
<script>
function anim() {
$('h1').addClass('animate');
}
</script>
You can then decide how many seconds you want the transition to be and change the scaling factor. (in this case I put 5 seconds and 2 times the original size)
You can use css to add simple animations to your html:
.animClass {
transition: 1000;
font-size: 50px;
}
(Transition specifies the duration of animation in milliseconds)
Then just add the animClass when you need the animation to occur:
function anim(){
document.getElementsByTagName("h1").classList.add("animClass");
}
Or in jQuery:
function anim(){
$("h1").addClass("animClass");
}
I'm currently using my phone, so I wasn't able to check whether it works properly. Please inform me if further problems occur.
It does not seem that choppy on my end as well. You can try adding transform: translateZ(0); to the h1 CSS class: https://jsfiddle.net/z6ztfgcg/3/
This trick triggers GPU acceleration in modern desktop and mobile browsers, which should really smooth things out. There are plenty of other methods which accomplish similar tasks found here.
Right now I am using Rico St.Cruz brillant working query.transit library but now I have to change some things to do with classes instead though not being this firm in CSS transitions. I tried to
replace:
JS:
$("#target_element").mouseenter( function() {
$("#arr_left")
.transition( { x: 3 }, 300, 'easeOutSine' )
.transition( { x: 0 }, 300, 'easeInSine' );
};
}
with:
JS:
$("#target_element").mouseenter( function() {
$("#arr_left").addClass('hint');
}
CSS:
#arr_left.hint {
-webkit-animation: hint_left 600ms;
-moz-animation: hint_left 600ms;
-o-animation: hint_left 600ms;
animation: hint_left 600ms;
}
#keyframes hint_left {
0%, 100% {
-webkit-transform: translate(0);
-moz-transform: translate(0);
-o-transform: translate(0);
transform: translate(0);
-webkit-animation-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1); /* easeOutSine */
animation-timing-function: cubic-bezier(0.39, 0.575, 0.565, 1);
}
50% {
-webkit-transform: translate(3px);
-moz-transform: translate(3px);
-o-transform: translate(3px);
transform: translate(3px);
-webkit-animation-timing-function: cubic-bezier(0.47, 0, 0.745, 0.715); /* easeInSine */
animation-timing-function: cubic-bezier(0.47, 0, 0.745, 0.715) ;
}
}
but this new code does not work.
1) What I am doing wrong here?
2) What is the shortest code (browser compatible) to reach this?
Addition: I’d like to keep the "hint" class generic to address via JS with each arrow has a specific own translation property. Thanks so much in advance!
EDIT:
http://jsfiddle.net/bg7w6jmh/61/
I added a fiddle. Note: I need the extra container for the arrow because it’s animated (rotated) in other places.
The aim is to make the little arrow smoothly move to the left 3px and back in to indicate the target_element being animated on click or swipe. For the values and easing see the keyframes. Thanks for help!
Happens to be ok now. While I was working endlessly on my fiddle I recognized that I missed a round bracket at the end of my event declaration…
I'm having a bit of an issue using some css animations in firefox. I am using them to slide in some radio buttons when the user clicks a button. In chrome everything seems to be fine but in firefox they kind of look like they are firing the animation twice (the second one slightly over the first one). I've tried a few things and can't seem to solve this problem. Here's what I'm doing :
$(document).on("click", ".addLesson", function(){
$(".contentList").addClass("fadeOutRight");
$(".contentList").hide();
$(".lessonOptions").addClass("fadeInLeft");
});
$(document).on("click", ".lessonCancel", function(){
$(".contentList").removeClass("fadeOutRight");
$(".contentList").addClass("fadeInLeft");
$(".contentList").show();
$(".lessonOptions").removeClass("fadeInLeft");
$(".lessonOptions input[type='radio']").removeAttr("checked");
});
And I'm just using animate.css styles for the animations themselves -
.fadeInLeft
-webkit-animation: fadeInLeft 1s forwards
animation: fadeInLeft 1s forwards
#-webkit-keyframes fadeInLeft
0%
opacity: 0
-webkit-transform: translate3d(-100%, 0, 0)
transform: translate3d(-100%, 0, 0)
100%
opacity: 1
-webkit-transform: none
transform: none
#keyframes fadeInLeft
0%
opacity: 0
-webkit-transform: translate3d(-100%, 0, 0)
transform: translate3d(-100%, 0, 0)
100%
opacity: 1
-webkit-transform: none
transform: none
.fadeOutRight
-webkit-animation: fadeOutRight 1s
animation: fadeOutRight 1s
#-webkit-keyframes fadeOutRight
0%
opacity: 1
100%
opacity: 0
-webkit-transform: translate3d(2000px, 0, 0)
transform: translate3d(2000px, 0, 0)
#keyframes fadeOutRight
0%
opacity: 1
100%
opacity: 0
-webkit-transform: translate3d(2000px, 0, 0)
transform: translate3d(2000px, 0, 0)
I think maybe I'm making the javascript and css fight against each other, but I'm not to sure because it works fine in chrome.
I also noticed when I mouse over the lessOptions div I'm sliding in (after it's entered the stage) it flickers or blinks.
I would appreciate any help on this, thanks for reading!!
Pen here - http://codepen.io/anon/pen/IkhGp
So for me, this problem occurred because I had an animation that lasted .5s, and a transition: all 1s; as well on my animated elements, and this was causing the animation to fire twice. Removing the transition and leaving the animation alone fixed the issue for me.
A while since this was posted but I came looking after having the same issue. For me seems to be an issue for me only when developer tools are open. Close the tools and refresh and the animation was playing correctly.
How would I add a custom animation delay for every div with the class "bounce"? Basically the class bounce contains the animation css keyframes (animate.css). Now, I have 20 divs called "360player bounce". but they all bounce at the same time.
example:
<div class="360player bounce">
<a href="audio/The_Song.mp3">
The Song
</a>
</div>
Just wondering how I could do this. I searched entire stackoverflow and google but no luck so far.
I have created a similar animation for falling stars. I believe you are going to have to create distinct animation sets each with different delays. It Depends on what you are trying to achieve in my instance I created 5, 6 different animation chains and delayed them each slightly so it appears they are all moving at different times.
Example below
#keyframes fallingstars {
0% {
opacity: 1;
transform: translate(0, 0px) rotateZ(0deg);
}
25% {
opacity: 1;
transform: translate(0px, 0px) rotateZ(deg);
}
100% {
opacity: 0;
transform: translate(-870px, 500px) rotateZ(310deg);
}
}
#keyframes fallingstars2 {
0% {
opacity: 1;
transform: translate(0, 0px) rotateZ(25deg);
}
25% {
opacity: 1;
transform: translate(0px, 0px) rotateZ(deg);
}
100% {
opacity: 0;
transform: translate(-570px, 600px) rotateZ(210deg);
}
}
#fallstar {
animation: fallingstars 12s infinite;
animation-delay:5s;
z-index:-1;
}
#fallstar2 {
animation: fallingstars2 12s infinite;
z-index:-1;
}
<img src="stars-ALL.svg" id="fallstar" alt="Stars" style="width:50px; height:50px; top:0px; right:-50px; position:absolute;" />
You could also modify the animation using jquery / js to change the delay. This is just one of several ways to accomplish this. Loop through all your divs, and for each div modify the animation delay. I feel this might be expensive.
I don't know if the CSS library you're using includes it, so here's the specific CSS property you're looking for:
http://www.w3schools.com/cssref/css3_pr_animation-delay.asp
You can apply this attribute on top of an existing CSS animation, perhaps by defining your own seperate class in your page's own CSS file and adding that.
CSS:
.wait300ms {
animation-delay: 300ms;
/*TODO: Add cross-browser attributes */
}
HTML:
<div class="360player bounce wait300ms">