Changing animation-timing-function with Element.animate() in JavaScript - javascript

I am trying to animate a HTML div using JavaScripts built in Element.animate() function. Sadly, I haven't found a way to change the animation-timing-function that is getting parsed along with other timing-settings as the second argument of the Element.animate() function.
My JavaScript code so far:
// This variable declares all keyframes of the animation.
const animationKeyframes = [
{transform: 'translateY(-100%)'},
{transform: 'translateY(0%)'}
]
// This variable contains all animation options.
// There should be a way to specify a timing-function.
const animationOptions = {
duration: 1000,
iterations: 1
}
// Runns the animation for the div that I want to animate.
Element.animate(animationKeyframes, animationOptions)
The code above executes without any errors and moves the div from the top to the bottom of the page at a linear speed. However, I want the speed to ease-in at the beginning and to ease-out at the end of the animation.
I tried:
adding animationTimingFunction: 'ease-in-out' to the animationTiming constant
adding animation-timing-function: ease-in-out; to the CSS properties of the div
My only source so far: Mozilla Docs: Element.animate()

You can just add the 'easing' prop in your animationOptions:
const animationOptions = {
duration: 1000,
iterations: 1,
easing: 'ease-in-out'
}
Other values that can be used in the easing property are: 'ease', 'linear', 'ease-in', 'ease-out', and 'ease-in-out'.

Related

Css3 transition queue

I am trying to queue css transition with same properties. Basically I want to translate an element to certain position (so transition duration 0) before I make another translate.
This is a mockup, click on move (box should move 100px right, before translate 100px left)
this doesnt work because second transition overwrites first?
https://jsfiddle.net/aqwaypoh/3/
This works (I needed transition duration non zero (0.01) otherwise transitionend doesnt fire).
https://jsfiddle.net/dpv3xzth/5/
There is another problem that transition end fires 2 times on chrome, but I could fix that, I was just wondering is there a better way to write this?
I would prefer if I could write this without end event or timer if possible?
<div class="box"></div>
move</a>
Update:
You can use CSS3 animation property with #keyframes.
.box.animate {
animation: move 2s;
}
#keyframes move {
0% {
transform: translate(100px);
}
100% {
transform: translate(0px);
}
}
And to make the box move you can add class animate to your element. Or you can set animation property yourself in javascript, it's up to you.
box.addClass('animate')
jsfiddle: https://jsfiddle.net/aqwaypoh/7/
Adding a timeout on the second condition gives you what you want I believe.
var box = $('.box'),
move = $('.move').click(function() {
box.css({
"transform": "translate(100px)",
'transition-duration': '0s'
});
setTimeout(function(){
box.css({
"transform": "translate(0px)",
'transition-duration': '0.5s'
});
}, 1);
})

React Virtual Dom Diff resets Css Animation

I am building a game, with css animations.
I have this css rule for move animation:
.animate {
animation: play-move 1s steps(10) infinite;
}
I update my state every half second so state changes as:
State: [0, 1, 0]
View: <div/><div class="animate"/><div />
State: [0, 0, 1]
View: <div/><div/><div class="animate">
The problem is as the dom changes, the css animation resets, so I can't see the full animation.
see react version:
http://jsfiddle.net/CGmCe/12998/
However if you reverse the move direction, animation doesn't reset.
mithriljs version:
http://jsfiddle.net/CGmCe/12982/
jquery:
http://jsfiddle.net/CGmCe/12968/
instead of updating entire DOM you can just change class attr value as like fuddle link below.
http://jsfiddle.net/CGmCe/12974/
on render: you can render <div class="tile temp100"></div>.
on state change you can change the class as sequence as temp100,temp010,temp001

JavaScript: An efficient way to handle events (Firefox-specific)

I'm running a scroll event that triggers TweenMax animations, and I'm noticing that, while it looks good on Chrome, there is a considerable amount of lag on Firefox. Does anyone have a suggestion about how to handle this scroll event as efficiently as possible? Also, is there something about Firefox's rendering that I'm not aware of that might be causing this? Any leads would be appreciated!
The gist is that I'm looking for containers on my page called "customers", which each contain three individual "customer" elements. When a div that matches "customers" scrolls into view, trigger a TweenMax animation, and add a class called "animated", which prevents the element from re-animating subsequently.
Here is a fiddle with the basic demonstration:
http://jsfiddle.net/epp37jsq/
EDIT
To clarify, the fiddle only demonstrates the behavior of my animation function. The lag does not occur there because the file size is quite small. On the actual site, I have 11 groups of 3 "customers." The image is the same, but pulled in 33 times. In the future, the images will be unique. In essence, the animation is being called for each of these 11 groups. I'm looking for suggestions on how to improve the speed of my page.
And my code:
var scrollTimer = null;
$(window).scroll(function () {
if (scrollTimer) {
clearTimeout(scrollTimer); // clear any previous pending timer
}
scrollTimer = setTimeout(handleScroll, 500); // set new timer
console.log("fired!");
});
function handleScroll() {
scrollTimer = null;
$('.customers').each(function() {
if (!$(this).hasClass('animated')) {
if ($(this).isOnScreen(0.45, 0.45)) {
TweenMax.staggerFromTo($(this).find('.customer'), 0.3, {
y: 50,
opacity: 0
}, {
y: 0,
opacity: 1,
ease: Power2.easeOut
}, 0.15);
$(this).addClass('animated');
}
}
});
}
Usually with Firefox, translating on the x or y axis can cause some jank. Sometimes adding a slight rotation:0.001 to your tween can help make your tween more smooth in Firefox.
http://jsfiddle.net/pwkja058/
Also using the GSAP special property autoAlpha instead of opacity can help increase performance
TweenMax.staggerFromTo($(this).find('.customer'), 0.3, {
y: 200,
rotation:0.01, /* add a slight rotation */
autoAlpha: 0 /* use instead of opacity */
}, {
y: 0,
rotation:0.01, /* add a slight rotation */
autoAlpha: 1, /* use instead of opacity */
ease: Power2.easeOut
}, 0.15);
autoAlpha is part of the GSAP CSSPlugin:
http://greensock.com/docs/#/HTML5/GSAP/Plugins/CSSPlugin/
autoAlpha - Identical to opacity except that when the value hits 0 the visibility property will be set to "hidden" in order to improve browser rendering performance and prevent clicks/interactivity on the target. When the value is anything other than 0, visibility will be set to "inherit". It is not set to "visible" in order to honor inheritance (imagine the parent element is hidden - setting the child to visible explicitly would cause it to appear when that's probably not what was intended). And for convenience, if the element's visibility is initially set to "hidden" and opacity is 1, it will assume opacity should also start at 0. This makes it simple to start things out on your page as invisible (set your css visibility:hidden) and then fade them in whenever you want.

Robust way to event handle after the *last* CSS3 transition?

Say I have a CSS class that transitions in several settings, with different timings to boot:
.hidden {
opacity:0;
height:0px;
transition:opacity 1s ease;
transition:height 2s ease;
}
I want to handle some logic after ALL the transitions are done. I know there's a transitionend event for that:
$('#content').on('transitionend', function(e) {
mandatoryLogic()
})
$('#content').addClass('hidden');
But, how do I ensure this event handle happens once and only once, at the end of the last transition (after the 2s height transition in my case)?
I've seen a few examples that involve checking for the type of transitionend, but this closely couples the JS to a particular CSS definition. So far I'm unable to come up with a JS solution that would survive say:
opacity changed to 3s, now the longest.
new width transition to 0px over 4s introduced
extreme case, all transitions removed (so the effects are instant)
I'm not entirely sure what you're asking, but if you want to make sure it only happens once, then use a variable set to false initially, and once the transition takes place it gets set to true. For example:
var transition = false ;
if( !transition ){
// do what you need to do
transition = true ;
}
If you want to make sure it happens once all transitions are complete, then check for the values of #content or .hidden. Whichever you prefer.
var height = $(element).height() ;
var opacity = $(element).css('opacity') ;
var transition = false ;
if( !transition && opacity = 'wanted value' && height = 'wanted value' ){
// do what you need to do
transition = true ;
}
This way, with var transition being set to true it won't happen again.

Generate Random Webkit Animation with Javascript

I was wondering if it is possible to generate a webkit animation with javascript. Basically all I need is that if i click element A, element B should be animated with a random parameter every time(this is why I cant use a pre-fixed CSS). I'm testing if I can actually generate all this through javascript and Ive gotten pretty far. My code does not do anything random yet but it is really easy to make it random once I get it to work right with javasript. So right now I just want to animate element B every time I click element A. My code looks like this:
$("#elementA").live('touchstart mousedown',function() {
$("head style").remove();
var cssAnimation = document.createElement('style');
cssAnimation.type = 'text/css';
var rules = document.createTextNode('#-webkit-keyframes random_spin {'+
'from { -webkit-transform: rotate(0deg); }'+
'to { -webkit-transform: rotate(1440deg); }'+
'}');
cssAnimation.appendChild(rules);
document.getElementsByTagName("head")[0].appendChild(cssAnimation);
$("#elementB").removeClass("random_spin");
$("#elementB").css({'-webkit-animation-name': ''});
$("#elementB").css({'-webkit-animation-name': 'random_spin'});
$("#elementB").addClass("random_spin");
});
There I just added the animation to the header and I applied it to elementB.
My "random_spin" class is a CSS I already predefined :
.random_spin {
-webkit-animation-duration: 5s;
-webkit-animation-timing-function: ease;
}
My intention with this is that I should be able to make my elementB spin every time I click on elementA. Unfortunately it only does it once and no matter how much I click on it or how many times I reset the animation name it still only does it once. What am I doing wrong?
To restart a CSS3 animation you cannot just remove and add a class without putting a small delay between the commands. This allows the browsers time to actually remove the class before adding the new one. You can do this with a simple setTimeout
setTimeout(function(){
$("#elementB").addClass("random_spin");
}, 100);
More information and examples can be found below.
http://css-tricks.com/restart-css-animation/

Categories

Resources