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 (order === 'circle') {
return [
this.getCapIcon( svg ),
this.getPlateIcon( svg ),
this.getBooksIcon( svg ),
this.getFamilyIcon( svg ),
this.getHandsIcon( svg )
];
} else if (order === 'track') {
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;
if (books.length > 0) {
var book = books.shift();
if (book.animations.length > 1) {
book.svgPath.animate({
transform: book.animations[0]
}, (fn.ANIMATION_DURATION * 0.5), function() {
book.svgPath.animate({
transform: book.animations[1]
}, (fn.ANIMATION_DURATION * 0.5), 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;
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
}, (fn.ANIMATION_DURATION * 0.25), 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