@hugeinc/scrollify
Advanced tools
Comparing version 0.3.0 to 0.4.7
'use strict'; | ||
Object.defineProperty(exports, '__esModule', { value: true }); | ||
/** | ||
@@ -8,8 +10,35 @@ * Feature detection: CSS transforms | ||
var dummy = document.createElement('div'); | ||
var transform = ['transform', 'webkitTransform', 'MozTransform', 'OTransform', 'msTransform'].find(function (t) { | ||
// return (document.body.style[t] !== undefined); // if DOM is not yet ready, let's do: | ||
return (dummy.style[t] !== undefined); | ||
var transform; | ||
var dummy = document.createElement('div'); // we use this instead of document.body if the DOM is not yet ready | ||
['transform', 'webkitTransform', 'MozTransform', 'OTransform', 'msTransform'].forEach(function (t) { | ||
if (dummy.style[t] !== undefined) { transform = t; } | ||
}); | ||
var transform$1 = transform; | ||
/* | ||
The MIT License (MIT) | ||
Copyright (c) 2015 Daniel Lundin | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
*/ | ||
function assignedMatrixMultiplication(a, b, res) { | ||
@@ -268,12 +297,25 @@ // Unrolled loop | ||
function getUnit(val) { | ||
var split = /([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg|rad|turn)?/.exec(val); | ||
if (split) return split[2]; | ||
} | ||
/* | ||
* scrollify | ||
* https://github.com/apathetic/scrollify | ||
* | ||
* Copyright (c) 2016, 2017 Wes Hatch | ||
* Licensed under the MIT license. | ||
* | ||
*/ | ||
/** | ||
* The Scrollify Class | ||
*/ | ||
var Scrollify = function Scrollify(element) { | ||
var this$1 = this; | ||
var Scrollify$1 = function Scrollify(element) { | ||
if (element instanceof HTMLElement == false) { element = document.querySelector(element); } | ||
if (!element || !transform) { return this.active = false; } | ||
// if (!transform) { throw 'Scrollify [error]: transforms not supported'; } | ||
// if (!element) { throw 'Scrollify [error]: could not find element'; } | ||
if (!element || !transform$1) { | ||
console.log('Scrollify [error] ', arguments[0]); | ||
return this.disable(); | ||
} | ||
@@ -289,9 +331,11 @@ this.element = element; | ||
rotation: [0,0,0], | ||
position: [0,0,0] | ||
// transformOrigin: [], | ||
position: [0,0,0], | ||
// transformOrigin: [0,0,0] | ||
// skew: [], | ||
}; | ||
window.addEventListener('scroll', function (e) { return this$1.onScroll(e); }); | ||
window.addEventListener('resize', function (e) { return this$1.onResize(e); }); | ||
// window.addEventListener('scroll', () => this.onScroll(), { passive: true }); | ||
// window.addEventListener('resize', () => this.onResize(), { passive: true }); | ||
window.addEventListener('scroll', this.onScroll.bind(this), { passive: true }); | ||
window.addEventListener('resize', this.onResize.bind(this), { passive: true }); | ||
}; | ||
@@ -304,52 +348,54 @@ | ||
* | ||
* start: (required) When to start the effect. It is a 0 - 1 value | ||
* representing the percentage of the viewport (eg. 0.5). | ||
* Any effects in the Scene will begin when the trigger element | ||
* crosses this threshold. | ||
* start: (required) When to start the effect. It is a 0 - 1 value | ||
* representing the percentage of the viewport (eg. 0.5). | ||
* Any effects in the Scene will begin when the trigger element | ||
* crosses this threshold. | ||
* | ||
* duration: The length of the effect, in pixels. Scrollify will | ||
* interpolate that into value into a "progress" variable, bounded | ||
* by 0 - 1. If not supplied, the default value is the height of the | ||
* viewport + element height, meaning the effect will last for as | ||
* long as the element is visible. | ||
*duration: The length of the effect, in pixels. Scrollify will | ||
* interpolate that into value into a "progress" variable, bounded | ||
* by 0 - 1. If not supplied, the default value is the height of | ||
* the viewport + element height, meaning the effect will last for | ||
* as long as the element is visible. | ||
* | ||
* trigger: If supplied, Scrollify will use this element's position to | ||
* start any Scene effects. If not supplied, the default is to use | ||
* the element itself as a trigger. | ||
* start any Scene effects. If not supplied, the default is to use | ||
* the element itself as a trigger. | ||
* | ||
* easing: Ease in/out of an effect. Any value from Robert Penner's easing | ||
* functions is valid. | ||
* easing: Ease in/out of any effects in the Scene. | ||
* | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.addScene = function addScene (opts) { | ||
Scrollify$1.prototype.addScene = function addScene (opts) { | ||
var this$1 = this; | ||
var triggerPos = opts.start || 0; | ||
var duration = opts.duration || window.innerHeight + this.element.offsetHeight; | ||
var trigger = opts.trigger ? opts.trigger instanceof HTMLElement ? opts.trigger : document.querySelector(opts.trigger) : this.element; | ||
var easing = opts.easing || false; | ||
var effects = opts.effects || []; | ||
var trigger = opts.trigger ? opts.trigger instanceof HTMLElement ? opts.trigger : document.querySelector(opts.trigger) : this.element; | ||
var applyTransform = opts.applyTransform !== undefined ? opts.applyTransform : true; // opt out rather than opt in | ||
var scene = { | ||
trigger: trigger, | ||
triggerPos: 1 - triggerPos, | ||
duration: duration, | ||
_trigger: trigger, // keep for internal calculations | ||
_applyTransform: false, // internal-use only. Whether to use matrix transforms or not. Perhaps should be moved to *effect* level | ||
_offset: opts.start || 0, // store original value for later calcs | ||
_duration: opts.duration || 1, // store original value for later calculations | ||
// start: 0, // absolute value in px. Some percentage of the viewport | ||
// duration: duration, // absolute value in px. Some percentage of the viewport | ||
easing: easing, | ||
applyTransform: applyTransform, | ||
effects: [] | ||
}; | ||
// scene.active = this.scroll > this.calculateStart(scene); // calculate any transformations if the scene has already passed. | ||
effects.map(function (effect) { | ||
this$1.addEffect(effect.fn, effect.options, scene); | ||
}); | ||
this.calculateStart(scene); | ||
scene.state = (this.scroll > this.start) ? (this.scroll > this.start+duration) ? 'after' : 'active' : 'before'; | ||
this.calculateDuration(scene); | ||
effects.map(function (effect) { | ||
this$1.addEffect(effect.name, effect.options, scene); | ||
}); | ||
scene.state = (this.scroll > this.start) ? (this.scroll > this.start+scene.duration) ? 'after' : 'active' : 'before'; | ||
this.updateScene(scene); | ||
this.calculate(scene); | ||
this.scenes.push(scene); | ||
if (opts.debug) { | ||
console.log('Scrollify scene: ', scene); | ||
} | ||
return this; | ||
@@ -363,4 +409,5 @@ }; | ||
*/ | ||
Scrollify.prototype.updateScene = function updateScene (scene) { | ||
Scrollify$1.prototype.updateScene = function updateScene (scene) { | ||
this.calculateStart(scene); | ||
this.calculateDuration(scene); | ||
this.calculate(scene); | ||
@@ -376,3 +423,3 @@ }; | ||
*/ | ||
Scrollify.prototype.addEffect = function addEffect (effect, options, scene) { | ||
Scrollify$1.prototype.addEffect = function addEffect (fn, options, scene) { | ||
if ( options === void 0 ) options = {}; | ||
@@ -382,2 +429,3 @@ | ||
var transforms = this.transforms; | ||
var context = { options: options, element: element, transforms: transforms }; | ||
@@ -391,3 +439,3 @@ if (!scene) { | ||
return this.addScene({ | ||
'effects': [{'name': effect, 'options': options}] | ||
'effects': [{'fn': fn, 'options': options}] | ||
}); | ||
@@ -397,16 +445,6 @@ } | ||
var curry = function (fn, options) { | ||
return function() { // NOTE: don't use => function here as we do NOT want to bind "this" | ||
var context = { | ||
'options': options, | ||
'element': element, | ||
'transforms': transforms | ||
}; | ||
// if any effect uses a matrix tranformation, we use true for the entire scene | ||
scene._applyTransform = scene._applyTransform || fn._applyTransform; | ||
scene.effects.push(fn.bind(context)); | ||
fn.call(context, this); // eslint-disable-line | ||
}; | ||
}; | ||
scene.effects.push(curry(effect, options)); | ||
return this; | ||
@@ -417,8 +455,8 @@ }; | ||
* Calculate the start point of each scene. | ||
* @param{[type]} scene A Scrollify Scene object. | ||
* @param{Scrollify.Scene} scene A Scrollify Scene object. | ||
* @return {Integer} The start position of the Scene, in pixels. | ||
*/ | ||
Scrollify.prototype.calculateStart = function calculateStart (scene) { | ||
var trigger = scene.trigger; | ||
var triggerPos = scene.triggerPos; | ||
Scrollify$1.prototype.calculateStart = function calculateStart (scene) { | ||
var offset = window.innerHeight - this.mapTo(scene._offset, window.innerHeight); | ||
var trigger = scene._trigger; | ||
var top = 0; | ||
@@ -430,13 +468,42 @@ | ||
} while(trigger); | ||
// top = trigger.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); | ||
// var test = trigger.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); | ||
// return Math.max(0, top - triggerPos * window.innerHeight); // (can be negative...?) | ||
scene.start = Math.max(0, top - triggerPos * window.innerHeight); | ||
scene.start = Math.max(0, top - offset); | ||
}; | ||
/** | ||
* [mapTo description] | ||
* @param{[type]} input [description] | ||
* @param{[type]} scale [description] | ||
* @return {[type]} [description] | ||
*/ | ||
Scrollify$1.prototype.mapTo = function mapTo (input, scale) { | ||
var parsed = parseFloat(input); | ||
var unit = getUnit(input); | ||
switch (unit) { | ||
case 'px': | ||
return parsed; | ||
case '%': | ||
return parsed / 100.0 * scale; | ||
default: | ||
return parsed * scale; | ||
} | ||
}; | ||
/** | ||
* [calculateDuration description] | ||
* @param{[type]} scene [description] | ||
* @return [type] [description] | ||
*/ | ||
Scrollify$1.prototype.calculateDuration = function calculateDuration (scene) { | ||
// if (typeof scene._duration === 'function') { return scene._duration(); } | ||
scene.duration = this.mapTo(scene._duration, window.innerHeight + this.element.offsetHeight); | ||
}; | ||
/** | ||
* onScroll Handler | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.onScroll = function onScroll () { | ||
Scrollify$1.prototype.onScroll = function onScroll () { | ||
if (!this.active) { return; } | ||
@@ -455,3 +522,3 @@ this.scroll = window.scrollY || window.pageYOffset; | ||
*/ | ||
Scrollify.prototype.onResize = function onResize () { | ||
Scrollify$1.prototype.onResize = function onResize () { | ||
this.scenes.forEach(this.updateScene, this); | ||
@@ -464,3 +531,3 @@ }; | ||
*/ | ||
Scrollify.prototype.update = function update () { | ||
Scrollify$1.prototype.update = function update () { | ||
this.scenes.forEach(this.calculate, this); | ||
@@ -477,3 +544,3 @@ this.ticking = false; | ||
*/ | ||
Scrollify.prototype.calculate = function calculate (scene) { | ||
Scrollify$1.prototype.calculate = function calculate (scene) { | ||
var start = scene.start; | ||
@@ -483,3 +550,2 @@ var duration = scene.duration; | ||
var progress; | ||
var matrix; | ||
@@ -516,9 +582,9 @@ // after end | ||
scene.effects.forEach(function (effect) { | ||
effect.call(progress); | ||
effect(progress); | ||
}); | ||
if (scene.applyTransform) { | ||
if (scene._applyTransform) { | ||
// transmogrify all applied transformations into a single matrix, and apply | ||
matrix = this.updateMatrix(); | ||
this.element.style[transform] = matrix.asCSS(); | ||
var matrix = this.updateMatrix(); | ||
this.element.style[transform$1] = matrix.asCSS(); | ||
} | ||
@@ -531,3 +597,3 @@ }; | ||
*/ | ||
Scrollify.prototype.updateMatrix = function updateMatrix () { | ||
Scrollify$1.prototype.updateMatrix = function updateMatrix () { | ||
var t = this.transforms; | ||
@@ -561,18 +627,2 @@ var m = this.matrix; | ||
// ----------------------------------------------------- | ||
// IF we wished to perform rotation AFTER skew / position / etc, we could do it here. | ||
// The ordering is important, and has an effect. | ||
// if (t.rotationPost) { | ||
// m.rotateX(t.rotationPost[0]); | ||
// m.rotateY(t.rotationPost[1]); | ||
// m.rotateZ(t.rotationPost[2]); | ||
// } | ||
// if (t.scalePost) { | ||
// m.scale(t.scalePost[0], t.scalePost[1]); | ||
// } | ||
// ----------------------------------------------------- | ||
// ... and here we put it back. (This duplication is not a mistake). | ||
@@ -590,6 +640,426 @@ if (t.transformOrigin) { | ||
*/ | ||
Scrollify.prototype.disable = function disable () { | ||
Scrollify$1.prototype.disable = function disable () { | ||
this.active = false; | ||
}; | ||
module.exports = Scrollify; | ||
/** | ||
* A list of some default "transformations" that may be applied | ||
* Options are applied at initialize and are curried in via "this". | ||
* | ||
* NOTE: for all functions herein, "this" contains effect options, a | ||
* transformation Object, and also a reference to the element. | ||
*/ | ||
/*global console*/ | ||
/*eslint no-invalid-this: "error"*/ | ||
// Effects that use matrix transformations. At present, only | ||
// built-in effects benefit from matrix transformations. | ||
[translateX, translateY, rotate, scale, parallax].forEach(function (fn) { | ||
fn._applyTransform = true; | ||
}); | ||
/** | ||
* Translate an element along the X-axis. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function translateX(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 0; | ||
var offset = (to - from) * progress + from; | ||
this.transforms.position[0] = offset; | ||
} | ||
/** | ||
* Translate an element vertically. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function translateY(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 0;// this.transforms.position[1]; | ||
var offset = (to - from) * progress + from; | ||
this.transforms.position[1] = offset; | ||
} | ||
// export function translate(progress) { | ||
// const to = this.options.to; | ||
// const from = this.options.from; | ||
// const offsetX = (to[0] - from[0]) * progress + from[0]; | ||
// const offsetY = (to[1] - from[1]) * progress + from[1]; | ||
// | ||
// this.transforms.position[0] = offsetX; | ||
// this.transforms.position[1] = offsetY; | ||
// } | ||
/** | ||
* Rotate an element, using radians. (note: rotates around Z-axis). | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function rotate(progress) { | ||
var radians = this.options.rad * progress; | ||
this.transforms.rotation[2] = radians; | ||
} | ||
/** | ||
* Uniformly scale an element along both axis'. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function scale(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 1; | ||
var from = (this.options.from !== undefined) ? this.options.from : this.transforms.scale[0]; | ||
var scale = (to - from) * progress + from; | ||
this.transforms.scale[0] = scale; | ||
this.transforms.scale[1] = scale; | ||
} | ||
/** | ||
* Update an element's opacity. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function fade(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 1; | ||
var opacity = (to - from) * progress + from; | ||
this.element.style.opacity = opacity; | ||
} | ||
/** | ||
* Update an element's blur. | ||
* @param {Float} progress Current progress of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function blur(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 0; | ||
var amount = (to - from) * progress + from; | ||
this.element.style.filter = 'blur(' + amount + 'px)'; | ||
} | ||
/** | ||
* Parallax an element. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function parallax(progress) { | ||
var range = this.options.range || 0; | ||
var offset = progress * range; // TODO add provision for speed as well | ||
this.transforms.position[1] = offset; // just vertical for now | ||
} | ||
/** | ||
* Toggle a class on or off. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function toggle(progress) { | ||
var opts = this.options; | ||
var element = this.element; | ||
var times = Object.keys(opts); | ||
times.forEach(function(time) { | ||
var css = opts[time]; | ||
if (progress > time) { | ||
element.classList.add(css); | ||
} else { | ||
element.classList.remove(css); | ||
} | ||
}); | ||
} | ||
/** | ||
* Sticky Element: sets up a sticky element which toggles position 'fixed' on / off. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function stick(progress) { | ||
var element = this.element; | ||
var currentState = '_'; | ||
if (progress <= 0) { | ||
setState(element, 'normal'); | ||
} else if (progress >= 1) { | ||
setState(element, 'bottom'); | ||
} else { | ||
setState(element, 'sticky'); | ||
} | ||
function setState(element, state) { | ||
var BCR = element.getBoundingClientRect(); | ||
if (currentState === state) { return; } | ||
if (state == 'sticky') { | ||
element.style.top = BCR.top + 'px'; | ||
element.style.left = BCR.left + 'px'; | ||
element.style.width = BCR.width + 'px'; | ||
} else { | ||
element.style.top = ''; | ||
element.style.left = ''; | ||
element.style.width = ''; | ||
} | ||
element.className = ''; | ||
// element.classList.remove(currentState); // TODO: why is this not working? | ||
element.classList.add(state); | ||
currentState = state; | ||
} | ||
} | ||
var effects = Object.freeze({ | ||
translateX: translateX, | ||
translateY: translateY, | ||
rotate: rotate, | ||
scale: scale, | ||
fade: fade, | ||
blur: blur, | ||
parallax: parallax, | ||
toggle: toggle, | ||
stick: stick | ||
}); | ||
/*eslint max-len: ["error", 120]*/ | ||
function oscillate(t, b, c, d) { | ||
var i = 4; // # of bounces | ||
t /= d; // percentage | ||
t = Math.PI * i * t; // go from 0 -> 2π | ||
t = Math.sin(t) * c; // now, oscillates between c, -c | ||
t = Math.abs(t); // "half wave rectifier" | ||
return t + b; | ||
} | ||
function easeInQuad(t, b, c, d) { | ||
return c * (t /= d) * t + b; | ||
} | ||
function easeOutQuad(t, b, c, d) { | ||
return -c * (t /= d) * (t - 2) + b; | ||
} | ||
function easeInOutQuad(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t + b; } | ||
return -c / 2 * (--t * (t - 2) - 1) + b; | ||
} | ||
function easeInCubic(t, b, c, d) { | ||
return c * (t /= d) * t * t + b; | ||
} | ||
function easeOutCubic(t, b, c, d) { | ||
return c * ((t = t / d - 1) * t * t + 1) + b; | ||
} | ||
function easeInOutCubic(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t + b; } | ||
return c / 2 * ((t -= 2) * t * t + 2) + b; | ||
} | ||
function easeInQuart(t, b, c, d) { | ||
return c * (t /= d) * t * t * t + b; | ||
} | ||
function easeOutQuart(t, b, c, d) { | ||
return -c * ((t = t / d - 1) * t * t * t - 1) + b; | ||
} | ||
function easeInOutQuart(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t + b; } | ||
return -c / 2 * ((t -= 2) * t * t * t - 2) + b; | ||
} | ||
function easeInQuint(t, b, c, d) { | ||
return c * (t /= d) * t * t * t * t + b; | ||
} | ||
function easeOutQuint(t, b, c, d) { | ||
return c * ((t = t / d - 1) * t * t * t * t + 1) + b; | ||
} | ||
function easeInOutQuint(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t * t + b; } | ||
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; | ||
} | ||
function easeInSine(t, b, c, d) { | ||
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; | ||
} | ||
function easeOutSine(t, b, c, d) { | ||
return c * Math.sin(t / d * (Math.PI / 2)) + b; | ||
} | ||
function easeInOutSine(t, b, c, d) { | ||
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; | ||
} | ||
function easeInExpo(t, b, c, d) { | ||
return t == 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; | ||
} | ||
function easeOutExpo(t, b, c, d) { | ||
return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; | ||
} | ||
function easeInOutExpo(t, b, c, d) { | ||
if (t == 0) { return b; } | ||
if (t == d) { return b + c; } | ||
if ((t /= d / 2) < 1) { return c / 2 * Math.pow(2, 10 * (t - 1)) + b; } | ||
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; | ||
} | ||
function easeInCirc(t, b, c, d) { | ||
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; | ||
} | ||
function easeOutCirc(t, b, c, d) { | ||
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; | ||
} | ||
function easeInOutCirc(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; } | ||
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; | ||
} | ||
function easeInElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
if (t == 0) { return b; } | ||
if ((t /= d) == 1) { return b + c; } | ||
if (!p) { p = d * .3; } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
return -(a * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; | ||
} | ||
function easeOutElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
if (t == 0) { return b; } | ||
if ((t /= d) == 1) { return b + c; } | ||
if (!p) { p = d * .3; } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
return a * Math.pow(2,-10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b; | ||
} | ||
function easeInOutElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
if (t == 0) { return b; } | ||
if ((t /= d / 2) == 2) { return b + c; } | ||
if (!p) { p = d * (.3 * 1.5); } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
if (t < 1) { return -.5 * (a * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; } | ||
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b; | ||
} | ||
function easeInBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
return c * (t /= d) * t * ((s + 1) * t - s) + b; | ||
} | ||
function easeOutBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; | ||
} | ||
function easeInOutBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
if ((t /= d / 2) < 1) { return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b; } | ||
return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b; | ||
} | ||
function easeOutBounce(t, b, c, d) { | ||
if (t /= d < 1 / 2.75) { | ||
return c * (7.5625 * t * t) + b; | ||
} else if (t < 2 / 2.75) { | ||
return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b; | ||
} else if (t < 2.5 / 2.75) { | ||
return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b; | ||
} else { | ||
return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b; | ||
} | ||
} | ||
var easings = Object.freeze({ | ||
oscillate: oscillate, | ||
easeInQuad: easeInQuad, | ||
easeOutQuad: easeOutQuad, | ||
easeInOutQuad: easeInOutQuad, | ||
easeInCubic: easeInCubic, | ||
easeOutCubic: easeOutCubic, | ||
easeInOutCubic: easeInOutCubic, | ||
easeInQuart: easeInQuart, | ||
easeOutQuart: easeOutQuart, | ||
easeInOutQuart: easeInOutQuart, | ||
easeInQuint: easeInQuint, | ||
easeOutQuint: easeOutQuint, | ||
easeInOutQuint: easeInOutQuint, | ||
easeInSine: easeInSine, | ||
easeOutSine: easeOutSine, | ||
easeInOutSine: easeInOutSine, | ||
easeInExpo: easeInExpo, | ||
easeOutExpo: easeOutExpo, | ||
easeInOutExpo: easeInOutExpo, | ||
easeInCirc: easeInCirc, | ||
easeOutCirc: easeOutCirc, | ||
easeInOutCirc: easeInOutCirc, | ||
easeInElastic: easeInElastic, | ||
easeOutElastic: easeOutElastic, | ||
easeInOutElastic: easeInOutElastic, | ||
easeInBack: easeInBack, | ||
easeOutBack: easeOutBack, | ||
easeInOutBack: easeInOutBack, | ||
easeOutBounce: easeOutBounce | ||
}); | ||
/** | ||
* Put Scrollify into the Global scope. | ||
* Useful for existing demos or if you wish to include manually | ||
*/ | ||
exports['default'] = Scrollify$1; | ||
exports.Scrollify = Scrollify$1; | ||
exports.fx = effects; | ||
exports.easings = easings; |
@@ -6,8 +6,35 @@ /** | ||
var dummy = document.createElement('div'); | ||
var transform = ['transform', 'webkitTransform', 'MozTransform', 'OTransform', 'msTransform'].find(function (t) { | ||
// return (document.body.style[t] !== undefined); // if DOM is not yet ready, let's do: | ||
return (dummy.style[t] !== undefined); | ||
var transform; | ||
var dummy = document.createElement('div'); // we use this instead of document.body if the DOM is not yet ready | ||
['transform', 'webkitTransform', 'MozTransform', 'OTransform', 'msTransform'].forEach(function (t) { | ||
if (dummy.style[t] !== undefined) { transform = t; } | ||
}); | ||
var transform$1 = transform; | ||
/* | ||
The MIT License (MIT) | ||
Copyright (c) 2015 Daniel Lundin | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
*/ | ||
function assignedMatrixMultiplication(a, b, res) { | ||
@@ -266,12 +293,25 @@ // Unrolled loop | ||
function getUnit(val) { | ||
var split = /([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg|rad|turn)?/.exec(val); | ||
if (split) return split[2]; | ||
} | ||
/* | ||
* scrollify | ||
* https://github.com/apathetic/scrollify | ||
* | ||
* Copyright (c) 2016, 2017 Wes Hatch | ||
* Licensed under the MIT license. | ||
* | ||
*/ | ||
/** | ||
* The Scrollify Class | ||
*/ | ||
var Scrollify = function Scrollify(element) { | ||
var this$1 = this; | ||
var Scrollify$1 = function Scrollify(element) { | ||
if (element instanceof HTMLElement == false) { element = document.querySelector(element); } | ||
if (!element || !transform) { return this.active = false; } | ||
// if (!transform) { throw 'Scrollify [error]: transforms not supported'; } | ||
// if (!element) { throw 'Scrollify [error]: could not find element'; } | ||
if (!element || !transform$1) { | ||
console.log('Scrollify [error] ', arguments[0]); | ||
return this.disable(); | ||
} | ||
@@ -287,9 +327,11 @@ this.element = element; | ||
rotation: [0,0,0], | ||
position: [0,0,0] | ||
// transformOrigin: [], | ||
position: [0,0,0], | ||
// transformOrigin: [0,0,0] | ||
// skew: [], | ||
}; | ||
window.addEventListener('scroll', function (e) { return this$1.onScroll(e); }); | ||
window.addEventListener('resize', function (e) { return this$1.onResize(e); }); | ||
// window.addEventListener('scroll', () => this.onScroll(), { passive: true }); | ||
// window.addEventListener('resize', () => this.onResize(), { passive: true }); | ||
window.addEventListener('scroll', this.onScroll.bind(this), { passive: true }); | ||
window.addEventListener('resize', this.onResize.bind(this), { passive: true }); | ||
}; | ||
@@ -302,52 +344,54 @@ | ||
* | ||
* start: (required) When to start the effect. It is a 0 - 1 value | ||
* representing the percentage of the viewport (eg. 0.5). | ||
* Any effects in the Scene will begin when the trigger element | ||
* crosses this threshold. | ||
* start: (required) When to start the effect. It is a 0 - 1 value | ||
* representing the percentage of the viewport (eg. 0.5). | ||
* Any effects in the Scene will begin when the trigger element | ||
* crosses this threshold. | ||
* | ||
* duration: The length of the effect, in pixels. Scrollify will | ||
* interpolate that into value into a "progress" variable, bounded | ||
* by 0 - 1. If not supplied, the default value is the height of the | ||
* viewport + element height, meaning the effect will last for as | ||
* long as the element is visible. | ||
*duration: The length of the effect, in pixels. Scrollify will | ||
* interpolate that into value into a "progress" variable, bounded | ||
* by 0 - 1. If not supplied, the default value is the height of | ||
* the viewport + element height, meaning the effect will last for | ||
* as long as the element is visible. | ||
* | ||
* trigger: If supplied, Scrollify will use this element's position to | ||
* start any Scene effects. If not supplied, the default is to use | ||
* the element itself as a trigger. | ||
* start any Scene effects. If not supplied, the default is to use | ||
* the element itself as a trigger. | ||
* | ||
* easing: Ease in/out of an effect. Any value from Robert Penner's easing | ||
* functions is valid. | ||
* easing: Ease in/out of any effects in the Scene. | ||
* | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.addScene = function addScene (opts) { | ||
Scrollify$1.prototype.addScene = function addScene (opts) { | ||
var this$1 = this; | ||
var triggerPos = opts.start || 0; | ||
var duration = opts.duration || window.innerHeight + this.element.offsetHeight; | ||
var trigger = opts.trigger ? opts.trigger instanceof HTMLElement ? opts.trigger : document.querySelector(opts.trigger) : this.element; | ||
var easing = opts.easing || false; | ||
var effects = opts.effects || []; | ||
var trigger = opts.trigger ? opts.trigger instanceof HTMLElement ? opts.trigger : document.querySelector(opts.trigger) : this.element; | ||
var applyTransform = opts.applyTransform !== undefined ? opts.applyTransform : true; // opt out rather than opt in | ||
var scene = { | ||
trigger: trigger, | ||
triggerPos: 1 - triggerPos, | ||
duration: duration, | ||
_trigger: trigger, // keep for internal calculations | ||
_applyTransform: false, // internal-use only. Whether to use matrix transforms or not. Perhaps should be moved to *effect* level | ||
_offset: opts.start || 0, // store original value for later calcs | ||
_duration: opts.duration || 1, // store original value for later calculations | ||
// start: 0, // absolute value in px. Some percentage of the viewport | ||
// duration: duration, // absolute value in px. Some percentage of the viewport | ||
easing: easing, | ||
applyTransform: applyTransform, | ||
effects: [] | ||
}; | ||
// scene.active = this.scroll > this.calculateStart(scene); // calculate any transformations if the scene has already passed. | ||
effects.map(function (effect) { | ||
this$1.addEffect(effect.fn, effect.options, scene); | ||
}); | ||
this.calculateStart(scene); | ||
scene.state = (this.scroll > this.start) ? (this.scroll > this.start+duration) ? 'after' : 'active' : 'before'; | ||
this.calculateDuration(scene); | ||
effects.map(function (effect) { | ||
this$1.addEffect(effect.name, effect.options, scene); | ||
}); | ||
scene.state = (this.scroll > this.start) ? (this.scroll > this.start+scene.duration) ? 'after' : 'active' : 'before'; | ||
this.updateScene(scene); | ||
this.calculate(scene); | ||
this.scenes.push(scene); | ||
if (opts.debug) { | ||
console.log('Scrollify scene: ', scene); | ||
} | ||
return this; | ||
@@ -361,4 +405,5 @@ }; | ||
*/ | ||
Scrollify.prototype.updateScene = function updateScene (scene) { | ||
Scrollify$1.prototype.updateScene = function updateScene (scene) { | ||
this.calculateStart(scene); | ||
this.calculateDuration(scene); | ||
this.calculate(scene); | ||
@@ -374,3 +419,3 @@ }; | ||
*/ | ||
Scrollify.prototype.addEffect = function addEffect (effect, options, scene) { | ||
Scrollify$1.prototype.addEffect = function addEffect (fn, options, scene) { | ||
if ( options === void 0 ) options = {}; | ||
@@ -380,2 +425,3 @@ | ||
var transforms = this.transforms; | ||
var context = { options: options, element: element, transforms: transforms }; | ||
@@ -389,3 +435,3 @@ if (!scene) { | ||
return this.addScene({ | ||
'effects': [{'name': effect, 'options': options}] | ||
'effects': [{'fn': fn, 'options': options}] | ||
}); | ||
@@ -395,16 +441,6 @@ } | ||
var curry = function (fn, options) { | ||
return function() { // NOTE: don't use => function here as we do NOT want to bind "this" | ||
var context = { | ||
'options': options, | ||
'element': element, | ||
'transforms': transforms | ||
}; | ||
// if any effect uses a matrix tranformation, we use true for the entire scene | ||
scene._applyTransform = scene._applyTransform || fn._applyTransform; | ||
scene.effects.push(fn.bind(context)); | ||
fn.call(context, this); // eslint-disable-line | ||
}; | ||
}; | ||
scene.effects.push(curry(effect, options)); | ||
return this; | ||
@@ -415,8 +451,8 @@ }; | ||
* Calculate the start point of each scene. | ||
* @param{[type]} scene A Scrollify Scene object. | ||
* @param{Scrollify.Scene} scene A Scrollify Scene object. | ||
* @return {Integer} The start position of the Scene, in pixels. | ||
*/ | ||
Scrollify.prototype.calculateStart = function calculateStart (scene) { | ||
var trigger = scene.trigger; | ||
var triggerPos = scene.triggerPos; | ||
Scrollify$1.prototype.calculateStart = function calculateStart (scene) { | ||
var offset = window.innerHeight - this.mapTo(scene._offset, window.innerHeight); | ||
var trigger = scene._trigger; | ||
var top = 0; | ||
@@ -428,13 +464,42 @@ | ||
} while(trigger); | ||
// top = trigger.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); | ||
// var test = trigger.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); | ||
// return Math.max(0, top - triggerPos * window.innerHeight); // (can be negative...?) | ||
scene.start = Math.max(0, top - triggerPos * window.innerHeight); | ||
scene.start = Math.max(0, top - offset); | ||
}; | ||
/** | ||
* [mapTo description] | ||
* @param{[type]} input [description] | ||
* @param{[type]} scale [description] | ||
* @return {[type]} [description] | ||
*/ | ||
Scrollify$1.prototype.mapTo = function mapTo (input, scale) { | ||
var parsed = parseFloat(input); | ||
var unit = getUnit(input); | ||
switch (unit) { | ||
case 'px': | ||
return parsed; | ||
case '%': | ||
return parsed / 100.0 * scale; | ||
default: | ||
return parsed * scale; | ||
} | ||
}; | ||
/** | ||
* [calculateDuration description] | ||
* @param{[type]} scene [description] | ||
* @return [type] [description] | ||
*/ | ||
Scrollify$1.prototype.calculateDuration = function calculateDuration (scene) { | ||
// if (typeof scene._duration === 'function') { return scene._duration(); } | ||
scene.duration = this.mapTo(scene._duration, window.innerHeight + this.element.offsetHeight); | ||
}; | ||
/** | ||
* onScroll Handler | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.onScroll = function onScroll () { | ||
Scrollify$1.prototype.onScroll = function onScroll () { | ||
if (!this.active) { return; } | ||
@@ -453,3 +518,3 @@ this.scroll = window.scrollY || window.pageYOffset; | ||
*/ | ||
Scrollify.prototype.onResize = function onResize () { | ||
Scrollify$1.prototype.onResize = function onResize () { | ||
this.scenes.forEach(this.updateScene, this); | ||
@@ -462,3 +527,3 @@ }; | ||
*/ | ||
Scrollify.prototype.update = function update () { | ||
Scrollify$1.prototype.update = function update () { | ||
this.scenes.forEach(this.calculate, this); | ||
@@ -475,3 +540,3 @@ this.ticking = false; | ||
*/ | ||
Scrollify.prototype.calculate = function calculate (scene) { | ||
Scrollify$1.prototype.calculate = function calculate (scene) { | ||
var start = scene.start; | ||
@@ -481,3 +546,2 @@ var duration = scene.duration; | ||
var progress; | ||
var matrix; | ||
@@ -514,9 +578,9 @@ // after end | ||
scene.effects.forEach(function (effect) { | ||
effect.call(progress); | ||
effect(progress); | ||
}); | ||
if (scene.applyTransform) { | ||
if (scene._applyTransform) { | ||
// transmogrify all applied transformations into a single matrix, and apply | ||
matrix = this.updateMatrix(); | ||
this.element.style[transform] = matrix.asCSS(); | ||
var matrix = this.updateMatrix(); | ||
this.element.style[transform$1] = matrix.asCSS(); | ||
} | ||
@@ -529,3 +593,3 @@ }; | ||
*/ | ||
Scrollify.prototype.updateMatrix = function updateMatrix () { | ||
Scrollify$1.prototype.updateMatrix = function updateMatrix () { | ||
var t = this.transforms; | ||
@@ -559,18 +623,2 @@ var m = this.matrix; | ||
// ----------------------------------------------------- | ||
// IF we wished to perform rotation AFTER skew / position / etc, we could do it here. | ||
// The ordering is important, and has an effect. | ||
// if (t.rotationPost) { | ||
// m.rotateX(t.rotationPost[0]); | ||
// m.rotateY(t.rotationPost[1]); | ||
// m.rotateZ(t.rotationPost[2]); | ||
// } | ||
// if (t.scalePost) { | ||
// m.scale(t.scalePost[0], t.scalePost[1]); | ||
// } | ||
// ----------------------------------------------------- | ||
// ... and here we put it back. (This duplication is not a mistake). | ||
@@ -588,6 +636,423 @@ if (t.transformOrigin) { | ||
*/ | ||
Scrollify.prototype.disable = function disable () { | ||
Scrollify$1.prototype.disable = function disable () { | ||
this.active = false; | ||
}; | ||
export default Scrollify; | ||
/** | ||
* A list of some default "transformations" that may be applied | ||
* Options are applied at initialize and are curried in via "this". | ||
* | ||
* NOTE: for all functions herein, "this" contains effect options, a | ||
* transformation Object, and also a reference to the element. | ||
*/ | ||
/*global console*/ | ||
/*eslint no-invalid-this: "error"*/ | ||
// Effects that use matrix transformations. At present, only | ||
// built-in effects benefit from matrix transformations. | ||
[translateX, translateY, rotate, scale, parallax].forEach(function (fn) { | ||
fn._applyTransform = true; | ||
}); | ||
/** | ||
* Translate an element along the X-axis. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function translateX(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 0; | ||
var offset = (to - from) * progress + from; | ||
this.transforms.position[0] = offset; | ||
} | ||
/** | ||
* Translate an element vertically. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function translateY(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 0;// this.transforms.position[1]; | ||
var offset = (to - from) * progress + from; | ||
this.transforms.position[1] = offset; | ||
} | ||
// export function translate(progress) { | ||
// const to = this.options.to; | ||
// const from = this.options.from; | ||
// const offsetX = (to[0] - from[0]) * progress + from[0]; | ||
// const offsetY = (to[1] - from[1]) * progress + from[1]; | ||
// | ||
// this.transforms.position[0] = offsetX; | ||
// this.transforms.position[1] = offsetY; | ||
// } | ||
/** | ||
* Rotate an element, using radians. (note: rotates around Z-axis). | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function rotate(progress) { | ||
var radians = this.options.rad * progress; | ||
this.transforms.rotation[2] = radians; | ||
} | ||
/** | ||
* Uniformly scale an element along both axis'. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function scale(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 1; | ||
var from = (this.options.from !== undefined) ? this.options.from : this.transforms.scale[0]; | ||
var scale = (to - from) * progress + from; | ||
this.transforms.scale[0] = scale; | ||
this.transforms.scale[1] = scale; | ||
} | ||
/** | ||
* Update an element's opacity. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function fade(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 1; | ||
var opacity = (to - from) * progress + from; | ||
this.element.style.opacity = opacity; | ||
} | ||
/** | ||
* Update an element's blur. | ||
* @param {Float} progress Current progress of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function blur(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 0; | ||
var amount = (to - from) * progress + from; | ||
this.element.style.filter = 'blur(' + amount + 'px)'; | ||
} | ||
/** | ||
* Parallax an element. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function parallax(progress) { | ||
var range = this.options.range || 0; | ||
var offset = progress * range; // TODO add provision for speed as well | ||
this.transforms.position[1] = offset; // just vertical for now | ||
} | ||
/** | ||
* Toggle a class on or off. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function toggle(progress) { | ||
var opts = this.options; | ||
var element = this.element; | ||
var times = Object.keys(opts); | ||
times.forEach(function(time) { | ||
var css = opts[time]; | ||
if (progress > time) { | ||
element.classList.add(css); | ||
} else { | ||
element.classList.remove(css); | ||
} | ||
}); | ||
} | ||
/** | ||
* Sticky Element: sets up a sticky element which toggles position 'fixed' on / off. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function stick(progress) { | ||
var element = this.element; | ||
var currentState = '_'; | ||
if (progress <= 0) { | ||
setState(element, 'normal'); | ||
} else if (progress >= 1) { | ||
setState(element, 'bottom'); | ||
} else { | ||
setState(element, 'sticky'); | ||
} | ||
function setState(element, state) { | ||
var BCR = element.getBoundingClientRect(); | ||
if (currentState === state) { return; } | ||
if (state == 'sticky') { | ||
element.style.top = BCR.top + 'px'; | ||
element.style.left = BCR.left + 'px'; | ||
element.style.width = BCR.width + 'px'; | ||
} else { | ||
element.style.top = ''; | ||
element.style.left = ''; | ||
element.style.width = ''; | ||
} | ||
element.className = ''; | ||
// element.classList.remove(currentState); // TODO: why is this not working? | ||
element.classList.add(state); | ||
currentState = state; | ||
} | ||
} | ||
var effects = Object.freeze({ | ||
translateX: translateX, | ||
translateY: translateY, | ||
rotate: rotate, | ||
scale: scale, | ||
fade: fade, | ||
blur: blur, | ||
parallax: parallax, | ||
toggle: toggle, | ||
stick: stick | ||
}); | ||
/*eslint max-len: ["error", 120]*/ | ||
function oscillate(t, b, c, d) { | ||
var i = 4; // # of bounces | ||
t /= d; // percentage | ||
t = Math.PI * i * t; // go from 0 -> 2π | ||
t = Math.sin(t) * c; // now, oscillates between c, -c | ||
t = Math.abs(t); // "half wave rectifier" | ||
return t + b; | ||
} | ||
function easeInQuad(t, b, c, d) { | ||
return c * (t /= d) * t + b; | ||
} | ||
function easeOutQuad(t, b, c, d) { | ||
return -c * (t /= d) * (t - 2) + b; | ||
} | ||
function easeInOutQuad(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t + b; } | ||
return -c / 2 * (--t * (t - 2) - 1) + b; | ||
} | ||
function easeInCubic(t, b, c, d) { | ||
return c * (t /= d) * t * t + b; | ||
} | ||
function easeOutCubic(t, b, c, d) { | ||
return c * ((t = t / d - 1) * t * t + 1) + b; | ||
} | ||
function easeInOutCubic(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t + b; } | ||
return c / 2 * ((t -= 2) * t * t + 2) + b; | ||
} | ||
function easeInQuart(t, b, c, d) { | ||
return c * (t /= d) * t * t * t + b; | ||
} | ||
function easeOutQuart(t, b, c, d) { | ||
return -c * ((t = t / d - 1) * t * t * t - 1) + b; | ||
} | ||
function easeInOutQuart(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t + b; } | ||
return -c / 2 * ((t -= 2) * t * t * t - 2) + b; | ||
} | ||
function easeInQuint(t, b, c, d) { | ||
return c * (t /= d) * t * t * t * t + b; | ||
} | ||
function easeOutQuint(t, b, c, d) { | ||
return c * ((t = t / d - 1) * t * t * t * t + 1) + b; | ||
} | ||
function easeInOutQuint(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t * t + b; } | ||
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; | ||
} | ||
function easeInSine(t, b, c, d) { | ||
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; | ||
} | ||
function easeOutSine(t, b, c, d) { | ||
return c * Math.sin(t / d * (Math.PI / 2)) + b; | ||
} | ||
function easeInOutSine(t, b, c, d) { | ||
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; | ||
} | ||
function easeInExpo(t, b, c, d) { | ||
return t == 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; | ||
} | ||
function easeOutExpo(t, b, c, d) { | ||
return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; | ||
} | ||
function easeInOutExpo(t, b, c, d) { | ||
if (t == 0) { return b; } | ||
if (t == d) { return b + c; } | ||
if ((t /= d / 2) < 1) { return c / 2 * Math.pow(2, 10 * (t - 1)) + b; } | ||
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; | ||
} | ||
function easeInCirc(t, b, c, d) { | ||
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; | ||
} | ||
function easeOutCirc(t, b, c, d) { | ||
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; | ||
} | ||
function easeInOutCirc(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; } | ||
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; | ||
} | ||
function easeInElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
if (t == 0) { return b; } | ||
if ((t /= d) == 1) { return b + c; } | ||
if (!p) { p = d * .3; } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
return -(a * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; | ||
} | ||
function easeOutElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
if (t == 0) { return b; } | ||
if ((t /= d) == 1) { return b + c; } | ||
if (!p) { p = d * .3; } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
return a * Math.pow(2,-10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b; | ||
} | ||
function easeInOutElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
if (t == 0) { return b; } | ||
if ((t /= d / 2) == 2) { return b + c; } | ||
if (!p) { p = d * (.3 * 1.5); } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
if (t < 1) { return -.5 * (a * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; } | ||
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b; | ||
} | ||
function easeInBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
return c * (t /= d) * t * ((s + 1) * t - s) + b; | ||
} | ||
function easeOutBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; | ||
} | ||
function easeInOutBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
if ((t /= d / 2) < 1) { return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b; } | ||
return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b; | ||
} | ||
function easeOutBounce(t, b, c, d) { | ||
if (t /= d < 1 / 2.75) { | ||
return c * (7.5625 * t * t) + b; | ||
} else if (t < 2 / 2.75) { | ||
return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b; | ||
} else if (t < 2.5 / 2.75) { | ||
return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b; | ||
} else { | ||
return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b; | ||
} | ||
} | ||
var easings = Object.freeze({ | ||
oscillate: oscillate, | ||
easeInQuad: easeInQuad, | ||
easeOutQuad: easeOutQuad, | ||
easeInOutQuad: easeInOutQuad, | ||
easeInCubic: easeInCubic, | ||
easeOutCubic: easeOutCubic, | ||
easeInOutCubic: easeInOutCubic, | ||
easeInQuart: easeInQuart, | ||
easeOutQuart: easeOutQuart, | ||
easeInOutQuart: easeInOutQuart, | ||
easeInQuint: easeInQuint, | ||
easeOutQuint: easeOutQuint, | ||
easeInOutQuint: easeInOutQuint, | ||
easeInSine: easeInSine, | ||
easeOutSine: easeOutSine, | ||
easeInOutSine: easeInOutSine, | ||
easeInExpo: easeInExpo, | ||
easeOutExpo: easeOutExpo, | ||
easeInOutExpo: easeInOutExpo, | ||
easeInCirc: easeInCirc, | ||
easeOutCirc: easeOutCirc, | ||
easeInOutCirc: easeInOutCirc, | ||
easeInElastic: easeInElastic, | ||
easeOutElastic: easeOutElastic, | ||
easeInOutElastic: easeInOutElastic, | ||
easeInBack: easeInBack, | ||
easeOutBack: easeOutBack, | ||
easeInOutBack: easeInOutBack, | ||
easeOutBounce: easeOutBounce | ||
}); | ||
/** | ||
* Put Scrollify into the Global scope. | ||
* Useful for existing demos or if you wish to include manually | ||
*/ | ||
export { Scrollify$1 as Scrollify, effects as fx, easings };export default Scrollify$1; |
(function () { | ||
'use strict'; | ||
'use strict'; | ||
/** | ||
* Feature detection: CSS transforms | ||
* @type {Boolean} | ||
*/ | ||
/** | ||
* Feature detection: CSS transforms | ||
* @type {Boolean} | ||
*/ | ||
var dummy = document.createElement('div'); | ||
var transform = ['transform', 'webkitTransform', 'MozTransform', 'OTransform', 'msTransform'].find(function (t) { | ||
// return (document.body.style[t] !== undefined); // if DOM is not yet ready, let's do: | ||
return (dummy.style[t] !== undefined); | ||
}); | ||
var transform; | ||
var dummy = document.createElement('div'); // we use this instead of document.body if the DOM is not yet ready | ||
function assignedMatrixMultiplication(a, b, res) { | ||
// Unrolled loop | ||
res[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12]; | ||
res[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13]; | ||
res[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14]; | ||
res[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15]; | ||
['transform', 'webkitTransform', 'MozTransform', 'OTransform', 'msTransform'].forEach(function (t) { | ||
if (dummy.style[t] !== undefined) { transform = t; } | ||
}); | ||
res[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12]; | ||
res[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13]; | ||
res[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14]; | ||
res[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15]; | ||
var transform$1 = transform; | ||
res[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12]; | ||
res[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13]; | ||
res[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14]; | ||
res[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15]; | ||
/* | ||
The MIT License (MIT) | ||
res[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12]; | ||
res[13] = a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13]; | ||
res[14] = a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14]; | ||
res[15] = a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15]; | ||
Copyright (c) 2015 Daniel Lundin | ||
return res; | ||
} | ||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
function assignTranslate(matrix, x, y, z) { | ||
matrix[0] = 1; | ||
matrix[1] = 0; | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = 1; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = x; | ||
matrix[13] = y; | ||
matrix[14] = z; | ||
matrix[15] = 1; | ||
} | ||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
function assignRotateX(matrix, rad) { | ||
matrix[0] = 1; | ||
matrix[1] = 0; | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = Math.cos(rad); | ||
matrix[6] = -Math.sin(rad); | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = Math.sin(rad); | ||
matrix[10] = Math.cos(rad); | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. | ||
*/ | ||
function assignedMatrixMultiplication(a, b, res) { | ||
// Unrolled loop | ||
res[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12]; | ||
res[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13]; | ||
res[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14]; | ||
res[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15]; | ||
var assignRotateY = function(matrix, rad) { | ||
matrix[0] = Math.cos(rad); | ||
matrix[1] = 0; | ||
matrix[2] = Math.sin(rad); | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = 1; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = -Math.sin(rad); | ||
matrix[9] = 0; | ||
matrix[10] = Math.cos(rad); | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
}; | ||
res[4] = a[4] * b[0] + a[5] * b[4] + a[6] * b[8] + a[7] * b[12]; | ||
res[5] = a[4] * b[1] + a[5] * b[5] + a[6] * b[9] + a[7] * b[13]; | ||
res[6] = a[4] * b[2] + a[5] * b[6] + a[6] * b[10] + a[7] * b[14]; | ||
res[7] = a[4] * b[3] + a[5] * b[7] + a[6] * b[11] + a[7] * b[15]; | ||
function assignRotateZ(matrix, rad) { | ||
matrix[0] = Math.cos(rad); | ||
matrix[1] = -Math.sin(rad); | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = Math.sin(rad); | ||
matrix[5] = Math.cos(rad); | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
res[8] = a[8] * b[0] + a[9] * b[4] + a[10] * b[8] + a[11] * b[12]; | ||
res[9] = a[8] * b[1] + a[9] * b[5] + a[10] * b[9] + a[11] * b[13]; | ||
res[10] = a[8] * b[2] + a[9] * b[6] + a[10] * b[10] + a[11] * b[14]; | ||
res[11] = a[8] * b[3] + a[9] * b[7] + a[10] * b[11] + a[11] * b[15]; | ||
function assignSkew(matrix, ax, ay) { | ||
matrix[0] = 1; | ||
matrix[1] = Math.tan(ax); | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = Math.tan(ay); | ||
matrix[5] = 1; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
res[12] = a[12] * b[0] + a[13] * b[4] + a[14] * b[8] + a[15] * b[12]; | ||
res[13] = a[12] * b[1] + a[13] * b[5] + a[14] * b[9] + a[15] * b[13]; | ||
res[14] = a[12] * b[2] + a[13] * b[6] + a[14] * b[10] + a[15] * b[14]; | ||
res[15] = a[12] * b[3] + a[13] * b[7] + a[14] * b[11] + a[15] * b[15]; | ||
return res; | ||
} | ||
function assignScale(matrix, x, y) { | ||
matrix[0] = x; | ||
matrix[1] = 0; | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = y; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
function assignTranslate(matrix, x, y, z) { | ||
matrix[0] = 1; | ||
matrix[1] = 0; | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = 1; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = x; | ||
matrix[13] = y; | ||
matrix[14] = z; | ||
matrix[15] = 1; | ||
} | ||
function assignIdentity(matrix) { | ||
matrix[0] = 1; | ||
matrix[1] = 0; | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = 1; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
function assignRotateX(matrix, rad) { | ||
matrix[0] = 1; | ||
matrix[1] = 0; | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = Math.cos(rad); | ||
matrix[6] = -Math.sin(rad); | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = Math.sin(rad); | ||
matrix[10] = Math.cos(rad); | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
function copyArray(a, b) { | ||
b[0] = a[0]; | ||
b[1] = a[1]; | ||
b[2] = a[2]; | ||
b[3] = a[3]; | ||
b[4] = a[4]; | ||
b[5] = a[5]; | ||
b[6] = a[6]; | ||
b[7] = a[7]; | ||
b[8] = a[8]; | ||
b[9] = a[9]; | ||
b[10] = a[10]; | ||
b[11] = a[11]; | ||
b[12] = a[12]; | ||
b[13] = a[13]; | ||
b[14] = a[14]; | ||
b[15] = a[15]; | ||
} | ||
function createMatrix() { | ||
var data = new Float32Array(16); | ||
var a = new Float32Array(16); | ||
var b = new Float32Array(16); | ||
assignIdentity(data); | ||
var assignRotateY = function(matrix, rad) { | ||
matrix[0] = Math.cos(rad); | ||
matrix[1] = 0; | ||
matrix[2] = Math.sin(rad); | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = 1; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = -Math.sin(rad); | ||
matrix[9] = 0; | ||
matrix[10] = Math.cos(rad); | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
}; | ||
return { | ||
data: data, | ||
function assignRotateZ(matrix, rad) { | ||
matrix[0] = Math.cos(rad); | ||
matrix[1] = -Math.sin(rad); | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = Math.sin(rad); | ||
matrix[5] = Math.cos(rad); | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
asCSS: function() { | ||
var css = 'matrix3d('; | ||
for (var i = 0; i < 15; ++i) { | ||
if (Math.abs(data[i]) < 0.0001) { | ||
css += '0,'; | ||
} else { | ||
css += data[i].toFixed(10) + ','; | ||
} | ||
} | ||
if (Math.abs(data[15]) < 0.0001) { | ||
css += '0)'; | ||
} else { | ||
css += data[15].toFixed(10) + ')'; | ||
} | ||
return css; | ||
}, | ||
function assignSkew(matrix, ax, ay) { | ||
matrix[0] = 1; | ||
matrix[1] = Math.tan(ax); | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = Math.tan(ay); | ||
matrix[5] = 1; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
clear: function() { | ||
assignIdentity(data); | ||
}, | ||
translate: function(x, y, z) { | ||
copyArray(data, a); | ||
assignTranslate(b, x, y, z); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
}, | ||
function assignScale(matrix, x, y) { | ||
matrix[0] = x; | ||
matrix[1] = 0; | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = y; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
rotateX: function(radians) { | ||
copyArray(data, a); | ||
assignRotateX(b, radians); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
}, | ||
function assignIdentity(matrix) { | ||
matrix[0] = 1; | ||
matrix[1] = 0; | ||
matrix[2] = 0; | ||
matrix[3] = 0; | ||
matrix[4] = 0; | ||
matrix[5] = 1; | ||
matrix[6] = 0; | ||
matrix[7] = 0; | ||
matrix[8] = 0; | ||
matrix[9] = 0; | ||
matrix[10] = 1; | ||
matrix[11] = 0; | ||
matrix[12] = 0; | ||
matrix[13] = 0; | ||
matrix[14] = 0; | ||
matrix[15] = 1; | ||
} | ||
rotateY: function(radians) { | ||
copyArray(data, a); | ||
assignRotateY(b, radians); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
}, | ||
function copyArray(a, b) { | ||
b[0] = a[0]; | ||
b[1] = a[1]; | ||
b[2] = a[2]; | ||
b[3] = a[3]; | ||
b[4] = a[4]; | ||
b[5] = a[5]; | ||
b[6] = a[6]; | ||
b[7] = a[7]; | ||
b[8] = a[8]; | ||
b[9] = a[9]; | ||
b[10] = a[10]; | ||
b[11] = a[11]; | ||
b[12] = a[12]; | ||
b[13] = a[13]; | ||
b[14] = a[14]; | ||
b[15] = a[15]; | ||
} | ||
rotateZ: function(radians) { | ||
copyArray(data, a); | ||
assignRotateZ(b, radians); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
}, | ||
function createMatrix() { | ||
var data = new Float32Array(16); | ||
var a = new Float32Array(16); | ||
var b = new Float32Array(16); | ||
assignIdentity(data); | ||
scale: function(x, y) { | ||
copyArray(data, a); | ||
assignScale(b, x, y); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
}, | ||
return { | ||
data: data, | ||
skew: function(ax, ay) { | ||
asCSS: function() { | ||
var css = 'matrix3d('; | ||
for (var i = 0; i < 15; ++i) { | ||
if (Math.abs(data[i]) < 0.0001) { | ||
css += '0,'; | ||
} else { | ||
css += data[i].toFixed(10) + ','; | ||
} | ||
} | ||
if (Math.abs(data[15]) < 0.0001) { | ||
css += '0)'; | ||
} else { | ||
css += data[15].toFixed(10) + ')'; | ||
} | ||
return css; | ||
}, | ||
clear: function() { | ||
assignIdentity(data); | ||
}, | ||
translate: function(x, y, z) { | ||
copyArray(data, a); | ||
assignSkew(b, ax, ay); | ||
assignTranslate(b, x, y, z); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
} | ||
}; | ||
} | ||
}, | ||
/** | ||
* The Scrollify Class | ||
*/ | ||
var Scrollify = function Scrollify(element) { | ||
var this$1 = this; | ||
rotateX: function(radians) { | ||
copyArray(data, a); | ||
assignRotateX(b, radians); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
}, | ||
if (element instanceof HTMLElement == false) { element = document.querySelector(element); } | ||
if (!element || !transform) { return this.active = false; } | ||
// if (!transform) { throw 'Scrollify [error]: transforms not supported'; } | ||
// if (!element) { throw 'Scrollify [error]: could not find element'; } | ||
rotateY: function(radians) { | ||
copyArray(data, a); | ||
assignRotateY(b, radians); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
}, | ||
this.element = element; | ||
this.ticking = false; | ||
this.scenes = []; | ||
this.scroll = window.scrollY || window.pageYOffset; | ||
this.active = true; | ||
this.matrix = createMatrix(); | ||
this.transforms = { | ||
scale: [1,1], | ||
rotation: [0,0,0], | ||
position: [0,0,0] | ||
// transformOrigin: [], | ||
// skew: [], | ||
}; | ||
rotateZ: function(radians) { | ||
copyArray(data, a); | ||
assignRotateZ(b, radians); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
}, | ||
window.addEventListener('scroll', function (e) { return this$1.onScroll(e); }); | ||
window.addEventListener('resize', function (e) { return this$1.onResize(e); }); | ||
scale: function(x, y) { | ||
copyArray(data, a); | ||
assignScale(b, x, y); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
}, | ||
skew: function(ax, ay) { | ||
copyArray(data, a); | ||
assignSkew(b, ax, ay); | ||
assignedMatrixMultiplication(a, b, data); | ||
return this; | ||
} | ||
}; | ||
} | ||
/** | ||
* Add a new Scene to the Scrollify object. Scene information includes when | ||
* to start applying an effect and for how long. | ||
* @param{Object} opts: Various options to apply to the new Scene: | ||
* | ||
* start: (required) When to start the effect. It is a 0 - 1 value | ||
* representing the percentage of the viewport (eg. 0.5). | ||
* Any effects in the Scene will begin when the trigger element | ||
* crosses this threshold. | ||
* | ||
* duration: The length of the effect, in pixels. Scrollify will | ||
* interpolate that into value into a "progress" variable, bounded | ||
* by 0 - 1. If not supplied, the default value is the height of the | ||
* viewport + element height, meaning the effect will last for as | ||
* long as the element is visible. | ||
* | ||
* trigger: If supplied, Scrollify will use this element's position to | ||
* start any Scene effects. If not supplied, the default is to use | ||
* the element itself as a trigger. | ||
* | ||
* easing: Ease in/out of an effect. Any value from Robert Penner's easing | ||
* functions is valid. | ||
* | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.addScene = function addScene (opts) { | ||
var this$1 = this; | ||
function getUnit(val) { | ||
var split = /([\+\-]?[0-9#\.]+)(%|px|pt|em|rem|in|cm|mm|ex|pc|vw|vh|deg|rad|turn)?/.exec(val); | ||
if (split) return split[2]; | ||
} | ||
var triggerPos = opts.start || 0; | ||
var duration = opts.duration || window.innerHeight + this.element.offsetHeight; | ||
var easing = opts.easing || false; | ||
var effects = opts.effects || []; | ||
var trigger = opts.trigger ? opts.trigger instanceof HTMLElement ? opts.trigger : document.querySelector(opts.trigger) : this.element; | ||
var applyTransform = opts.applyTransform !== undefined ? opts.applyTransform : true; // opt out rather than opt in | ||
var scene = { | ||
trigger: trigger, | ||
triggerPos: 1 - triggerPos, | ||
duration: duration, | ||
easing: easing, | ||
applyTransform: applyTransform, | ||
effects: [] | ||
}; | ||
/* | ||
* scrollify | ||
* https://github.com/apathetic/scrollify | ||
* | ||
* Copyright (c) 2016, 2017 Wes Hatch | ||
* Licensed under the MIT license. | ||
* | ||
*/ | ||
// scene.active = this.scroll > this.calculateStart(scene); // calculate any transformations if the scene has already passed. | ||
/** | ||
* The Scrollify Class | ||
*/ | ||
var Scrollify = function Scrollify(element) { | ||
if (element instanceof HTMLElement == false) { element = document.querySelector(element); } | ||
if (!element || !transform$1) { | ||
console.log('Scrollify [error] ', arguments[0]); | ||
return this.disable(); | ||
} | ||
this.calculateStart(scene); | ||
scene.state = (this.scroll > this.start) ? (this.scroll > this.start+duration) ? 'after' : 'active' : 'before'; | ||
this.element = element; | ||
this.ticking = false; | ||
this.scenes = []; | ||
this.scroll = window.scrollY || window.pageYOffset; | ||
this.active = true; | ||
this.matrix = createMatrix(); | ||
this.transforms = { | ||
scale: [1,1], | ||
rotation: [0,0,0], | ||
position: [0,0,0], | ||
// transformOrigin: [0,0,0] | ||
// skew: [], | ||
}; | ||
effects.map(function (effect) { | ||
this$1.addEffect(effect.name, effect.options, scene); | ||
}); | ||
// window.addEventListener('scroll', () => this.onScroll(), { passive: true }); | ||
// window.addEventListener('resize', () => this.onResize(), { passive: true }); | ||
window.addEventListener('scroll', this.onScroll.bind(this), { passive: true }); | ||
window.addEventListener('resize', this.onResize.bind(this), { passive: true }); | ||
}; | ||
this.updateScene(scene); | ||
this.scenes.push(scene); | ||
/** | ||
* Add a new Scene to the Scrollify object. Scene information includes when | ||
* to start applying an effect and for how long. | ||
* @param{Object} opts: Various options to apply to the new Scene: | ||
* | ||
* start: (required) When to start the effect. It is a 0 - 1 value | ||
* representing the percentage of the viewport (eg. 0.5). | ||
* Any effects in the Scene will begin when the trigger element | ||
* crosses this threshold. | ||
* | ||
*duration: The length of the effect, in pixels. Scrollify will | ||
* interpolate that into value into a "progress" variable, bounded | ||
* by 0 - 1. If not supplied, the default value is the height of | ||
* the viewport + element height, meaning the effect will last for | ||
* as long as the element is visible. | ||
* | ||
* trigger: If supplied, Scrollify will use this element's position to | ||
* start any Scene effects. If not supplied, the default is to use | ||
* the element itself as a trigger. | ||
* | ||
* easing: Ease in/out of any effects in the Scene. | ||
* | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.addScene = function addScene (opts) { | ||
var this$1 = this; | ||
return this; | ||
var trigger = opts.trigger ? opts.trigger instanceof HTMLElement ? opts.trigger : document.querySelector(opts.trigger) : this.element; | ||
var easing = opts.easing || false; | ||
var effects = opts.effects || []; | ||
var scene = { | ||
_trigger: trigger, // keep for internal calculations | ||
_applyTransform: false, // internal-use only. Whether to use matrix transforms or not. Perhaps should be moved to *effect* level | ||
_offset: opts.start || 0, // store original value for later calcs | ||
_duration: opts.duration || 1, // store original value for later calculations | ||
// start: 0, // absolute value in px. Some percentage of the viewport | ||
// duration: duration, // absolute value in px. Some percentage of the viewport | ||
easing: easing, | ||
effects: [] | ||
}; | ||
/** | ||
* Update each scene. | ||
* @param{Object} scene: The scene to update. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.updateScene = function updateScene (scene) { | ||
this.calculateStart(scene); | ||
this.calculate(scene); | ||
}; | ||
effects.map(function (effect) { | ||
this$1.addEffect(effect.fn, effect.options, scene); | ||
}); | ||
/** | ||
* Add a particular transformation to a scene. | ||
* @param{Function} effect: The transformation function to apply. | ||
* @param{Object} options: Any transformation options. | ||
* @param{Object} scene: Object containing start and duration information. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.addEffect = function addEffect (effect, options, scene) { | ||
if ( options === void 0 ) options = {}; | ||
this.calculateStart(scene); | ||
this.calculateDuration(scene); | ||
var element = this.element; | ||
var transforms = this.transforms; | ||
scene.state = (this.scroll > this.start) ? (this.scroll > this.start+scene.duration) ? 'after' : 'active' : 'before'; | ||
if (!scene) { | ||
if (this.scenes.length) { | ||
// use the most recently added scene | ||
scene = this.scenes[this.scenes.length - 1]; | ||
} else { | ||
// or if no scene (ie "addEffect" was called directly on Scrollify), set up a default one | ||
return this.addScene({ | ||
'effects': [{'name': effect, 'options': options}] | ||
}); | ||
} | ||
} | ||
this.calculate(scene); | ||
this.scenes.push(scene); | ||
var curry = function (fn, options) { | ||
return function() { // NOTE: don't use => function here as we do NOT want to bind "this" | ||
var context = { | ||
'options': options, | ||
'element': element, | ||
'transforms': transforms | ||
}; | ||
if (opts.debug) { | ||
console.log('Scrollify scene: ', scene); | ||
} | ||
fn.call(context, this); // eslint-disable-line | ||
}; | ||
}; | ||
return this; | ||
}; | ||
scene.effects.push(curry(effect, options)); | ||
/** | ||
* Update each scene. | ||
* @param{Object} scene: The scene to update. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.updateScene = function updateScene (scene) { | ||
this.calculateStart(scene); | ||
this.calculateDuration(scene); | ||
this.calculate(scene); | ||
}; | ||
return this; | ||
}; | ||
/** | ||
* Add a particular transformation to a scene. | ||
* @param{Function} effect: The transformation function to apply. | ||
* @param{Object} options: Any transformation options. | ||
* @param{Object} scene: Object containing start and duration information. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.addEffect = function addEffect (fn, options, scene) { | ||
if ( options === void 0 ) options = {}; | ||
/** | ||
* Calculate the start point of each scene. | ||
* @param{[type]} scene A Scrollify Scene object. | ||
* @return {Integer} The start position of the Scene, in pixels. | ||
*/ | ||
Scrollify.prototype.calculateStart = function calculateStart (scene) { | ||
var trigger = scene.trigger; | ||
var triggerPos = scene.triggerPos; | ||
var top = 0; | ||
var element = this.element; | ||
var transforms = this.transforms; | ||
var context = { options: options, element: element, transforms: transforms }; | ||
do { | ||
top += trigger.offsetTop || 0; | ||
trigger = trigger.offsetParent; | ||
} while(trigger); | ||
// top = trigger.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); | ||
if (!scene) { | ||
if (this.scenes.length) { | ||
// use the most recently added scene | ||
scene = this.scenes[this.scenes.length - 1]; | ||
} else { | ||
// or if no scene (ie "addEffect" was called directly on Scrollify), set up a default one | ||
return this.addScene({ | ||
'effects': [{'fn': fn, 'options': options}] | ||
}); | ||
} | ||
} | ||
// return Math.max(0, top - triggerPos * window.innerHeight); // (can be negative...?) | ||
scene.start = Math.max(0, top - triggerPos * window.innerHeight); | ||
}; | ||
// if any effect uses a matrix tranformation, we use true for the entire scene | ||
scene._applyTransform = scene._applyTransform || fn._applyTransform; | ||
scene.effects.push(fn.bind(context)); | ||
/** | ||
* onScroll Handler | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.onScroll = function onScroll () { | ||
if (!this.active) { return; } | ||
this.scroll = window.scrollY || window.pageYOffset; | ||
return this; | ||
}; | ||
if (!this.ticking) { | ||
window.requestAnimationFrame(this.update.bind(this)); | ||
this.ticking = true; | ||
} | ||
}; | ||
/** | ||
* Calculate the start point of each scene. | ||
* @param{Scrollify.Scene} scene A Scrollify Scene object. | ||
* @return {Integer} The start position of the Scene, in pixels. | ||
*/ | ||
Scrollify.prototype.calculateStart = function calculateStart (scene) { | ||
var offset = window.innerHeight - this.mapTo(scene._offset, window.innerHeight); | ||
var trigger = scene._trigger; | ||
var top = 0; | ||
/** | ||
* onResize Handler | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.onResize = function onResize () { | ||
this.scenes.forEach(this.updateScene, this); | ||
}; | ||
do { | ||
top += trigger.offsetTop || 0; | ||
trigger = trigger.offsetParent; | ||
} while(trigger); | ||
// var test = trigger.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); | ||
/** | ||
* Update the transformations for every scene. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.update = function update () { | ||
this.scenes.forEach(this.calculate, this); | ||
this.ticking = false; | ||
}; | ||
scene.start = Math.max(0, top - offset); | ||
}; | ||
/** | ||
* Calculate the transformations for each scene. | ||
* @param{Object} scene: An Object containing start and duration | ||
* information as well as an Array of | ||
* transformations to apply. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.calculate = function calculate (scene) { | ||
var start = scene.start; | ||
var duration = scene.duration; | ||
var scroll = this.scroll; | ||
var progress; | ||
var matrix; | ||
/** | ||
* [mapTo description] | ||
* @param{[type]} input [description] | ||
* @param{[type]} scale [description] | ||
* @return {[type]} [description] | ||
*/ | ||
Scrollify.prototype.mapTo = function mapTo (input, scale) { | ||
var parsed = parseFloat(input); | ||
var unit = getUnit(input); | ||
// after end | ||
if (scroll - start > duration) { | ||
if (scene.state !== 'after') { // do one final iteration | ||
scene.state = 'after'; | ||
progress = 1; | ||
} else { | ||
return; | ||
} | ||
switch (unit) { | ||
case 'px': | ||
return parsed; | ||
case '%': | ||
return parsed / 100.0 * scale; | ||
default: | ||
return parsed * scale; | ||
} | ||
}; | ||
// before start | ||
} else if (scroll - start < 0) { | ||
if (scene.state !== 'before') { // do one final iteration | ||
scene.state = 'before'; | ||
progress = 0; | ||
} else { | ||
return; | ||
} | ||
/** | ||
* [calculateDuration description] | ||
* @param{[type]} scene [description] | ||
* @return [type] [description] | ||
*/ | ||
Scrollify.prototype.calculateDuration = function calculateDuration (scene) { | ||
// if (typeof scene._duration === 'function') { return scene._duration(); } | ||
scene.duration = this.mapTo(scene._duration, window.innerHeight + this.element.offsetHeight); | ||
}; | ||
// active | ||
} else { | ||
scene.state = 'active'; | ||
if (scene.easing) { // start, from, to, end | ||
progress = scene.easing(scroll - start, 0, 1, duration); | ||
} else { | ||
progress = (scroll - start) / duration; | ||
} | ||
} | ||
/** | ||
* onScroll Handler | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.onScroll = function onScroll () { | ||
if (!this.active) { return; } | ||
this.scroll = window.scrollY || window.pageYOffset; | ||
// cycle through any registered transformations | ||
scene.effects.forEach(function (effect) { | ||
effect.call(progress); | ||
}); | ||
if (!this.ticking) { | ||
window.requestAnimationFrame(this.update.bind(this)); | ||
this.ticking = true; | ||
} | ||
}; | ||
if (scene.applyTransform) { | ||
// transmogrify all applied transformations into a single matrix, and apply | ||
matrix = this.updateMatrix(); | ||
this.element.style[transform] = matrix.asCSS(); | ||
} | ||
}; | ||
/** | ||
* onResize Handler | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.onResize = function onResize () { | ||
this.scenes.forEach(this.updateScene, this); | ||
}; | ||
/** | ||
* Loop through all the element's transformation data and calculates a matrix representing it. | ||
* @return {Matrix} Ye olde Matrix | ||
*/ | ||
Scrollify.prototype.updateMatrix = function updateMatrix () { | ||
var t = this.transforms; | ||
var m = this.matrix; | ||
/** | ||
* Update the transformations for every scene. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.update = function update () { | ||
this.scenes.forEach(this.calculate, this); | ||
this.ticking = false; | ||
}; | ||
m.clear(); | ||
/** | ||
* Calculate the transformations for each scene. | ||
* @param{Object} scene: An Object containing start and duration | ||
* information as well as an Array of | ||
* transformations to apply. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.calculate = function calculate (scene) { | ||
var start = scene.start; | ||
var duration = scene.duration; | ||
var scroll = this.scroll; | ||
var progress; | ||
// here we adjust the transformOrigin ... | ||
if (t.transformOrigin) { | ||
m.translate(-t.transformOrigin[0], -t.transformOrigin[1], -t.transformOrigin[2]); | ||
// after end | ||
if (scroll - start > duration) { | ||
if (scene.state !== 'after') { // do one final iteration | ||
scene.state = 'after'; | ||
progress = 1; | ||
} else { | ||
return; | ||
} | ||
if (t.scale) { | ||
m.scale(t.scale[0], t.scale[1]); | ||
// before start | ||
} else if (scroll - start < 0) { | ||
if (scene.state !== 'before') { // do one final iteration | ||
scene.state = 'before'; | ||
progress = 0; | ||
} else { | ||
return; | ||
} | ||
if (t.skew) { | ||
m.skew(t.skew[0], t.skew[1]); | ||
// active | ||
} else { | ||
scene.state = 'active'; | ||
if (scene.easing) { // start, from, to, end | ||
progress = scene.easing(scroll - start, 0, 1, duration); | ||
} else { | ||
progress = (scroll - start) / duration; | ||
} | ||
} | ||
if (t.rotation) { | ||
m.rotateX(t.rotation[0]); | ||
m.rotateY(t.rotation[1]); | ||
m.rotateZ(t.rotation[2]); | ||
} | ||
// cycle through any registered transformations | ||
scene.effects.forEach(function (effect) { | ||
effect(progress); | ||
}); | ||
if (t.position) { | ||
m.translate(t.position[0], t.position[1], t.position[2]); | ||
} | ||
if (scene._applyTransform) { | ||
// transmogrify all applied transformations into a single matrix, and apply | ||
var matrix = this.updateMatrix(); | ||
this.element.style[transform$1] = matrix.asCSS(); | ||
} | ||
}; | ||
// ----------------------------------------------------- | ||
// IF we wished to perform rotation AFTER skew / position / etc, we could do it here. | ||
// The ordering is important, and has an effect. | ||
/** | ||
* Loop through all the element's transformation data and calculates a matrix representing it. | ||
* @return {Matrix} Ye olde Matrix | ||
*/ | ||
Scrollify.prototype.updateMatrix = function updateMatrix () { | ||
var t = this.transforms; | ||
var m = this.matrix; | ||
// if (t.rotationPost) { | ||
// m.rotateX(t.rotationPost[0]); | ||
// m.rotateY(t.rotationPost[1]); | ||
// m.rotateZ(t.rotationPost[2]); | ||
// } | ||
m.clear(); | ||
// if (t.scalePost) { | ||
// m.scale(t.scalePost[0], t.scalePost[1]); | ||
// } | ||
// ----------------------------------------------------- | ||
// here we adjust the transformOrigin ... | ||
if (t.transformOrigin) { | ||
m.translate(-t.transformOrigin[0], -t.transformOrigin[1], -t.transformOrigin[2]); | ||
} | ||
if (t.scale) { | ||
m.scale(t.scale[0], t.scale[1]); | ||
} | ||
// ... and here we put it back. (This duplication is not a mistake). | ||
if (t.transformOrigin) { | ||
m.translate(t.transformOrigin[0], t.transformOrigin[1], t.transformOrigin[2]); | ||
} | ||
if (t.skew) { | ||
m.skew(t.skew[0], t.skew[1]); | ||
} | ||
return m; | ||
}; | ||
if (t.rotation) { | ||
m.rotateX(t.rotation[0]); | ||
m.rotateY(t.rotation[1]); | ||
m.rotateZ(t.rotation[2]); | ||
} | ||
/** | ||
* Disable Scrollify-ing. Perhaps for performance reasons / mobile devices. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.disable = function disable () { | ||
this.active = false; | ||
}; | ||
if (t.position) { | ||
m.translate(t.position[0], t.position[1], t.position[2]); | ||
} | ||
/** | ||
* Translate an element along the X-axis. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function translateX(progress) { | ||
var to = this.options.to || 0; | ||
var from = this.options.from || 0; | ||
var offset = (to - from) * progress + from; | ||
this.transforms.position[0] = offset; | ||
// ... and here we put it back. (This duplication is not a mistake). | ||
if (t.transformOrigin) { | ||
m.translate(t.transformOrigin[0], t.transformOrigin[1], t.transformOrigin[2]); | ||
} | ||
/** | ||
* Translate an element vertically. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function translateY(progress) { | ||
var to = this.options.to || 0; | ||
var from = this.options.from || 0; // this.transforms.position[1]; | ||
var offset = (to - from) * progress + from; | ||
return m; | ||
}; | ||
this.transforms.position[1] = offset; | ||
} | ||
/** | ||
* Disable Scrollify-ing. Perhaps for performance reasons / mobile devices. | ||
* @return {void} | ||
*/ | ||
Scrollify.prototype.disable = function disable () { | ||
this.active = false; | ||
}; | ||
/** | ||
* Rotate an element, using radians. (note: rotates around Z-axis). | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function rotate(progress) { | ||
var radians = this.options.rad * progress; | ||
/** | ||
* A list of some default "transformations" that may be applied | ||
* Options are applied at initialize and are curried in via "this". | ||
* | ||
* NOTE: for all functions herein, "this" contains effect options, a | ||
* transformation Object, and also a reference to the element. | ||
*/ | ||
this.transforms.rotation[2] = radians; | ||
}; | ||
/*global console*/ | ||
/*eslint no-invalid-this: "error"*/ | ||
/** | ||
* Uniformly scale an element along both axis'. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function scale(progress) { | ||
var to = this.options.to || 1; | ||
var from = this.options.from || this.transforms.scale[0]; | ||
var scale = (to - from) * progress + from; | ||
// Effects that use matrix transformations. At present, only | ||
// built-in effects benefit from matrix transformations. | ||
[translateX, translateY, rotate, scale, parallax].forEach(function (fn) { | ||
fn._applyTransform = true; | ||
}); | ||
this.transforms.scale[0] = scale; | ||
this.transforms.scale[1] = scale; | ||
}; | ||
/** | ||
* Update an element's opacity. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function fade(progress) { | ||
var to = this.options.to !== undefined ? this.options.to : 1; | ||
var from = this.options.from !== undefined ? this.options.from : 1; | ||
var opacity = (to - from) * progress + from; | ||
/** | ||
* Translate an element along the X-axis. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function translateX(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 0; | ||
var offset = (to - from) * progress + from; | ||
this.element.style.opacity = opacity; | ||
}; | ||
this.transforms.position[0] = offset; | ||
} | ||
/** | ||
* Parallax an element. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
* | ||
* "this" contains effect options and also a reference to the element. | ||
*/ | ||
function parallax(progress) { | ||
var offset = 0; | ||
var range = this.options.range || 0; | ||
/** | ||
* Translate an element vertically. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function translateY(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 0;// this.transforms.position[1]; | ||
var offset = (to - from) * progress + from; | ||
offset = progress * range; | ||
this.transforms.position[1] = offset; // just vertical for now | ||
} | ||
this.transforms.position[1] = offset; | ||
} | ||
/** | ||
* Toggle a class on or off. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function toggle(progress) { | ||
var opts = this.options; | ||
var element = this.element; | ||
var times = Object.keys(opts); | ||
// export function translate(progress) { | ||
// const to = this.options.to; | ||
// const from = this.options.from; | ||
// const offsetX = (to[0] - from[0]) * progress + from[0]; | ||
// const offsetY = (to[1] - from[1]) * progress + from[1]; | ||
// | ||
// this.transforms.position[0] = offsetX; | ||
// this.transforms.position[1] = offsetY; | ||
// } | ||
times.forEach(function(time) { | ||
var css = opts[time]; | ||
/** | ||
* Rotate an element, using radians. (note: rotates around Z-axis). | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function rotate(progress) { | ||
var radians = this.options.rad * progress; | ||
if (progress > time) { | ||
element.classList.add(css); | ||
} else { | ||
element.classList.remove(css); | ||
} | ||
}); | ||
} | ||
this.transforms.rotation[2] = radians; | ||
} | ||
/** | ||
* Sticky Element: sets up a sticky element which toggles position 'fixed' on / off. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function stick(progress) { | ||
var element = this.element; | ||
var currentState = '_'; | ||
/** | ||
* Uniformly scale an element along both axis'. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function scale(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 1; | ||
var from = (this.options.from !== undefined) ? this.options.from : this.transforms.scale[0]; | ||
var scale = (to - from) * progress + from; | ||
// progress = Math.min(1.0, Math.max(0.0, progress)); | ||
this.transforms.scale[0] = scale; | ||
this.transforms.scale[1] = scale; | ||
} | ||
if (progress <= 0) { | ||
setState(element, 'normal'); | ||
} else if (progress >= 1) { | ||
setState(element, 'bottom'); | ||
/** | ||
* Update an element's opacity. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function fade(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 1; | ||
var opacity = (to - from) * progress + from; | ||
this.element.style.opacity = opacity; | ||
} | ||
/** | ||
* Update an element's blur. | ||
* @param {Float} progress Current progress of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function blur(progress) { | ||
var to = (this.options.to !== undefined) ? this.options.to : 0; | ||
var from = (this.options.from !== undefined) ? this.options.from : 0; | ||
var amount = (to - from) * progress + from; | ||
this.element.style.filter = 'blur(' + amount + 'px)'; | ||
} | ||
/** | ||
* Parallax an element. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function parallax(progress) { | ||
var range = this.options.range || 0; | ||
var offset = progress * range; // TODO add provision for speed as well | ||
this.transforms.position[1] = offset; // just vertical for now | ||
} | ||
/** | ||
* Toggle a class on or off. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function toggle(progress) { | ||
var opts = this.options; | ||
var element = this.element; | ||
var times = Object.keys(opts); | ||
times.forEach(function(time) { | ||
var css = opts[time]; | ||
if (progress > time) { | ||
element.classList.add(css); | ||
} else { | ||
setState(element, 'sticky'); | ||
element.classList.remove(css); | ||
} | ||
}); | ||
} | ||
function setState(element, state) { | ||
var BCR = element.getBoundingClientRect(); | ||
/** | ||
* Sticky Element: sets up a sticky element which toggles position 'fixed' on / off. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
function stick(progress) { | ||
var element = this.element; | ||
var currentState = '_'; | ||
if (currentState === state) { return; } | ||
if (state == 'sticky') { | ||
element.style.top = BCR.top + 'px'; | ||
element.style.left = BCR.left + 'px'; | ||
element.style.width = BCR.width + 'px'; | ||
} else { | ||
element.style.top = ''; | ||
element.style.left = ''; | ||
element.style.width = ''; | ||
} | ||
if (progress <= 0) { | ||
setState(element, 'normal'); | ||
} else if (progress >= 1) { | ||
setState(element, 'bottom'); | ||
} else { | ||
setState(element, 'sticky'); | ||
} | ||
element.className = ''; | ||
// element.classList.remove(currentState); // TODO: why is this not working? | ||
element.classList.add(state); | ||
function setState(element, state) { | ||
var BCR = element.getBoundingClientRect(); | ||
currentState = state; | ||
if (currentState === state) { return; } | ||
if (state == 'sticky') { | ||
element.style.top = BCR.top + 'px'; | ||
element.style.left = BCR.left + 'px'; | ||
element.style.width = BCR.width + 'px'; | ||
} else { | ||
element.style.top = ''; | ||
element.style.left = ''; | ||
element.style.width = ''; | ||
} | ||
// boundsParams = ["top", "left", "bottom", "right", "margin", "marginLeft", "marginRight", "marginTop", "marginBottom"]; | ||
element.className = ''; | ||
// element.classList.remove(currentState); // TODO: why is this not working? | ||
element.classList.add(state); | ||
currentState = state; | ||
} | ||
} | ||
var fx = Object.freeze({ | ||
translateX: translateX, | ||
translateY: translateY, | ||
rotate: rotate, | ||
scale: scale, | ||
fade: fade, | ||
parallax: parallax, | ||
toggle: toggle, | ||
stick: stick | ||
}); | ||
var fx = Object.freeze({ | ||
translateX: translateX, | ||
translateY: translateY, | ||
rotate: rotate, | ||
scale: scale, | ||
fade: fade, | ||
blur: blur, | ||
parallax: parallax, | ||
toggle: toggle, | ||
stick: stick | ||
}); | ||
/*eslint max-len: ["error", 120]*/ | ||
/*eslint max-len: ["error", 120]*/ | ||
function oscillate(t, b, c, d) { | ||
var i = 4; // # of bounces | ||
t /= d; // percentage | ||
t = Math.PI * i * t; // go from 0 -> 2π | ||
t = Math.sin(t) * c; // now, oscillates between c, -c | ||
t = Math.abs(t); // "half wave rectifier" | ||
return t + b; | ||
} | ||
function oscillate(t, b, c, d) { | ||
var i = 4; // # of bounces | ||
t /= d; // percentage | ||
t = Math.PI * i * t; // go from 0 -> 2π | ||
t = Math.sin(t) * c; // now, oscillates between c, -c | ||
t = Math.abs(t); // "half wave rectifier" | ||
return t + b; | ||
} | ||
function easeInQuad(t, b, c, d) { | ||
return c * (t /= d) * t + b; | ||
} | ||
function easeInQuad(t, b, c, d) { | ||
return c * (t /= d) * t + b; | ||
} | ||
function easeOutQuad(t, b, c, d) { | ||
return -c * (t /= d) * (t - 2) + b; | ||
} | ||
function easeOutQuad(t, b, c, d) { | ||
return -c * (t /= d) * (t - 2) + b; | ||
} | ||
function easeInOutQuad(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t + b; } | ||
return -c / 2 * (--t * (t - 2) - 1) + b; | ||
} | ||
function easeInOutQuad(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t + b; } | ||
return -c / 2 * (--t * (t - 2) - 1) + b; | ||
} | ||
function easeInCubic(t, b, c, d) { | ||
return c * (t /= d) * t * t + b; | ||
} | ||
function easeInCubic(t, b, c, d) { | ||
return c * (t /= d) * t * t + b; | ||
} | ||
function easeOutCubic(t, b, c, d) { | ||
return c * ((t = t / d - 1) * t * t + 1) + b; | ||
} | ||
function easeOutCubic(t, b, c, d) { | ||
return c * ((t = t / d - 1) * t * t + 1) + b; | ||
} | ||
function easeInOutCubic(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t + b; } | ||
return c / 2 * ((t -= 2) * t * t + 2) + b; | ||
} | ||
function easeInOutCubic(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t + b; } | ||
return c / 2 * ((t -= 2) * t * t + 2) + b; | ||
} | ||
function easeInQuart(t, b, c, d) { | ||
return c * (t /= d) * t * t * t + b; | ||
} | ||
function easeInQuart(t, b, c, d) { | ||
return c * (t /= d) * t * t * t + b; | ||
} | ||
function easeOutQuart(t, b, c, d) { | ||
return -c * ((t = t / d - 1) * t * t * t - 1) + b; | ||
} | ||
function easeOutQuart(t, b, c, d) { | ||
return -c * ((t = t / d - 1) * t * t * t - 1) + b; | ||
} | ||
function easeInOutQuart(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t + b; } | ||
return -c / 2 * ((t -= 2) * t * t * t - 2) + b; | ||
} | ||
function easeInOutQuart(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t + b; } | ||
return -c / 2 * ((t -= 2) * t * t * t - 2) + b; | ||
} | ||
function easeInQuint(t, b, c, d) { | ||
return c * (t /= d) * t * t * t * t + b; | ||
} | ||
function easeInQuint(t, b, c, d) { | ||
return c * (t /= d) * t * t * t * t + b; | ||
} | ||
function easeOutQuint(t, b, c, d) { | ||
return c * ((t = t / d - 1) * t * t * t * t + 1) + b; | ||
} | ||
function easeOutQuint(t, b, c, d) { | ||
return c * ((t = t / d - 1) * t * t * t * t + 1) + b; | ||
} | ||
function easeInOutQuint(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t * t + b; } | ||
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; | ||
} | ||
function easeInOutQuint(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return c / 2 * t * t * t * t * t + b; } | ||
return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; | ||
} | ||
function easeInSine(t, b, c, d) { | ||
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; | ||
} | ||
function easeInSine(t, b, c, d) { | ||
return -c * Math.cos(t / d * (Math.PI / 2)) + c + b; | ||
} | ||
function easeOutSine(t, b, c, d) { | ||
return c * Math.sin(t / d * (Math.PI / 2)) + b; | ||
} | ||
function easeOutSine(t, b, c, d) { | ||
return c * Math.sin(t / d * (Math.PI / 2)) + b; | ||
} | ||
function easeInOutSine(t, b, c, d) { | ||
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; | ||
} | ||
function easeInOutSine(t, b, c, d) { | ||
return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b; | ||
} | ||
function easeInExpo(t, b, c, d) { | ||
return t == 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; | ||
} | ||
function easeInExpo(t, b, c, d) { | ||
return t == 0 ? b : c * Math.pow(2, 10 * (t / d - 1)) + b; | ||
} | ||
function easeOutExpo(t, b, c, d) { | ||
return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; | ||
} | ||
function easeOutExpo(t, b, c, d) { | ||
return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; | ||
} | ||
function easeInOutExpo(t, b, c, d) { | ||
if (t == 0) { return b; } | ||
if (t == d) { return b + c; } | ||
if ((t /= d / 2) < 1) { return c / 2 * Math.pow(2, 10 * (t - 1)) + b; } | ||
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; | ||
} | ||
function easeInOutExpo(t, b, c, d) { | ||
if (t == 0) { return b; } | ||
if (t == d) { return b + c; } | ||
if ((t /= d / 2) < 1) { return c / 2 * Math.pow(2, 10 * (t - 1)) + b; } | ||
return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b; | ||
} | ||
function easeInCirc(t, b, c, d) { | ||
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; | ||
} | ||
function easeInCirc(t, b, c, d) { | ||
return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b; | ||
} | ||
function easeOutCirc(t, b, c, d) { | ||
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; | ||
} | ||
function easeOutCirc(t, b, c, d) { | ||
return c * Math.sqrt(1 - (t = t / d - 1) * t) + b; | ||
} | ||
function easeInOutCirc(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; } | ||
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; | ||
} | ||
function easeInOutCirc(t, b, c, d) { | ||
if ((t /= d / 2) < 1) { return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b; } | ||
return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b; | ||
} | ||
function easeInElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
function easeInElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
if (t == 0) { return b; } | ||
if ((t /= d) == 1) { return b + c; } | ||
if (!p) { p = d * .3; } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
return -(a * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; | ||
if (t == 0) { return b; } | ||
if ((t /= d) == 1) { return b + c; } | ||
if (!p) { p = d * .3; } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
return -(a * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; | ||
} | ||
function easeOutElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
function easeOutElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
if (t == 0) { return b; } | ||
if ((t /= d) == 1) { return b + c; } | ||
if (!p) { p = d * .3; } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
return a * Math.pow(2,-10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b; | ||
if (t == 0) { return b; } | ||
if ((t /= d) == 1) { return b + c; } | ||
if (!p) { p = d * .3; } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
return a * Math.pow(2,-10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b; | ||
} | ||
function easeInOutElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
function easeInOutElastic(t, b, c, d) { | ||
var s = 1.70158; | ||
var p = 0; | ||
var a = c; | ||
if (t == 0) { return b; } | ||
if ((t /= d / 2) == 2) { return b + c; } | ||
if (!p) { p = d * (.3 * 1.5); } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
if (t < 1) { return -.5 * (a * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; } | ||
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b; | ||
if (t == 0) { return b; } | ||
if ((t /= d / 2) == 2) { return b + c; } | ||
if (!p) { p = d * (.3 * 1.5); } | ||
if (a < Math.abs(c)) { | ||
a = c; var s = p / 4; | ||
} else { | ||
var s = p / (2 * Math.PI) * Math.asin(c / a); | ||
} | ||
if (t < 1) { return -.5 * (a * Math.pow(2,10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b; } | ||
return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b; | ||
} | ||
function easeInBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
return c * (t /= d) * t * ((s + 1) * t - s) + b; | ||
} | ||
function easeInBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
return c * (t /= d) * t * ((s + 1) * t - s) + b; | ||
} | ||
function easeOutBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; | ||
} | ||
function easeOutBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; | ||
} | ||
function easeInOutBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
if ((t /= d / 2) < 1) { return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b; } | ||
return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b; | ||
} | ||
function easeInOutBack(t, b, c, d, s) { | ||
if (s == undefined) { s = 1.70158; } | ||
if ((t /= d / 2) < 1) { return c / 2 * (t * t * (((s *= 1.525) + 1) * t - s)) + b; } | ||
return c / 2 * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2) + b; | ||
} | ||
function easeOutBounce(t, b, c, d) { | ||
if (t /= d < 1 / 2.75) { | ||
return c * (7.5625 * t * t) + b; | ||
} else if (t < 2 / 2.75) { | ||
return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b; | ||
} else if (t < 2.5 / 2.75) { | ||
return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b; | ||
} else { | ||
return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b; | ||
} | ||
function easeOutBounce(t, b, c, d) { | ||
if (t /= d < 1 / 2.75) { | ||
return c * (7.5625 * t * t) + b; | ||
} else if (t < 2 / 2.75) { | ||
return c * (7.5625 * (t -= 1.5 / 2.75) * t + .75) + b; | ||
} else if (t < 2.5 / 2.75) { | ||
return c * (7.5625 * (t -= 2.25 / 2.75) * t + .9375) + b; | ||
} else { | ||
return c * (7.5625 * (t -= 2.625 / 2.75) * t + .984375) + b; | ||
} | ||
} | ||
var easings = Object.freeze({ | ||
oscillate: oscillate, | ||
easeInQuad: easeInQuad, | ||
easeOutQuad: easeOutQuad, | ||
easeInOutQuad: easeInOutQuad, | ||
easeInCubic: easeInCubic, | ||
easeOutCubic: easeOutCubic, | ||
easeInOutCubic: easeInOutCubic, | ||
easeInQuart: easeInQuart, | ||
easeOutQuart: easeOutQuart, | ||
easeInOutQuart: easeInOutQuart, | ||
easeInQuint: easeInQuint, | ||
easeOutQuint: easeOutQuint, | ||
easeInOutQuint: easeInOutQuint, | ||
easeInSine: easeInSine, | ||
easeOutSine: easeOutSine, | ||
easeInOutSine: easeInOutSine, | ||
easeInExpo: easeInExpo, | ||
easeOutExpo: easeOutExpo, | ||
easeInOutExpo: easeInOutExpo, | ||
easeInCirc: easeInCirc, | ||
easeOutCirc: easeOutCirc, | ||
easeInOutCirc: easeInOutCirc, | ||
easeInElastic: easeInElastic, | ||
easeOutElastic: easeOutElastic, | ||
easeInOutElastic: easeInOutElastic, | ||
easeInBack: easeInBack, | ||
easeOutBack: easeOutBack, | ||
easeInOutBack: easeInOutBack, | ||
easeOutBounce: easeOutBounce | ||
}); | ||
var easings = Object.freeze({ | ||
oscillate: oscillate, | ||
easeInQuad: easeInQuad, | ||
easeOutQuad: easeOutQuad, | ||
easeInOutQuad: easeInOutQuad, | ||
easeInCubic: easeInCubic, | ||
easeOutCubic: easeOutCubic, | ||
easeInOutCubic: easeInOutCubic, | ||
easeInQuart: easeInQuart, | ||
easeOutQuart: easeOutQuart, | ||
easeInOutQuart: easeInOutQuart, | ||
easeInQuint: easeInQuint, | ||
easeOutQuint: easeOutQuint, | ||
easeInOutQuint: easeInOutQuint, | ||
easeInSine: easeInSine, | ||
easeOutSine: easeOutSine, | ||
easeInOutSine: easeInOutSine, | ||
easeInExpo: easeInExpo, | ||
easeOutExpo: easeOutExpo, | ||
easeInOutExpo: easeInOutExpo, | ||
easeInCirc: easeInCirc, | ||
easeOutCirc: easeOutCirc, | ||
easeInOutCirc: easeInOutCirc, | ||
easeInElastic: easeInElastic, | ||
easeOutElastic: easeOutElastic, | ||
easeInOutElastic: easeInOutElastic, | ||
easeInBack: easeInBack, | ||
easeOutBack: easeOutBack, | ||
easeInOutBack: easeInOutBack, | ||
easeOutBounce: easeOutBounce | ||
}); | ||
Scrollify.fx = fx; | ||
Scrollify.easings = easings; | ||
/** | ||
* Put Scrollify into the Global scope. | ||
* Useful for existing demos or if you wish to include manually | ||
*/ | ||
window.Scrollify = Scrollify; | ||
window.Scrollify = Scrollify; | ||
window.Scrollify.fx = fx; | ||
window.Scrollify.easings = easings; | ||
}()); | ||
}()); |
@@ -5,10 +5,11 @@ { | ||
"license": "MIT", | ||
"version": "0.3.0", | ||
"version": "0.4.7", | ||
"description": "A simple thing for triggering 'them scroll effects that everybody loves", | ||
"main": "./dist/scrollify.cjs.js", | ||
"broswer": "./dist/scrollify.min.js", | ||
"broswer": "./dist/scrollify.js", | ||
"jsnext:main": "./dist/scrollify.es6.js", | ||
"module": "./dist/scrollify.es6.js", | ||
"repository": { | ||
"type": "git", | ||
"url": "git@github.com:hugeinc/component-scrollify.git" | ||
"url": "https://github.com/apathetic/scrollify.git" | ||
}, | ||
@@ -22,4 +23,3 @@ "keywords": [ | ||
"clean": "rm -f dist/*.js*", | ||
"#build": "npm run clean && node build.js", | ||
"build": "npm run clean && npm run lint && rollup -c && rollup -c rollup.shim.config.js", | ||
"build": "npm run clean && npm run lint && rollup -c", | ||
"lint": "eslint source/js/*.js", | ||
@@ -31,8 +31,6 @@ "test": "#tape -r babel-register test/*.js" | ||
"http-server": "^0.9.0", | ||
"rollup": "^0.34.1", | ||
"rollup": "^0.45.2", | ||
"rollup-plugin-buble": "^0.12.1", | ||
"rollup-plugin-uglify": "^1.0.1", | ||
"tape": "^4.6.0", | ||
"uglify-js": "^2.7.0" | ||
"tape": "^4.6.0" | ||
} | ||
} |
# Scrollify | ||
Scrollify. Do things on scroll. | ||
Scrollify. Do things on scroll. 3KB minified and gzipped. | ||
@@ -9,28 +9,26 @@ ## What sorts of things? | ||
- *Stick*: sticks an element to a particular point and holds in there for a | ||
pre-defined number of pixels. | ||
- *Parallax*: move stuff on scroll. A subtle effect that transistions elements | ||
more slowly (or perhaps quickly) than the speed of the user-scroll. | ||
- *Toggle*: turn a CSS class on or off if the element crosses a particular | ||
threshold on the page. | ||
- *Translate*: translate an element along the X- or Y- axis. | ||
- *Rotate*: rotate an element via scroll. | ||
- *Scale*: scale an element. | ||
- *Fade*: change an element's opacity. | ||
- **Stick**: sticks an element to a particular point and holds in there for a pre-defined number of pixels. | ||
- **Parallax**: move stuff on scroll. A subtle effect that transitions elements more slowly (or perhaps quickly) than the speed of the user-scroll. | ||
- **Toggle**: turn a CSS class on or off if the element crosses a particular threshold on the page. | ||
- **Translate**: translate an element along the X- or Y- axis. | ||
- **Rotate**: rotate an element via scroll. | ||
- **Scale**: scale an element. | ||
- **Fade**: change an element's opacity. | ||
###Notes | ||
Scrollify works by first calculating an element's position in the page so that it may be manipulated on scroll. It is important to note that as the page loads, this position may jump around as the DOM is constructed and images are loaded, etc. Therefore, it is important that Scrollify'd elements are not initialized until the page has finished loading all images and the DOM is stable. | ||
If you're trying to Scrollify an element whose position on the page is dependant on assets loading above of it, you may wish to use __window.addEventListener('load'__ rather than the more common __window.addEventListener('DOMContentLoaded'__, OR check out the lovely <a href="https://github.com/desandro/imagesloaded">imagesloaded.js</a> plugin. | ||
### Notes | ||
Scrollify works by first calculating an element's position in the page so that it may be manipulated on scroll. It is important to note that as the page loads, this position may jump around as the DOM is constructed and images are loaded, etc. Therefore, it is recommended that Scrollify'd elements are not initialized until the page has finished loading all images and the DOM is stable. For example, if you're trying to _Scrollify_ an element whose position on the page is dependent on assets loading above of it, you may wish to use ```window.addEventListener('load'...``` rather than the more common ```'DOMContentLoaded'```. | ||
## API | ||
Coming soon. Please see the demo/index.html page for now. | ||
## Demo | ||
## Examples | ||
[Showcase](http://apathetic.github.io/showcase/components/scrollify/). | ||
First, spin up a webserver via ```npm i && npm start```. Navigate to localhost:8080/demo to check out the demos. Code samples are therein. | ||
First, install dependencies and spin up a webserver via ```npm i && npm start```. Navigate to ```localhost:8080/demo``` to check out the demos. Code samples are therein. | ||
## Getting Started | ||
Download it from [Github](https://github.com/apathetic/scrollify). | ||
Either: | ||
* npm: ```npm i @hugeinc/scrollify``` | ||
* github: download it from [Github](https://github.com/apathetic/scrollify). | ||
## Support | ||
@@ -41,4 +39,14 @@ * IE9+ | ||
## TODO | ||
* sticky effect glitchy on resize | ||
* relative units "+=", "-=", etc | ||
* getComputedStyle to avoid defining default vals | ||
* simplify API for effects / options definition | ||
## Release History | ||
### 0.3 | ||
* start and duration can accept various parameter types: float, 'px', '%' | ||
* internalized applyTransform check | ||
### 0.2 | ||
@@ -45,0 +53,0 @@ * quick scrolling bug fixing |
@@ -1,23 +0,25 @@ | ||
// import babel from 'rollup-plugin-babel'; | ||
import buble from 'rollup-plugin-buble'; | ||
// import uglify from 'rollup-plugin-uglify'; | ||
export default { | ||
entry: 'src/scrollify.js', | ||
plugins: [ | ||
// babel({ | ||
// exclude: [ | ||
// 'node_modules/**', | ||
// 'source/js/lib/**' | ||
// ], | ||
// presets: 'es2015-rollup' | ||
// }) | ||
buble(), | ||
// uglify() | ||
], | ||
targets: [ | ||
{ dest: 'dist/scrollify.cjs.js', format: 'cjs' }, | ||
{ dest: 'dist/scrollify.es6.js', format: 'es6' } | ||
] | ||
}; | ||
export default [ | ||
{ | ||
entry: 'src/index.js', | ||
exports: 'named', | ||
plugins: [ | ||
buble() | ||
], | ||
targets: [ | ||
{ dest: 'dist/scrollify.cjs.js', format: 'cjs' }, | ||
{ dest: 'dist/scrollify.es6.js', format: 'es' }, | ||
] | ||
}, | ||
{ | ||
entry: 'src/shim.js', | ||
moduleName: 'Scrollify', | ||
plugins: [ | ||
buble() | ||
], | ||
targets: [ | ||
{ dest: 'dist/scrollify.js', format: 'iife' } | ||
] | ||
} | ||
]; |
@@ -8,3 +8,3 @@ /*eslint max-len: ["error", 120]*/ | ||
t = Math.sin(t) * c; // now, oscillates between c, -c | ||
t = Math.abs(t); // "half wave rectifier" | ||
t = Math.abs(t); // "half wave rectifier" | ||
return t + b; | ||
@@ -11,0 +11,0 @@ } |
@@ -15,5 +15,12 @@ /** | ||
// Effects that use matrix transformations. At present, only | ||
// built-in effects benefit from matrix transformations. | ||
[translateX, translateY, rotate, scale, parallax].forEach((fn) => { | ||
fn._applyTransform = true; | ||
}); | ||
/** | ||
* Translate an element along the X-axis. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
@@ -23,5 +30,5 @@ * @return {void} | ||
export function translateX(progress) { | ||
let to = this.options.to || 0; | ||
let from = this.options.from || 0; | ||
let offset = (to - from) * progress + from; | ||
const to = (this.options.to !== undefined) ? this.options.to : 0; | ||
const from = (this.options.from !== undefined) ? this.options.from : 0; | ||
const offset = (to - from) * progress + from; | ||
@@ -33,3 +40,3 @@ this.transforms.position[0] = offset; | ||
* Translate an element vertically. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
@@ -39,5 +46,5 @@ * @return {void} | ||
export function translateY(progress) { | ||
let to = this.options.to || 0; | ||
let from = this.options.from || 0; // this.transforms.position[1]; | ||
let offset = (to - from) * progress + from; | ||
const to = (this.options.to !== undefined) ? this.options.to : 0; | ||
const from = (this.options.from !== undefined) ? this.options.from : 0;// this.transforms.position[1]; | ||
const offset = (to - from) * progress + from; | ||
@@ -47,5 +54,15 @@ this.transforms.position[1] = offset; | ||
// export function translate(progress) { | ||
// const to = this.options.to; | ||
// const from = this.options.from; | ||
// const offsetX = (to[0] - from[0]) * progress + from[0]; | ||
// const offsetY = (to[1] - from[1]) * progress + from[1]; | ||
// | ||
// this.transforms.position[0] = offsetX; | ||
// this.transforms.position[1] = offsetY; | ||
// } | ||
/** | ||
* Rotate an element, using radians. (note: rotates around Z-axis). | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
@@ -55,3 +72,3 @@ * @return {void} | ||
export function rotate(progress) { | ||
let radians = this.options.rad * progress; | ||
const radians = this.options.rad * progress; | ||
@@ -63,3 +80,3 @@ this.transforms.rotation[2] = radians; | ||
* Uniformly scale an element along both axis'. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
@@ -69,5 +86,5 @@ * @return {void} | ||
export function scale(progress) { | ||
let to = this.options.to || 1; | ||
let from = this.options.from || this.transforms.scale[0]; | ||
let scale = (to - from) * progress + from; | ||
const to = (this.options.to !== undefined) ? this.options.to : 1; | ||
const from = (this.options.from !== undefined) ? this.options.from : this.transforms.scale[0]; | ||
const scale = (to - from) * progress + from; | ||
@@ -80,3 +97,3 @@ this.transforms.scale[0] = scale; | ||
* Update an element's opacity. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
@@ -86,5 +103,5 @@ * @return {void} | ||
export function fade(progress) { | ||
let to = this.options.to !== undefined ? this.options.to : 1; | ||
let from = this.options.from !== undefined ? this.options.from : 1; | ||
let opacity = (to - from) * progress + from; | ||
const to = (this.options.to !== undefined) ? this.options.to : 0; | ||
const from = (this.options.from !== undefined) ? this.options.from : 1; | ||
const opacity = (to - from) * progress + from; | ||
@@ -95,14 +112,25 @@ this.element.style.opacity = opacity; | ||
/** | ||
* Update an element's blur. | ||
* @param {Float} progress Current progress of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
*/ | ||
export function blur(progress) { | ||
const to = (this.options.to !== undefined) ? this.options.to : 0; | ||
const from = (this.options.from !== undefined) ? this.options.from : 0; | ||
const amount = (to - from) * progress + from; | ||
this.element.style.filter = 'blur(' + amount + 'px)'; | ||
}; | ||
/** | ||
* Parallax an element. | ||
* @param {Float} progress: Current progress data of the scene, between 0 and 1. | ||
* @param {Float} progress Current progress data of the scene, between 0 and 1. | ||
* @this {Object} | ||
* @return {void} | ||
* | ||
* "this" contains effect options and also a reference to the element. | ||
*/ | ||
export function parallax(progress) { | ||
let offset = 0; | ||
let range = this.options.range || 0; | ||
const range = this.options.range || 0; | ||
const offset = progress * range; // TODO add provision for speed as well | ||
offset = progress * range; | ||
this.transforms.position[1] = offset; // just vertical for now | ||
@@ -118,8 +146,8 @@ } | ||
export function toggle(progress) { | ||
let opts = this.options; | ||
let element = this.element; | ||
let times = Object.keys(opts); | ||
const opts = this.options; | ||
const element = this.element; | ||
const times = Object.keys(opts); | ||
times.forEach(function(time) { | ||
let css = opts[time]; | ||
const css = opts[time]; | ||
@@ -144,4 +172,2 @@ if (progress > time) { | ||
// progress = Math.min(1.0, Math.max(0.0, progress)); | ||
if (progress <= 0) { | ||
@@ -175,4 +201,2 @@ setState(element, 'normal'); | ||
} | ||
// boundsParams = ["top", "left", "bottom", "right", "margin", "marginLeft", "marginRight", "marginTop", "marginBottom"]; | ||
} |
@@ -5,3 +5,3 @@ /* | ||
* | ||
* Copyright (c) 2016 Wes Hatch | ||
* Copyright (c) 2016, 2017 Wes Hatch | ||
* Licensed under the MIT license. | ||
@@ -11,9 +11,5 @@ * | ||
/*eslint max-len: ["error", 120]*/ | ||
/*global document requestAnimationFrame console HTMLElement*/ | ||
// TODO add weakmap support for public / private methods | ||
import transform from './transform'; | ||
import createMatrix from './matrix'; | ||
import { getUnit } from './normalize'; | ||
@@ -32,5 +28,6 @@ | ||
if (element instanceof HTMLElement == false) { element = document.querySelector(element); } | ||
if (!element || !transform) { return this.active = false; } | ||
// if (!transform) { throw 'Scrollify [error]: transforms not supported'; } | ||
// if (!element) { throw 'Scrollify [error]: could not find element'; } | ||
if (!element || !transform) { | ||
console.log('Scrollify [error] ', arguments[0]); | ||
return this.disable(); | ||
} | ||
@@ -46,9 +43,9 @@ this.element = element; | ||
rotation: [0,0,0], | ||
position: [0,0,0] | ||
// transformOrigin: [], | ||
position: [0,0,0], | ||
// transformOrigin: [0,0,0] | ||
// skew: [], | ||
}; | ||
window.addEventListener('scroll', (e) => this.onScroll(e)); | ||
window.addEventListener('resize', (e) => this.onResize(e)); | ||
window.addEventListener('scroll', () => this.onScroll(), { passive: true }); | ||
window.addEventListener('resize', () => this.onResize(), { passive: true }); | ||
} | ||
@@ -61,19 +58,18 @@ | ||
* | ||
* start: (required) When to start the effect. It is a 0 - 1 value | ||
* representing the percentage of the viewport (eg. 0.5). | ||
* Any effects in the Scene will begin when the trigger element | ||
* crosses this threshold. | ||
* start: (required) When to start the effect. It is a 0 - 1 value | ||
* representing the percentage of the viewport (eg. 0.5). | ||
* Any effects in the Scene will begin when the trigger element | ||
* crosses this threshold. | ||
* | ||
* duration: The length of the effect, in pixels. Scrollify will | ||
* interpolate that into value into a "progress" variable, bounded | ||
* by 0 - 1. If not supplied, the default value is the height of the | ||
* viewport + element height, meaning the effect will last for as | ||
* long as the element is visible. | ||
* duration: The length of the effect, in pixels. Scrollify will | ||
* interpolate that into value into a "progress" variable, bounded | ||
* by 0 - 1. If not supplied, the default value is the height of | ||
* the viewport + element height, meaning the effect will last for | ||
* as long as the element is visible. | ||
* | ||
* trigger: If supplied, Scrollify will use this element's position to | ||
* start any Scene effects. If not supplied, the default is to use | ||
* the element itself as a trigger. | ||
* start any Scene effects. If not supplied, the default is to use | ||
* the element itself as a trigger. | ||
* | ||
* easing: Ease in/out of an effect. Any value from Robert Penner's easing | ||
* functions is valid. | ||
* easing: Ease in/out of any effects in the Scene. | ||
* | ||
@@ -83,29 +79,32 @@ * @return {void} | ||
addScene(opts) { | ||
let triggerPos = opts.start || 0; | ||
let duration = opts.duration || window.innerHeight + this.element.offsetHeight; | ||
let easing = opts.easing || false; | ||
let effects = opts.effects || []; | ||
let trigger = opts.trigger ? opts.trigger instanceof HTMLElement ? opts.trigger : document.querySelector(opts.trigger) : this.element; | ||
let applyTransform = opts.applyTransform !== undefined ? opts.applyTransform : true; // opt out rather than opt in | ||
const trigger = opts.trigger ? opts.trigger instanceof HTMLElement ? opts.trigger : document.querySelector(opts.trigger) : this.element; | ||
const easing = opts.easing || false; | ||
const effects = opts.effects || []; | ||
let scene = { | ||
trigger: trigger, | ||
triggerPos: 1 - triggerPos, | ||
duration: duration, | ||
_trigger: trigger, // keep for internal calculations | ||
_applyTransform: false, // internal-use only. Whether to use matrix transforms or not. Perhaps should be moved to *effect* level | ||
_offset: opts.start || 0, // store original value for later calcs | ||
_duration: opts.duration || 1, // store original value for later calculations | ||
// start: 0, // absolute value in px. Some percentage of the viewport | ||
// duration: duration, // absolute value in px. Some percentage of the viewport | ||
easing: easing, | ||
applyTransform: applyTransform, | ||
effects: [] | ||
}; | ||
// scene.active = this.scroll > this.calculateStart(scene); // calculate any transformations if the scene has already passed. | ||
effects.map((effect) => { | ||
this.addEffect(effect.fn, effect.options, scene); | ||
}); | ||
this.calculateStart(scene); | ||
scene.state = (this.scroll > this.start) ? (this.scroll > this.start+duration) ? 'after' : 'active' : 'before'; | ||
this.calculateDuration(scene); | ||
effects.map((effect) => { | ||
this.addEffect(effect.name, effect.options, scene); | ||
}); | ||
scene.state = (this.scroll > this.start) ? (this.scroll > this.start+scene.duration) ? 'after' : 'active' : 'before'; | ||
this.updateScene(scene); | ||
this.calculate(scene); | ||
this.scenes.push(scene); | ||
if (opts.debug) { | ||
console.log('Scrollify scene: ', scene); | ||
} | ||
return this; | ||
@@ -121,2 +120,3 @@ } | ||
this.calculateStart(scene); | ||
this.calculateDuration(scene); | ||
this.calculate(scene); | ||
@@ -132,5 +132,6 @@ } | ||
*/ | ||
addEffect(effect, options = {}, scene) { | ||
let element = this.element; | ||
let transforms = this.transforms; | ||
addEffect(fn, options = {}, scene) { | ||
const element = this.element; | ||
const transforms = this.transforms; | ||
const context = { options, element, transforms }; | ||
@@ -144,3 +145,3 @@ if (!scene) { | ||
return this.addScene({ | ||
'effects': [{'name': effect, 'options': options}] | ||
'effects': [{'fn': fn, 'options': options}] | ||
}); | ||
@@ -150,16 +151,6 @@ } | ||
let curry = (fn, options) => { | ||
return function() { // NOTE: don't use => function here as we do NOT want to bind "this" | ||
let context = { | ||
'options': options, | ||
'element': element, | ||
'transforms': transforms | ||
}; | ||
// if any effect uses a matrix tranformation, we use true for the entire scene | ||
scene._applyTransform = scene._applyTransform || fn._applyTransform; | ||
scene.effects.push(fn.bind(context)); | ||
fn.call(context, this); // eslint-disable-line | ||
}; | ||
}; | ||
scene.effects.push(curry(effect, options)); | ||
return this; | ||
@@ -170,8 +161,8 @@ } | ||
* Calculate the start point of each scene. | ||
* @param {[type]} scene A Scrollify Scene object. | ||
* @param {Scrollify.Scene} scene A Scrollify Scene object. | ||
* @return {Integer} The start position of the Scene, in pixels. | ||
*/ | ||
calculateStart(scene) { | ||
let trigger = scene.trigger; | ||
let triggerPos = scene.triggerPos; | ||
const offset = window.innerHeight - this.mapTo(scene._offset, window.innerHeight); | ||
let trigger = scene._trigger; | ||
let top = 0; | ||
@@ -183,9 +174,38 @@ | ||
} while(trigger); | ||
// top = trigger.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); | ||
// var test = trigger.getBoundingClientRect().top + (window.scrollY || window.pageYOffset); | ||
// return Math.max(0, top - triggerPos * window.innerHeight); // (can be negative...?) | ||
scene.start = Math.max(0, top - triggerPos * window.innerHeight); | ||
scene.start = Math.max(0, top - offset); | ||
} | ||
/** | ||
* [mapTo description] | ||
* @param {[type]} input [description] | ||
* @param {[type]} scale [description] | ||
* @return {[type]} [description] | ||
*/ | ||
mapTo(input, scale) { | ||
const parsed = parseFloat(input); | ||
const unit = getUnit(input); | ||
switch (unit) { | ||
case 'px': | ||
return parsed; | ||
case '%': | ||
return parsed / 100.0 * scale; | ||
default: | ||
return parsed * scale; | ||
} | ||
} | ||
/** | ||
* [calculateDuration description] | ||
* @param {[type]} scene [description] | ||
* @return [type] [description] | ||
*/ | ||
calculateDuration(scene) { | ||
// if (typeof scene._duration === 'function') { return scene._duration(); } | ||
scene.duration = this.mapTo(scene._duration, window.innerHeight + this.element.offsetHeight); | ||
} | ||
/** | ||
* onScroll Handler | ||
@@ -229,7 +249,6 @@ * @return {void} | ||
calculate(scene) { | ||
let start = scene.start; | ||
let duration = scene.duration; | ||
let scroll = this.scroll; | ||
const start = scene.start; | ||
const duration = scene.duration; | ||
const scroll = this.scroll; | ||
let progress; | ||
let matrix; | ||
@@ -266,8 +285,8 @@ // after end | ||
scene.effects.forEach((effect) => { | ||
effect.call(progress); | ||
effect(progress); | ||
}); | ||
if (scene.applyTransform) { | ||
if (scene._applyTransform) { | ||
// transmogrify all applied transformations into a single matrix, and apply | ||
matrix = this.updateMatrix(); | ||
let matrix = this.updateMatrix(); | ||
this.element.style[transform] = matrix.asCSS(); | ||
@@ -310,18 +329,2 @@ } | ||
// ----------------------------------------------------- | ||
// IF we wished to perform rotation AFTER skew / position / etc, we could do it here. | ||
// The ordering is important, and has an effect. | ||
// if (t.rotationPost) { | ||
// m.rotateX(t.rotationPost[0]); | ||
// m.rotateY(t.rotationPost[1]); | ||
// m.rotateZ(t.rotationPost[2]); | ||
// } | ||
// if (t.scalePost) { | ||
// m.scale(t.scalePost[0], t.scalePost[1]); | ||
// } | ||
// ----------------------------------------------------- | ||
// ... and here we put it back. (This duplication is not a mistake). | ||
@@ -328,0 +331,0 @@ if (t.transformOrigin) { |
@@ -6,10 +6,8 @@ /** | ||
import scrollify from './scrollify.js'; | ||
import Scrollify from './scrollify.js'; | ||
import * as fx from './effects'; | ||
import * as easings from './easings'; | ||
scrollify.fx = fx; | ||
scrollify.easings = easings; | ||
window.Scrollify = scrollify; | ||
window.Scrollify = Scrollify; | ||
window.Scrollify.fx = fx; | ||
window.Scrollify.easings = easings; |
@@ -6,8 +6,9 @@ /** | ||
const dummy = document.createElement('div'); | ||
const transform = ['transform', 'webkitTransform', 'MozTransform', 'OTransform', 'msTransform'].find((t) => { | ||
// return (document.body.style[t] !== undefined); // if DOM is not yet ready, let's do: | ||
return (dummy.style[t] !== undefined); | ||
let transform; | ||
const dummy = document.createElement('div'); // we use this instead of document.body if the DOM is not yet ready | ||
['transform', 'webkitTransform', 'MozTransform', 'OTransform', 'msTransform'].forEach((t) => { | ||
if (dummy.style[t] !== undefined) { transform = t; } | ||
}); | ||
export default transform; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
772873
5
3882
56
0
1