Andrea Pinchi Design Director

Projects

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;

}

PROJECTS

  •  
    Impossible game: Nyala
  •  
    Wovns: dynamic identity
  •  
    Redesigning Amnesty International Italy
  •  
    Enel powers change
    with Formula E
  •  
    Greenpeace against offshore drilling
  •  
    Space Reactive
  •  
    Worth Wearing
  •  
    Type Seeker
  •  
    Zoetropic Christmas
  •  
    Save the Arctic
  •  
    Greenpeace action path
  •  
    No country for young men
  •  
    Cetacean Pavilion
  •  
    No Hate Speech Online Poster proposals
  •  
    DFI Mobile Application
  •  
    LYH
  •  
    Hotpoint Innovation Area
  •  
    The Boxes Flow
  •  
    Low poly 3D illustrations
  •  
    Chinagram
  •  
    Better Nouveau
  •  
    Banca d’Italia exhibition
  •  
    Chinagram for iPad: Making of
  •  
    Poetry visualization
  •  
    Summer Nights lamp
  •  
    Laser cutting: a menu
  •  
    Persol incognito
  •  
    Type Paintings

Andrea Pinchi — VAT 02985820543 — mail@andreapinchi.it