An animation library for paper.js.
An animation library for paper.js.
See a live demo on jsbin.
TypeScript declarations are available as of 1.2.1, in dist/src/animatePaper.d.ts
.
paper
is now a peerDependency, this should remove unnecessary code from your dependency tree.segmentGrow
property and grow
effect have been removed (this feature was very buggy).rotate
or scale
properties, you can provide a new setting : center
(or rotateCenter
/scaleCenter
) (default is item.position
).Animation
supports a new option repeat
(defaults to 0
).settings.complete
callback takes the Animation
object as 1st argument.paper.Group
animation (1.1.*)function
(p: number) => number
to settings.easing
(1.2.*)npm install --save paper-animate
then
import * as animatePaper from "paper-animate";
or var animatePaper = require("paper-animate")
bower install paper-animate --save
(not recommended)
Get the minified file in dist/paper-animate-browser.min.js
, and include it in your page, after paper.js.
This is a work in progress, and any help or feedback is more than welcome.
So far, only opacity
, position
, scale
, rotate
, translate
, fillColor
and strokeColor
are supported, but I add more whenever I have the time.
(you can animate a Group
too)
You can either use a predefined animation :
var myCircle = new paper.Path.Circle(new paper.Point(50,50),35);
animatePaper.fx.shake(myCircle);
Predefined animations available by default : shake
, fadeIn
, fadeOut
, slideUp
, slideDown
, splash
. You can try them on this demo.
Or animate properties :
var myCircle = new paper.Path.Circle(new paper.Point(50,50),35);
animatePaper.animate(myCircle, {
properties: {
translate: new paper.Point(100,50),
scale: 3
},
settings: {
duration: 4000,
delay: 1000,
easing: "easeInElastic",
complete: function(item, animation) {
console.log('complete !');
}
}
});
When animating position
or color properties, you can provide either relative or absolute values :
var square = new paper.Path.Rectangle(new paper.Point(75, 75), new paper.Size(50,50));
square.strokeColor = 'green';
square.animate({
properties: {
position: {
x: "+200", // relative to the current position of the item. At the end, `x` will be : 275
y: 150 // absolute position. At the end, `y` will be : 150
},
strokeColor: {
hue: "+100",
brightness: "-0.4"
}
},
settings: {
duration:1500,
easing:"easeInBounce"
}
});
Note : Relative values must be strings.
If you want your Animation
to run more than once, you can use the settings.repeat
option (defaults to 0
).
If settings.repeat
is a number > 0, your animation will run settings.repeat
additional times.
If you set settings.repeat
to true
, the animation will repeat infinitely until you call animatePaper.stop(item, true, true)
(the third parameter should be true, otherwise only the current Animation
will be stopped).
If you set settings.repeat
to a function, it will be called at the end of every "loop" and the Animation
will repeat itself as long as settings.repeat
returns true
.
This feature works best with relative values (e.g. '+myVal'
instead of myVal
), if you repeat an animation with absolute values you won't get the desired result.
animatePaper.animate(item,{
properties: {
rotate: '+360'
},
settings: {
center: new paper.Point(100, 50),
duration: 2000,
repeat: 2, // animation will run 3 times total
easing: "linear"
}
});
animatePaper.animate(item2,{
properties: {
rotate: '+360'
},
settings: {
center: new paper.Point(100, 50),
duration: 2000,
repeat: true, // will loop until .stop() is called
easing: "linear"
}
});
setTimeout(function() {
animatePaper.stop(item2, false, true);
}, 10000);
var c = 0;
animatePaper.animate(item3,{
properties: {
rotate: '+360'
},
settings: {
center: new paper.Point(100, 50),
duration: 2000,
repeat: function(item, animation) { // will run until c >= 2
c++;
return (c < 2);
},
easing: "linear"
}
});
The lib also extends Item.prototype
with .animate()
and .stop()
methods, which means you can also use
myCircle.animate({
/*
Animation parameters ...
*/
});
If you want to perform multiple animations successively, you can provide an array of parameters objects :
var star = new paper.Path.Star(new paper.Point(45,50),5,25,45);
star.fillColor = "black";
star.opacity = 0;
star.animate([{
properties: {
translate: new paper.Point(200,50),
rotate: -200,
scale: 2,
opacity:1
},
settings: {
duration:3000,
easing:"swing"
}
},
{
properties: {
translate: new paper.Point(0,50),
rotate: 200,
scale: 1,
opacity:0
},
settings: {
duration:3000,
easing:"swing"
}
}]);
This is especially helpful when adding predefined animations to the library, it helps avoiding callback hell.
You can stop all running animations on an item by calling :
animatePaper.stop(star);
// or
star.stop();
The stop
method can take a goToEnd
argument.
If true, all the animations will take their final value and complete
callbacks will be called.
By default, the supported easing functions are : linear, swing, easeInSine, easeOutSine, easeInOutSine, easeInCirc, easeOutCirc, easeInOutCirc, easeInElastic, easeOutElastic, easeInOutElastic, easeInBack, easeOutBack, easeInOutBack, easeInBounce, easeOutBounce, easeInOutBounce, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeInQuint, easeOutQuint, easeInOutQuint, easeInExpo, easeOutExpo, easeInOutExpo.
If you want to use more easing functions, settings.easing
can take a (p: number) => number
function as a value, so that you can use your own or use some from an external library such as bezier-easing.
animatePaper.animate(item,{
properties: {
/** ... **/
},
settings: {
/** ... **/
easing: BezierEasing(0, 0, 1, 0.5)
}
});
Alternatively, you can use the animatePaper.extendEasing(myEasingFunctions)
method to add your own easing functions or override any existing easing.
The method takes only one argument : an object in which keys are easing names, and values are easing functions:
animatePaper.extendEasing({
"triple": function(p) {
return p*3;
}
});
Learn more about easing here.
If you want to add support for a new property or override the library's behavior for properties that are already supported,
you can use animatePaper.extendPropHooks(myPropHooks);
.
myPropHooks
should be an object in which keys are property names, and values are "hook objects".
Each "hook object" can have a get
, set
and ease
method, and will be used to interface the animation with the property.
For example, say you want to add support for color animation:
animatePaper.extendPropHooks({
"fillColor": {
get: function(tween) {
// my code ...
},
ease: function(tween,easedPercent) {
// my code ...
}
}
});
When these functions are used, they are passed only one argument : the Tween object (see the doc in doc/ for more details),
exept for the ease()
function which gets the eased percent as second parameter.
get()
function must return the current value of the Tween.item
's property.set()
function must set the value of the Tween.item
's property with Tween.now
(which will most likely be the result of get()
or ease()
)ease()
function must return the eased value. The second parameter is the eased percent.To do so, simply add properties to animatePaper.fx
, like so :
animatePaper.fx.wave = function(item,settings) {
var myAnimations = [...];
item.animate(myAnimations);
};
animatePaper.fx.wave(myItem);
gulp build-paper-animate
and gulp build-paper-animate-browser
.npm test
.item.data._animatePaperVals
works to allow multiple animations of the same property at the same time.Tween
so that we garantee values are right at 0
and 1
positions, to avoid problems with imprecise numbers (floating point). See "Negative position" in tests.js.I'm a beginner in paper.js, so if you spot a mistake or want to add something to the lib, any help would be appreciated :-)
camille dot hodoul at gmail dot com
@Eartz_HC