Rewinding CSS animation - javascript

Let say I have a div
<div id='animate'></div>
and has an animation of:
#keyframes move{
from{transform:translateX(500px);}
to{transform:translateX(0px);}
}
And i have a button that when clicked will programatically set the animationDirection to reverse. But what happen is that it restart the animation and execute the animation in reverse. What I really want is reverse the animation from its current state(before the animation ends) without restarting.
Is that possible?
http://jsfiddle.net/fdZKw/

keyframe animations require a from (0%) and a to (100%) parameters, so unless you set these parameters on the fly via javascript, I don't think you can make it happen. Although, the transition property does what you want - https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Using_CSS_transitions
I have applied it to your fiddle: http://jsfiddle.net/fdZKw/1/
#animate{
width:100px;
height:100px;
background:#0099CC;
transition:transform 5s;
-webkit-transition:-webkit-transform 5s;
}
#animate.go {
transform:translateX(500px);
-webkit-transform:translateX(500px);
}

Related

How do I run this piece for css code through javascript

Thanks for taking out the time to look into this and any help in this regard is appreciated.
I have the following piece of code.
.middle_n.expand.remove
{
animation: contractm 0.3s forwards;
transform-origin: 0 75px;
height:200%;
animation-delay: 1.3s;
}
#keyframes contractm
{
0%{}
100%{transform:translate(147.8%,100%) rotate(-16.75deg);}
}
I wish to pass a dynamic value to rotate in contractm through javascript. How do I do that. Can multi step animation run through javascript?
Thanks again.
In my opinion, if you want to control your animation rather than just let it animate, my recommendation is that you can use js to control the style of your element. Because animation is to complete a series of animation.
And there is a really powerful css called css variable, you can take more details on https://developer.mozilla.org/en-US/docs/Web/CSS/Using_CSS_custom_properties.
const rotate=document.getElementById("rotate")
let r=0
rotate.addEventListener("click",()=>{
r += 10
rotate.style.setProperty("--rotate", r+"deg");
})
#rotate{
--rotate:0deg;
background:pink;
width:100px;
height:100px;
transform:rotate(var(--rotate));
transition:transform 1s;
}
<p>click the square and then it will rotate.</p>
<div id="rotate"></div>
Of course, if you want a series of animations, you can check it on https://developer.mozilla.org/en-US/docs/Web/CSS/animation. It's easy to set steps in animation.

How can I animate an element programmaticaly using JavaScript?

I am looking at this code http://codepen.io/optyler/pen/FgDyr and if you hover to the triangle element, you will see the animation. However instead of hovering it, I want to do it programmaticaly using JavaScript. This is what I have done so far:
document.querySelector('.triangle').classList.add('animateSpeak');
and added a new css class
.animateSpeak {
animation: vibrate .5s infinite ease-out;
}
The animation is working though as you can see here http://imgur.com/a/V9JyO the left part is only animating. Am I doing something wrong here?
Since you're using a CSS 3 animation, you would probably need some sort of active class.
Just change the :hover selectors (line 54) to, say, .active instead. i.e.:
.triangle.active,
.triangle.active:before,
.triangle.active:after {
animation: vibrate .5s infinite ease-out;
}
You can start the animation programmatically by adding the .active class or stop it be removing the class.
To answer your second question, it looks like the :before and :after elements need the animation too.
In your CSS add
.animateSpeak,
.animateSpeak:before,
.animateSpeak:after {
animation: vibrate .5s infinite ease-out;
}
Just a quick thought, you can avoid the intersection of the three becoming darker than their constituents by changing the color from rgba to rgb or a solid color,
$font_color: rgb(231,236,241);

Parallax scroll with easing

I have an element that move relative to scroll. I use jQuery for this:
$('#object').css('transform','translateY('+($(window).scrollTop()*.4)+'px)');
CSS
#object {
width:200px;
top:100%;
left:50%;
position:absolute;
}
This works well, but moves my element directly without any easing (delay).
By setting a transition using css I get some of the effect that I'm looking for, but doesn't look good if I scroll at the same time:
transition: 400ms ease;
Is it possible to do this smooth, but in a more elegant way?
I figured it out by myself. The problem was the css "ease". Ease means that it will start slow and end slow, which will result in at the time scrolling is active it will always be on the slow start. However if you use css "ease-out" it will always start fast and slow down in the end. So use this:
transition: 400ms ease-out;
Or cubic-bezier if you want to customize the easing-curve yourself:
transition: 400ms cubic-bezier(0.235, 0.615, 0.185, 0.995);
When doing a parallax effect you will set a new translateY() on every scroll event that triggers. The event triggers really often and normally there should be no need for a transition. If you still experience bad rendering it is probably because the browser does not render on every event. You can force the browser to do so by using requestAnimationFrame.
var translate = function() {
$('#object').css('transform','translateY('+($(window).scrollTop()*.4)+'px)');
}
$(window).on('scroll', function() {
window.requestAnimationFrame(translate);
});

How do you store content or metadata within a css keyframe?

Does anyone know why I can't see the effects of the content property in my keyframe animation?
I tried something like
#-webkit-keyframes mymove {
0.000% {-webkit-transform: matrix(1,0,0,1,294,-135);
color:blue;
content:"test";
}
/*... more keyframes that changed the -webkit-transform property...*/
}
When I was watching my animated HTML div during the animation, I could see the effects of the -webkit-transform and color properties, but not the content property. It's as if the content property wasn't even applied during the animation. jQuery didn't return a value either when I did $(<my animated html element>).css("content"); However, repeatedly testing $(<my animated html element>).css("-webkit-transform") returned different values as the div moved across the screen.
I don't necessarily want to use the content property to display anything. I want to be able to store some meta data in the CSS keyframe rule so that I can refer back to the corresponding percentage at which the animation is at. I need to be able to run an animation on an infinite loop, and periodically query the animated HTML element to figure out how far along it is in the animation. I thought that I could use the content property to just put arbitrary strings, but it's not working on Chrome or Firefox. Does anyone have any ideas how I'd store metadata within the keyframe CSS rule?
I dont fully understand what you are trying to say when you are storing the metadata in keyframe.. In anyway, jquery or the javascript cannot read the css3 'content' data. Also I am pretty sure you cannot use content property inside the keyframe. you either need to use :after or :before. eg.
#box:before {
content: "test";
}
If you want the animation run infinte, you can use
-webkit-animation: mymove 5s infinite;
Let me know if this works.
Check this url http://msdn.microsoft.com/en-us/library/ie/jj680076(v=vs.85).aspx.
This article works good on Internet Explore 9+
For another browsers other than IE 9+, you need to copy and paste the css3 animation keyframe with vendor specific keywork.
for eg. for chrome you have to write the css in the article as:
#keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
.TransformDemoDivFadeOut:hover {
animation-duration: 2s;
animation-name: fadeOut;
#-webkit-animation-duration: 2s;
#-webkit-animation-name: fadeOut;
}
#-webkit-keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}

How to optimize the jquery animate code

Hi I am doing a zoom in & out using jquery animate. The problem is it is too slow and takes too much of time. The animate function is going to zoom approximately 100's of divs. Can some one please tell me what should be done to make it optimized. Here is the code below
//Zoom In by clicking the plus button
$("div#explanation .plus").click(function(){
jsPlumb.repaintEverything();
/* var strongFont = parseFloat($("div.window strong").css('font-size'));
var newStrongFont = strongFont + 2;
//alert("the new font is"+strongFont);
*/
$("div#demo1").animate({'height':'+=20', 'width':'+=20'});
$("div.window ").animate({
'height':'+=20px', 'width':'+=20px'
},0,function(){
jsPlumb.repaintEverything();
});
/* $("div.window strong").animate({
fontSize:newStrongFont
},0,function(){
jsPlumb.repaintEverything();
});
*/
});
I am having similar to zoom out. Please guide me. Thanks!
First off, you have to realize that you're almost certainly not going to get good performance aniating hundreds of elements. It's just too much for the browser to handle. I would try to animate a single container element to achieve whatever effect you're going after.
That said, you might want to take a look at the animate-enhanced plugin. In browsers that support CSS animation, the plugin automatically translates .animate(...) calls into CSS animations, which are usually hardware-accelerated. This gives much better performance than animate's usual method of changing an element's properties on a set interval.
You might also try using CSS animation directly if the plugin doesn't help. I'm not sure whether you're really trying to animate the size of the box or if you're trying to animate an actual zoom (where the box and all of its contents get bigger), but here's an example that animates the latter:
div {
width:200px;
height:200px;
background:red;
color:white;
margin:20px 50px;
padding:5px;
-webkit-transform-origin: 50% 50%;
-moz-transform-origin: 50% 50%;
}
div:hover {
-webkit-transform: scale(1.4);
-moz-transform: scale(1.4);
-webkit-animation-name: popin;
-moz-animation-name: popin;
-webkit-animation-duration: 350ms;
-moz-animation-duration: 350ms;
}
#-webkit-keyframes popin {
from {
-webkit-transform: scale(1);
}
to {
-webkit-transform: scale(1.4);
}
}
#-moz-keyframes popin {
from {
-moz-transform: scale(1);
}
to {
-moz-transform: scale(1.4);
}
}
The time for the animation to complete is something you can specify as the second argument to .animate(). You have not specified it so the default is 400ms. You can set it to whatever you want. The animation will always complete in approx the time that you set, but if there is too much work for the computer to do in that time to show you a smooth animation, you will get a jumpy one.
The only way to make an animation less jumpy is to optimize what you are animating or how you are animating it. Animating 100s of divs at the same time is probably more than anything but a very, very fast computer can do smoothly.
You will probably want to rethink what you are animating. One possible work-around in cases like this to animate an outline rather than the entire contents when the contents are really complex to animate with good performance.
If you want further help, you will have to show us more of the problem. We need to see the HTML you have so we can see what you're really trying to animate and we probably need to see the repaintEverything() function to see what it's doing.
If you're not too concerned about older browsers, you might be able to use css transform properties for this. They usually work quite quickly, allowing you to efficiently zoom in on a complicated section of the document. Here's a contrived example, which uses jQuery to zoom in on something whenever it's clicked. Animating would get more complicated: I don't believe jQuery's animate works with transform, but in theory you could repeatedly adjust the scale on a small level using timeouts.

Categories

Resources