react-spark-scroll
Version:
Scroll-based animation and actions for React
119 lines (102 loc) • 3.8 kB
JavaScript
// Minimum required to already be loaded in:
// TweenLite.js,CSSPlugin,TimelineLite
// (TweenMax loads all these and more)
;
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
var _ = require('lodash');
var Actor = (function () {
function Actor(tl, context) {
_classCallCheck(this, Actor);
this.tl = tl;
this.context = context;
this.frames = [];
this.frameHash = {};
this.normalizedFrames = [];
}
_createClass(Actor, [{
key: 'normalizeFrames',
value: function normalizeFrames() {
this.normalizedFrames = _.sortBy(_.cloneDeep(this.frames), 'scrollY');
_.forEach(this.normalizedFrames, function (frame, index, arr) {
return index && _.defaults(frame.anims, arr[index - 1].anims);
});
}
}, {
key: 'keyframe',
value: function keyframe(scrollY, anims, ease) {
var frame = { scrollY: scrollY, anims: anims, ease: ease };
this.frames.push(frame);
this.frameHash[scrollY] = frame;
}
}, {
key: 'buildTimeline',
value: function buildTimeline() {
var _this = this;
this.tl.clear();
_.forEach(this.normalizedFrames, function (frame, index, arr) {
if (index) {
var prevFrame = arr[index - 1];
// for easing, instead of this:
// @tl.fromTo(@context, frame.scrollY - prevFrame.scrollY, prevFrame.anims, frame.anims, prevFrame.scrollY)//
// ...do this:
// creating a new fromTo for each property to support per-property easing
// this seems pretty inefficient
var duration = frame.scrollY - prevFrame.scrollY;
for (var k in frame.anims) {
var v = frame.anims[k];
var a = {},
pa = {};
a[k] = v;
a.ease = frame.ease[k];
pa[k] = prevFrame.anims[k];
_this.tl.fromTo(_this.context, duration, pa, a, prevFrame.scrollY);
_this.tl.pause();
}
}
});
}
}, {
key: 'finishedAddingKeyframes',
value: function finishedAddingKeyframes() {
this.normalizeFrames();
this.buildTimeline();
}
}, {
key: 'moveKeyframe',
value: function moveKeyframe(oldPos, newPos) {
var frame = this.frameHash[oldPos];
this.frameHash[newPos] = frame;
frame.scrollY = newPos;
delete this.frameHash[oldPos];
this.normalizeFrames();
this.buildTimeline();
}
}, {
key: 'removeAllKeyframes',
value: function removeAllKeyframes() {
this.tl.clear();
this.frames = [];
}
}]);
return Actor;
})();
var GSAPAnimator = (function () {
function GSAPAnimator() {
_classCallCheck(this, GSAPAnimator);
this.tl = new TimelineLite({ useFrames: true });
}
_createClass(GSAPAnimator, [{
key: 'addActor',
value: function addActor(options) {
return new Actor(this.tl, options.context);
}
}, {
key: 'update',
value: function update(pos) {
if (pos >= 0) this.tl.seek(pos, false); // it balks at negative pos values
}
}]);
return GSAPAnimator;
})();
module.exports = GSAPAnimator;