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