I want to be able to define tweened animations using Paper.js. So far I have determined that Tween.js would probably be the best library to use for this. However I don't see any examples on the web, all of them seem to be for Three.js.
Does anyone have other suggestions for how I might achieve tweened animations? I am trying to animate some paths on mouseMove() mouseDown() and mouseUp() events.
Here are a few examples of how to use Tween.js with Paper.js:
A very simple example of moving a star without interaction.
A tutorial article on creating a nice jelly effect which heavily uses mouses and scrolling velocity.
A complex multipart animation on CodePen that uses mouseOver as a trigger.
Here's the relevant code snippet on the paperjs + tweenjs integration from the first example.
path.position = {
x : 100,
y : 100
}
createjs.Tween.get( path.position, { loop: true } )
.to( { x: 300 }, 1000, createjs.Ease.quadOut )
.wait( 2000 )
.to( { x: 100, y: 300 }, 1000, createjs.Ease.quadOut )
.wait( 2000 )
.to( { x: 100, y: 100 }, 1000, createjs.Ease.quadOut )
.wait( 2000 )
.call( function() {
console.log( 'done!' );
} );
var update = function() {
paper.view.draw();
}
createjs.Ticker.setFPS( 60 );
createjs.Ticker.addEventListener( 'tick', update );
Related
When I click a button, I want OrbitControls(camera) be in front of the object(face side) smoothly by using tween.js.
I use this code but find that after changing controls.target and panning far from the target object, I only can zoom in a little level, and after I zoom in, I can't pan.
Is there another way to look at a object? Thanks!
var from = {
x: controls.target.x,
y: controls.target.y,
z: controls.target.z
};
var to = {
x: object.getWorldPosition().x,
y: object.getWorldPosition().y,
z: object.getWorldPosition().z
};
var tween = new TWEEN.Tween(from)
.to(to, 1000)
.easing(TWEEN.Easing.Quadratic.InOut) // | TWEEN.Easing.Linear.None
.onUpdate(function () {
controls.target.set( this.x, this.y, this.z )
})
.onComplete(function () {
controls.target.set( this.x, this.y, this.z )
})
.start();
Try the following: When the animation starts, disable the controls via controls.enabled = false; to prevent any interference with your animation. Next, implement the onComplete() callback of one of your tweens like so:
.onComplete(function() {
controls.enabled = true;
camera.getWorldDirection( lookDirection );
controls.target.copy( camera.position ).add( lookDirection.multiplyScalar( 10 ) );
})
The idea is enabling the controls again, computing the current look direction of your view and then setting a new target for the controls. You can also set a predefined target if you need an exact target spot for each camera position. The value 10 is in world units and determines how far away the target should be along the look direction.
Updated fiddle: https://jsfiddle.net/ckgo7qu8/
I'm using jQueryRotate to rotate my image.
Basically I want the image to start at 0 then rotate to -20 degrees then to 15 degrees then keep going back and forth between these 2 values and continue this infinitely.
So basically a little image shake, would this be possible with jQueryRotate or would you recommend another jquery plugin? Would need something with IE9 support.
Sorry forgot to post the code, but I was able to come up with a solution.
function() {
var rotation = function() {
$("#img1").rotate({
duration: 1000,
angle: 0,
animateTo: -15,
callback: function() {
$(this).rotate({
duration: 1000,
angle: -15,
animateTo: 0,
callback: function() {}
});
}
});
}
rotation();
I'm using PhysicsJS to make a 2D roulette ball spinning animation.
So far, I've implemented the following:
used a constraint so that the ball wouldn't "fly away":
rigidConstraints.distanceConstraint( wheel, ball, 1 );
used drag to slow down the ball:
world.add(Physics.integrator('verlet', { drag: 0.9 }));
made the wheel attract the ball, so that it would fall towards it when the drag has slowed down the ball enough
My questions:
how do I gradually slow down the ball spinning?
I have already a very high drag value, but it doesn't look like it's doing anything
how do I make attraction towards the wheel work?
The distance constraint should keep the ball from escaping, not from getting closer to the wheel.
why does angularVelocity: -0.005 not work at all on the wheel?
My code, also on JSfiddle
Physics(function (world) {
var viewWidth = window.innerWidth
,viewHeight = window.innerHeight
,renderer
;
world.add(Physics.integrator('verlet', {
drag: 0.9
}));
var rigidConstraints = Physics.behavior('verlet-constraints', {
iterations: 10
});
// create a renderer
renderer = Physics.renderer('canvas', {
el: 'viewport'
,width: viewWidth
,height: viewHeight
});
// add the renderer
world.add(renderer);
// render on each step
world.on('step', function () {
world.render();
});
// create some bodies
var ball = Physics.body('circle', {
x: viewWidth / 2
,y: viewHeight / 2 - 300
,vx: -0.05
,mass: 0.1
,radius: 10
,cof: 0.99
,styles: {
fillStyle: '#cb4b16'
,angleIndicator: '#72240d'
}
})
var wheel = Physics.body('circle', {
x: viewWidth / 2
,y: viewHeight / 2
,angularVelocity: -0.005
,radius: 100
,mass: 100
,restitution: 0.35
// ,cof: 0.99
,styles: {
fillStyle: '#6c71c4'
,angleIndicator: '#3b3e6b'
}
,treatment: "static"
});
world.add(ball);
world.add(wheel);
rigidConstraints.distanceConstraint( wheel, ball, 1 );
world.add( rigidConstraints );
// add things to the world
world.add([
Physics.behavior('interactive', { el: renderer.el })
,Physics.behavior('newtonian', { strength: 5 })
,Physics.behavior('body-impulse-response')
,Physics.behavior('body-collision-detection')
,Physics.behavior('sweep-prune')
]);
// subscribe to ticker to advance the simulation
Physics.util.ticker.on(function( time ) {
world.step( time );
});
// start the ticker
Physics.util.ticker.start();
});
Drag has a bug in that version of PhysicsJS, try using the most updated version from github. https://github.com/wellcaffeinated/PhysicsJS/issues/94
Unfortunately the distance constraint imposes a fixed distance. So to prevent the ball's escape in that way, you'd need to implement your own behavior. (more below)
You'll have to change behavior: "static" to be behavior: "kinematic". Static bodies don't ever move on their own.
To create a custom behavior check out the documentation here: https://github.com/wellcaffeinated/PhysicsJS/wiki/Behaviors#creating-a-custom-behavior
In order to get the functionality you're describing, you'll need to do something like this:
// in the behave method
// calculate the displacement of the ball from the wheel... something like....
disp.clone( wheel.state.pos ).vsub( ball.state.pos );
// if it's greater than max distance, then move it back inside the max radius
if ( disp.norm() > maxDist ){
var moveBy = disp.norm() - maxDist;
disp.normalize(); // unit vector towards the wheel
disp.mult( moveBy );
ball.state.pos.vadd( disp ); // move it back inside the max radius
}
Of course, this is a "just get it done" way of doing this but it should work.
I'm using Snap.svg to create some SVGs that animate on hover.
A very simplified jsfiddle is here:
http://jsfiddle.net/62UA7/2/
var s = Snap("#svg");
var smallCircle = s.circle(100, 150, 70);
//animation
function animateSVG(){
smallCircle.animate({cy: 300}, 5000,mina.bounce);
smallCircle.animate({fill:"red"},200);
}
//reset function?
function resetSVG(){
// something here to reset SVG??
}
smallCircle.mouseover(animateSVG,resetSVG);
The hover / animation is working fine.
The intention is to stop the animation and return to original SVG state if the user moves the mouse off the SVG - and this is where I'm currently stuck.
The actual SVG files I'm using are complex, so hoping for a quick way of 'refreshing' the SVG rather than manually moving it back to original position and colour
I'm assuming there's a really easy way of doing this - just can't seem to work it out or find the answer in any documentation anywhere.
Hopefully someone can help - thanks in advance if you can!
If you are only willing to animate between 2 states I found that Codrops animated svg icons did great job with handling this type of snap.svg animations. I have started using their code as a basis for my future exploration of SNAP.SVG. But getting back to the code: the most fun part is that you configure your animation with simple JSON objects such as:
plus : {
url : 'plus',
animation : [
{
el : 'path:nth-child(1)',
animProperties : {
from : { val : '{"transform" : "r0 32 32", "opacity" : 1}' },
to : { val : '{"transform" : "r180 32 32", "opacity" : 0}' }
}
},
{
el : 'path:nth-child(2)',
animProperties : {
from : { val : '{"transform" : "r0 32 32"}' },
to : { val : '{"transform" : "r180 32 32"}' }
}
}
]
},
and you can easily attach any sort of event trigger for animation In/Out. Hope that helps.
Personally I'd probably do it something like the following, storing it in a data element. It depends what problems you are really trying to overcome though, how you are actually animating it (I suspect it could be easier than my solution with certain animations, but trying to think of something that covers most bases), and if you really need it reset, also how many attributes you are animating and if there is other stuff going on...
var smallCircle = s.circle(100, 150, 70);
var saveAttributes = ['fill', 'cy'];
Snap.plugin( function( Snap, Element, Paper, global ) {
Element.prototype.resetSVG = function() {
this.stop();
for( var a=0; a<saveAttributes.length; a++) {
if( this.data( saveAttributes[a] ) ) {
this.attr( saveAttributes[a], this.data( saveAttributes[a] ) );
};
};
};
Element.prototype.storeAttributes = function() {
for( var a=0; a<saveAttributes.length; a++) {
if( this.attr( saveAttributes[a]) ) {
this.data( saveAttributes[a], this.attr( saveAttributes[a] ) );
};
};
};
});
function animateSVG(){
smallCircle.animate({cy: 300}, 5000,mina.bounce);
smallCircle.animate({fill:"red"},200);
};
smallCircle.storeAttributes();
smallCircle.mouseover( animateSVG );
smallCircle.mouseout( smallCircle.resetSVG );
jsfiddle
I'm making a simple prototype in HTML5 canvas, and want to basically draw a slingshot. When someone clicks down and pulls back, I want the rubber band to stretch. It doesnt have to be perfect.
Any suggestions on how I can do this? I'm not too certain how to mimic the effect :)
thanks
It would be easier to do with SVG than with canvas, especially using a library like Raphaël. See this demo – that is not very different from what you want to do. If you use Raphaël then it will be much more portable than canvas, because it will work even on IE 6 (using VML).
Update:
(Fixed the Fiddle example - it had some outdated dependencies - now it's fixed)
Ok, see THIS DEMO. It should be pretty much what you explained or at least it should get you started. Here is the code:
var R = Raphael(10, 10, 400, 400);
var l = R.path("M100 200L200 200L300 200");
l.attr({
stroke: 'red',
'stroke-width': 4
});
var c = R.circle(200, 200, 10).attr({
fill: 'white',
stroke: 'red',
'stroke-width': 4
});
function move(dx, dy) {
var x = 200 + dx, y = 200 + dy;
this.attr({cx: x, cy: y});
l.attr({path: "M100 200L"+x+" "+y+"L300 200"});
}
function start() {
c.stop();
l.stop();
}
function end() {
this.animate({cx: 200, cy: 200}, 2000, "elastic");
l.animate({path: "M100 200L200 200L300 200"},
2000, "elastic");
}
c.drag(move, start, end);
a lot of these kind of behaviours have been implemented and written about in the Flash community. Krazy dad has some nice articles + code on elasticity.
http://www.krazydad.com/bestiary/bestiary_springyTitles.html