KineticJS animation with JQuery - javascript

I am new in KineticJS and I am stacked. I want to use a simple animation with opacity but I found out that there is not so "simple" as it seems. I read the doc about animations with KineticJS (you won't say simple about this tutorial). What I want to know Is there a simple method to animate things with KineticJS like JQuery or JCanvaScript has? for example
this.animate({
opacity:0,
x: 50
}, 500);
something like this?
If there is not can we use KineticJS with JQuery to make animations simple? I found out THIS project that has very interesting piece of code:
$(logo.getCanvas()).animate({
opacity: 1,
top: "+=50px"
}, 1000);
so guys what do you think? Is it buggy to use this method?

If you just have to do your opacity animation : you should stick to JQuery which will hide the computations done for the animation (and what you were pointed to is a good solution).
If you want more controls over your animation : go with KineticJS.
Through, I think you will have more issues trying to use JQuery animations and KineticJS layers at the same time rather than using only KineticJS (and Kinetic.Animation is pretty simple once you have understand how to play with it)
edit: Quick How-To for animations :
So, as you may have seen, in Kinetic, you do not give the final position like in JQuery : you have an access to a function which is called at each frame of the animation and all the logic have to be placed in it :
<script>
// you should have an object yourShape containing your KineticJS object.
var duration = 1000 ; // we set it to last 1s
var anim = new Kinetic.Animation({
func: function(frame) {
if (frame.time >= duration) {
anim.stop() ;
} else {
yourShape.setOpacity(frame.time / duration) ;
}
},
node: layer
});
anim.start();
</script>

Related

Interval doesn't clear immediately after repeating for a while

I have a bouncing arrow on my website that I created with Jquery and setInterval, like this:
bouncing = setInterval(function() {
$("div").animate({
top:"30px"
},100,"easeInCubic",function() {
$("div").animate({
top:"0px"
},100,"easeOutCubic");
});
console.log("bounced");
},200);
You can see this in place in a codepen here: http://codepen.io/mcheah/pen/wMmowr
I made it run faster than i needed because its easier to see the issues quicker. My issue is that after leaving the interval running for a few seconds, you'll notice that instead of bouncing back up or down immediately, the bouncing element will stop for half a second and then just hang there, before beginning again. If you leave it running even longer (20 seconds) and then clear the interval, you'll notice that it takes a few seconds to stop bouncing.
My questions are these:
Why does the bouncing go out of sync occasionally?
Why does the clear interval take a while to clear if it's been repeating for a while?
Is there a better way to have a bouncing arrow? Are CSS transitions more reliable?
Thanks for your help!
Your are trying to perfectly coordinate a setInterval() timer and two jQuery animations such that the two come out perfectly coordinated. This is asking for trouble and the two may drift apart over time so it is considered a poor design pattern.
If, instead, you just use the completion of the second animation to restart the first and make your repeat like that, then you have perfect coordination every time.
You can see that here in another version of your codepen: http://codepen.io/anon/pen/NxYeyd
function run() {
var self = $("div");
if (self.data("stop")) return;
self.animate({top:"30px"},100, "easeInCubic")
.animate({top:"0px"}, 100, "easeOutCubic", run);
}
run();
$("div").click(function() {
// toggle animation
var self = $(this);
// invert setting to start/stop
self.data("stop", !self.data("stop"));
run();
console.log("toggled bouncing");
});
It's not a good idea to mix animate() with timers this way. There's NO chance you can synchronize something like this. And there's no need to. You can simply append a function into the animation queue, look here: https://stackoverflow.com/a/11764283/3227403
What animate() does is put an animation request into a job queue which will be processed later, when the right time comes. When you break the interval the stuff that accumulated in the queue will still be processed. There's a method to clear the queue and stop all animation immediately.
The JQuery animation functions actually manipulate CSS, and there is nothing beyond it in HTML. Another option would be using a canvas, but it is a completely different approach and I wouldn't recommend it. With JQuery's animation your already at the best choice.
This is a simple solution to your problem:
function bounce()
{
$("div")
.animate({
top: "30px"
}, 100, "easeInCubic")
.animate({
top: "0px"
}, 100, "easeOutCubic", bounce); // this loops the animation
}
Start bouncing on page load with:
$(bounce);
Stop bouncing on click with:
$("div").click(function() {
$("div").stop().clearQueue().css({ top: "0px" });
// you want to reset the style because it can stop midway
});
EDIT: there were some inaccuracies I corrected now. The running example is on codepen now.
If you want to use javascript for animation you can use something better like the greensock tween library
http://greensock.com/docs/#/HTML5/GSAP/TweenMax/to/
something like this:
var tween = TweenMax.to($("div"), 100, {y: "100px", yoyo: true, repeat: -1});
You could wrap your interval code with:
if(!$("div").is(":animated"))
This will initiate your animation only if your previous one is finished.
The reason why it was bouncing weird is that your animations are queued.
You can check how it works now:
http://codepen.io/luminaxster/pen/XKzLBg
I would recommend using the complete callback when the second animation ends instead and have variable to control a bounce recursive call in this version:
http://codepen.io/luminaxster/pen/qNVzLY

Infinite rotation with snap.svg

Is there a way for a svg element to be rotating infinitely?
Snap offers a way to rotate by a certain amount, but how can I make to rotate infinitely?
There's a few different ways to do this, As Alvin and Monkeyinsight say, you can do it with CSS, and also as mentioned do it with SVG markup. I'm guessing you don't want SVG markup as thats probably why you are using Snap in the first place (although you could always element.parse( as an inbetween stage maybe)
Just as an alternative, as sometimes you need to combine more complex bits, I'll show how to do an infinite animation in Snap with a callback...
var s = Snap("#svg");
var block = s.rect(100, 100, 100, 100);
function infRotate( el ) {
el.transform('r0,150,150'); // some kind of transform reset, or removing the previous completed transform maybe needed.
el.animate({ transform: 'r360,150,150' }, 2000, mina.linear, infRotate.bind( null, el));
};
infRotate( block );
This has a simple callback on the completion of an animation, so this could be used for more complex functions.
jsfiddle
I suspect the CSS/SVG markup solutions would be more efficient, but possibly less flexible with other Snap stuff.
Edit: You may want to keep an eye on memory if this would be in a situation where it really would be running for a long time.

How to change jquery animate() duration while animating using step

So here is the scenario. I'm trying to make a infinite image carousel, and everytime it will show an image that has a class of special .special I want to slow down the animation duration or the scrolling of the animation. So users can see the special image longer. Here is my code.
$photoGalleryList.animate({
left : '-' + (computedWidth) + 'px'
},
{
duration : 10000,
easing : 'linear',
step : function(now, fx) {
if(visibleSpecialImage()) {
// SLOW ANIMATION DURATION
// Tried setting fx.options.duration still no effect
}
}
});
I'm not sure if my approach is right (doing it with step), jquery animate() documentation says
step
Type: Function( Number now, Tween tween )
A function to be called for each animated property of each animated element. This function provides an opportunity to modify the Tween object to change the value of the property before it is set.
I'm not sure if I understood the documentation clearly, But base on what I read it's possible using step, I tried googling my problem and never found any concrete answer So now I'm stackoverflowing and hopefully solve this problem. Thanks

Is it okay to use .animate with 0 duration all the time? Is there a better alternative?

I've grown used to code my jquery animation by doing the following.
Set the initial state of the element (things like width, height, top, left, opacity, etc...) using either css or javascript. This initial state is the state at the end of the animation.
Use .animate with 0 duration to move the element to the state in which elements are at the beginning of the animation.
Use a regular .animate with the appropriate duration to do the animation in which at the end, the elements are back to state in step 1.
Here is an example.
/* css file */
.animatedObject
{
width:60%;
}
// javascript file
$('.animatedObject')
.animate({width: '-=20%'}, 0)
.animate({width: '+=20%'}, 1000);
There are several advantage using this code at least for me. First, it looks clear to me what I'm trying to animate. Second, if javascript is disabled, the object would be at the end state of the animation which is often where I want it to be for graceful degradation. Third, objects can change position slightly for adjustments using css and the animation would still look largely the same.
The reason I'm not using the .css is that it if I try to replace the animate with 0 duration with the .css method, I would get differing animation starting point. I don't think it support += or -=, or if it does, it behaves differently.
So, is this a good way to do this? What is the industry standard way?
Well you could still use .css():
var anObj = $('.animatedObject');
anObj.css("width", anObj.css("width") - (20 / anObj.css("width"))).animate({
width: '+=20%'
}, 1000);
I believe this would work faster.
Edit:
I did a little benchmark for you, using jsperf.com. Here are my results (using Google Chrome):
.animate({}, 0)
Code:
$('.animatedObject')
.animate({width: '-=20%'}, 0)
.animate({width: '+=20%'}, 1000);
End Results:
10,013 operations per second
±7.48%
fastest
.css();
Code:
var anObj = $('.animatedObject');
anObj.css("width", anObj.css("width") - (20 / anObj.css("width"))).animate({
width: '+=20%'
}, 1000);
End Results:
2,477 operations per second
±6.39%
75% slower
Conclusion
Keep the animation function. It turns out using .css() is actually slower. I guess it's the fact that you have 2 extra functions. It's not worth it. This was actually a surprise to me as I thought .css() would function faster than it did. Test this yourself in your browser!

animate christmas ornaments with Jquery ui effects

hi i am playing with jquery ui effects and trying to animate some christmas ornaments. the idea is that they would swing if you hover over them. and swing from the midpoint of the top of the image (the top of the string) like a real ornament and not just the whole image moving back and forth.
what i have so far is here:
http://jsfiddle.net/9ceeW/
its displaying on click, when i do it on hover they dont work as well or realistically.
this is my first foray into jquery animation and i am not really sure how to proceed next. any help would really be appreciated.
thanks!
You can use the plugin from
http://www.zachstronaut.com/posts/2009/02/17/animate-css-transforms-firefox-webkit.html
add a custom animation queue as in A non-nested animation sequence in jQuery?
and you end up with animated christmas balls at http://jsfiddle.net/gaby/9ceeW/8/
update
updated to allow multiple balls to animate at the same time.. http://jsfiddle.net/gaby/9ceeW/9/
Check out the jQuery Path plugin for animating elements along curves. See the author's demo page.
Not really my thing, but you need to add something like this:
$('#ball1').click(function () {
$(this).effect("bounce", { direction:'left', times:1, distance:60 }, 500);
$(this).effect("bounce", { direction:'left', times:1, distance:30 }, 750);
$(this).effect("bounce", { direction:'left', times:1, distance:15 }, 1000);
$(this).effect("bounce", { direction:'left', times:1, distance:5 }, 1250);
});
Updated fiddle: http://jsfiddle.net/N7qM9/

Categories