Paper.js animation for “Save the Arctic” campaign
Here the Paper.js animation we developed for the restyling of the “Save the Arctic” campaign for Greenpeace.
var topLeft = [0,0];
var bottomRight = view.viewSize;
// background
bg = new Path.Rectangle({
topLeft: topLeft,
bottomRight: bottomRight,
});
bg.fillColor = {
gradient: {
stops: [['#064188', 0.05], ['#011952', 1]],
radial: true
},
origin: bg.position,
destination: bg.bounds.rightCenter
}
/*Ship Animation*/
//radius of circle (route)
var turnradius = 400;
route = new Path.Circle({
center: view.center,
radius: turnradius});
//debug: route.selected= true;
route.flatten(150);
var segments = route.segments;
for (var i = 0; i < segments.length; i++) {
if(Math.round(Math.random())){
route.removeSegment(i);
}
}
route.smooth();
var ship = project.importSVG(document.getElementById('ship'));
ship.rotate(0);
ship.scale(0.8);
var offset = 0;
var oldRotation = 0;
var tangent;
var ship_trace = new Path();
ship_trace.insertBelow(ship);
trace_count = 0;
ship_trace.add(ship.position);
ship.onFrame = function (event) {
ship.position = route.getPointAt(offset);
offset+=event.delta*20; // speed - 150px/second
if(offset> route.length){
offset=0;
}
tangent = route.getTangentAt(offset);
rotation = tangent.angle - oldRotation;
ship.rotate(rotation);
oldRotation = tangent.angle;
trace_count++;
if(trace_count%2 == 0){
ship_trace.add(ship.position);
if(ship_trace.segments.length > 100){
ship_trace.removeSegment(0);
}
if(ship_trace.segments.length > 1){
ship_trace.style = {
strokeColor: '#FFF',
strokeWidth: 15,
strokeCap: 'round'
};
ship_trace.opacity = .05;
//delete the path when out of focus
if( (ship_trace.segments[ship_trace.segments.length - 1].point - ship_trace.segments[ship_trace.segments.length - 2].point).length > 4){
ship_trace.remove();
ship_trace = new Path();
ship_trace.insertBelow(ship);
trace_count = 0;
}
}
}
}
/*******/
bear_layer = new Layer();
bear_layer.activate();
// import the bear
var bear_back = project.importSVG(document.getElementById('bear_back_svg'));
var bear = project.importSVG(document.getElementById('bear_svg'));
bear.shadowColor = new Color(0,0,0,.2);
bear.shadowBlur = view.viewSize.width/200;
bear.shadowOffset = 0;
for (var i = 0; i < bear.children.length; i++) {
bear.children[i].style = {
fillColor : {
gradient : {
stops : ['#f3fbff', '#c2d2db'],
radial: true
},
origin : bear.children[i].position,
destination : bear.children[i].position + 220
}
};
}
bear_bounds = new Path.Rectangle(bear.bounds.x,bear.bounds.y,bear.bounds.width,bear.bounds.height)
bear.position = new Point(bear_bounds.bounds.width/2, bear_bounds.bounds.height/2);
//bear_back
bear_back.position = new Point(bear_bounds.bounds.width/2, bear_bounds.bounds.height/2);
bear_back.fillColor = new Color(255,255,255,1);
bear_back.opacity = .6;
bear_back.shadowColor = '#bad1f5';
bear_back.shadowBlur = 40;
bear_back.shadowOffset = 0;
bear_back.children[0].smooth();
//create a empty bear, we will put there all the hitted shapes
var bear_move = new Group();
bear_move.shadowColor = new Color(0,0,0,.1);
bear_move.shadowBlur = 30;
bear_move.shadowOffset = 0;
// the circle for hitTest
var hitCircle = new Path.Ellipse({
center: new Point(bear_bounds.bounds.width/2, bear_bounds.bounds.height/2),
size: bear_bounds.bounds
});
//debug: display hitCircle
//hitCircle.selected = true;
//scale to 1
bear_layer.scale(1);
function onFrame(event) {
if(bear.children.length >= 1 ){
if(Math.round(Math.random())){ //randomize circle scale
hitCircle.scale(.9991);
for (var i = 0; i < bear.children.length; i++) {
var intersections = hitCircle.getIntersections(bear.children[i]);
if(intersections.length > 0){
copy = bear.children[i].clone();
copy.clockwise = Math.round(Math.random());
bear_move.addChild(copy);
bear.children[i].remove();
//debug: intersections points
/*for (var h = 0; h < intersections.length; h++) {
var intersectionPath = new Path.Circle({
center: intersections[h].point,
radius: 3,
fillColor: 'red'
});
}*/
}
}
}
}
for (var i = 0; i < bear_move.children.length; i++) {
bear_move.children[i].scale(.9989);
if(bear_move.children[i].clockwise){
bear_move.children[i].rotate(-.03)
}else {
bear_move.children[i].rotate(.03)
}
if (bear_move.children[i].bounds.width < 10) {
if(bear_move.children[i].opacity > 0.01){
bear_move.children[i].opacity = bear_move.children[i].opacity-.01
}else {
bear_move.children[i].remove();
}
}
}
if(bear_back.children[0].opacity > .02){
bear_back.children[0].opacity -= .00001;
}
if(bear_back.children[1].opacity > .01){
bear_back.children[1].opacity -= .00008;
}
if(bear_back.children[2].opacity > .01){
bear_back.children[2].opacity -= .001;
}
}
function onResize(event){
route.bounds.width = 800;
route.bounds.height = 800;
bear_layer.bounds.width = 805.7367475253404;
bear_layer.bounds.height = 810.1726177758762;
var currentviewWidth= view.viewSize.width;
var position;
if(currentviewWidth <= 600){
route.scale(0.55);
bear_layer.scale(.65);
position = view.center - new Point(50,60);
}
else if((601 <= currentviewWidth) && ( currentviewWidth < 800)){
route.scale(0.8);
bear_layer.scale(0.9);
position = view.center - new Point(60,120);
}
else{
route.scale(1);
bear_layer.scale(1.1);
position = view.center - new Point(60,130);
}
//resize background
bg.bounds.width = currentviewWidth;
//new position for layer
route.position = view.center;
bear_layer.position = position;
}