Skip to content

Instantly share code, notes, and snippets.

@rogeruiz
Last active August 29, 2015 14:19
Show Gist options
  • Select an option

  • Save rogeruiz/f35b498fa80d07b1dc1f to your computer and use it in GitHub Desktop.

Select an option

Save rogeruiz/f35b498fa80d07b1dc1f to your computer and use it in GitHub Desktop.
Animation Engine used on How We Work for CISofRichmond
import { $, RSVP, _, Snap, mina, help } from 'util';
var Fn = function() {
var fn = this;
this.DELAY_START = 250;
this.ANIMATION_DURATION = 550;
this.CIRCLE_ROTATION_DURATION = 50000;
this.el = {
container: '.js-hww-container'
};
this.ctx = {
'studentDropout': {
init: function() {
var svg = this.getSvg();
this.books = fn.getAllBooks( svg );
},
animate: function() {
var ctx = this;
window.setTimeout( function() {
fn.toppleBooks( ctx.books );
}, fn.DELAY_START );
}
},
'siteCoordinator': {
init: function() {
var svg = this.getSvg();
this.coordinator = fn.getCoordinator( svg );
this.coordinator.attr( {
transform: 'translate(50, 0)',
opacity: 0
} );
},
animate: function() {
var ctx = this;
window.setTimeout(function() {
ctx.coordinator.animate( {
transform: 'translate(0, 0)',
opacity: 1
}, fn.ANIMATION_DURATION );
}, fn.DELAY_START);
}
},
'collaborativeEffort': {
init: function() {
var svg = this.getSvg();
this.mainCircle = fn.getMainCircle( svg );
this.icons = fn.getAllIcons( svg, 'circle' );
_.forEach(this.icons, function( icon ) {
icon.attr({
opacity: 0.15
});
});
},
animate: function() {
var ctx = this;
window.setTimeout( function() {
fn.fadeIn(ctx.icons, function() {
fn.rotateMainCircle( ctx.mainCircle );
});
}, fn.DELAY_START );
}
},
'integratedServices': {
init: function() {
var svg = this.getSvg();
this.mainCircle = fn.getMainCircle( svg );
this.icons = fn.getAllIcons( svg, 'circle' );
},
animate: function() {
var ctx = this;
window.setTimeout( function() {
fn.bounceIn(ctx.icons, function() {
fn.rotateMainCircle( ctx.mainCircle );
});
}, fn.DELAY_START );
}
},
'monitorTrackServices': {
init: function() {
var svg = this.getSvg();
this.icons = fn.getAllIcons( svg, 'track' );
_.forEach(this.icons, function( icon ) {
var cover = icon.select( '#cis-circle-cover' );
var mark = icon.select( '#cis-check-mark' );
cover.attr({
opacity: 0
});
var len = mark.getTotalLength();
mark.attr({
'stroke-dasharray': len + ' ' + len,
'stroke-dashoffset': len,
opacity: 0
});
});
},
animate: function() {
var ctx = this;
window.setTimeout( function() {
fn.animateTracks( ctx.icons );
}, fn.DELAY_START );
}
}
};
return this;
};
Fn.prototype.getMainCircle = function( svg ) {
return svg.select( '#cis-circle-main' );
};
Fn.prototype.getCapIcon = function( svg ) {
return svg.select( '#cis-cap' );
};
Fn.prototype.getFamilyIcon = function( svg ) {
return svg.select( '#cis-family' );
};
Fn.prototype.getPlateIcon = function( svg ) {
return svg.select( '#cis-plate' );
};
Fn.prototype.getBooksIcon = function( svg ) {
return svg.select( '#cis-books' );
};
Fn.prototype.getHandsIcon = function( svg ) {
return svg.select( '#cis-hands' );
};
Fn.prototype.getCoordinator = function( svg ) {
return svg.select( '#cis-coordinator' );
};
Fn.prototype.getAllIcons = function(svg, order) {
if ( 'circle' === order ) {
return [
this.getCapIcon( svg ),
this.getPlateIcon( svg ),
this.getBooksIcon( svg ),
this.getFamilyIcon( svg ),
this.getHandsIcon( svg )
];
} else if ( 'track' === order ) {
return [
this.getPlateIcon( svg ),
this.getBooksIcon( svg ),
this.getFamilyIcon( svg ),
this.getHandsIcon( svg ),
this.getCapIcon( svg )
];
}
};
Fn.prototype.getAllBooks = function( svg ) {
var bookRange = _.range( 4 );
return _.map( bookRange, function( book, idx ) {
var path = svg.select( '#cis-book-' + ( idx + 1 ) );
var bounds = path.getBBox();
var width = bounds.width;
var x = bounds.x;
var cx = width + x;
var height = bounds.height;
var y = bounds.y;
var cy = height + y;
var queue = [];
switch ( idx ) {
case 0:
queue.push( `rotate(90, ${cx}, ${cy})` );
break;
case 1:
queue.push( `rotate(45, ${cx}, ${cy})` );
queue.push( `rotate(90, ${cx}, ${cy}), translate(${-width}, 0)` );
break;
default:
queue.push( `rotate(35, ${cx}, ${cy})` );
}
return {
svgPath: path,
animations: queue
};
} );
};
Fn.prototype.rotateMainCircle = function( circle ) {
var fn = this;
var cx = circle.attr( 'cx' );
var cy = circle.attr( 'cy' );
var r = circle.attr( 'r' );
circle.animate( {
transform: `rotate(360, ${cx}, ${cy})`
}, fn.CIRCLE_ROTATION_DURATION, function() {
circle.attr( {
transform: `rotate(0, ${cx}, ${cy})`
} );
fn.rotateMainCircle( circle );
} );
};
Fn.prototype.toppleBooks = function( books, done ) {
var fn = this;
var halfTime = fn.ANIMATION_DURATION * 0.5;
if ( books.length > 0 ) {
var book = books.shift();
if ( book.animations.length > 1 ) {
book.svgPath.animate( {
transform: book.animations[ 0 ]
}, halfTime, function() {
book.svgPath.animate( {
transform: book.animations[ 1 ]
}, halfTime, function() {
fn.toppleBooks(books, done);
} );
} );
} else {
book.svgPath.animate( {
transform: book.animations[ 0 ]
}, fn.ANIMATION_DURATION, function() {
fn.toppleBooks( books, done );
} );
}
} else {
if ( $.isFunction( done ) ) {
done();
}
}
};
Fn.prototype.animateTracks = function( icons, done ) {
var fn = this;
if ( icons.length > 0 ) {
var icon = icons.shift();
var cover = icon.select( '#cis-circle-cover' );
var mark = icon.select( '#cis-check-mark' );
cover.animate( {
opacity: 0.8
}, fn.ANIMATION_DURATION, function() {
mark.animate( {
opacity: 1,
'stroke-dashoffset': 10
}, fn.ANIMATION_DURATION, function() {
fn.animateTracks(icons, done);
} );
} );
} else {
if ( $.isFunction( done ) ) {
done();
}
}
};
Fn.prototype.fadeIn = function( items, done ) {
var fn = this;
if ( items.length > 0 ) {
var item = items.shift();
item.animate( {
opacity: 1
}, fn.ANIMATION_DURATION, function() {
fn.fadeIn( items, done );
} );
} else {
if ( $.isFunction( done ) ) {
done();
}
}
};
Fn.prototype.bounceIn = function( items, done ) {
var fn = this;
var quarterTime = fn.ANIMATION_DURATION * 0.25;
if ( items.length > 0 ) {
var item = items.shift();
var scaleFactor = 1.25;
var x = item.select( 'circle' ).attr( 'cx' ) * ( scaleFactor - 1 );
var y = item.select( 'circle' ).attr( 'cy' ) * ( scaleFactor - 1 );
item.animate( {
transform: `translate(${-x}, ${-y}) scale(${scaleFactor})`,
opacity: 0.85
}, quarterTime, function() {
item.animate( {
transform: 'scale(1)',
opacity: 1
}, fn.ANIMATION_DURATION, mina.bounce, function() {
fn.bounceIn( items, done );
} );
} );
} else {
if ( $.isFunction( done ) ) {
done();
}
}
};
var Engine = function( name ) {
var component = this;
this.fn = new Fn();
this.animated = false;
this.name = name;
this.ctx = this.fn.ctx[ name ];
this.ctx.getContainer = function() {
return $( '.js-' + help.dasherize( name ) );
};
this.ctx.getSvg = function() {
return Snap( '#cis-' + help.dasherize( name ) );
};
this.ctx.getParentContainer = function() {
return this.getContainer().parents( component.fn.el.container );
};
this.ctx.getThreshold = function() {
return this.getParentContainer().offset().top - ( this.getContainer().height() * 0.5 );
};
this.ctx.init();
this.recalculateSize();
return this;
};
Engine.prototype.triggerAnimation = function() {
if ( this.animated ) {
return;
}
if ( $(window).scrollTop() >= this.ctx.getThreshold() ) {
this.ctx.animate();
this.animated = true;
}
};
Engine.prototype.recalculateSize = function() {
var $container = this.ctx.getContainer();
$container.find( 'svg' ).css({
width: $container.width(),
height: $container.width()
});
};
export default Engine;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment