UNPKG

parallaxis

Version:

A tiny parallax library that updates styles on scroll

221 lines (174 loc) 6.23 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _raf = require('raf'); var _raf2 = _interopRequireDefault(_raf); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } var cache = new WeakMap(); var difference = function difference(a, b) { return Math.abs(a - b); }; var elements = function elements(className) { var els = [].concat(_toConsumableArray(document.querySelectorAll('.' + className))); return els.map(function (el) { var relative = el.dataset.relative === 'true'; var offset = relative ? elY(el) : 0; var end = parseInt(el.dataset.end, 10); var start = parseInt(el.dataset.start, 10); var opacityStart = parseFloat(el.dataset.opacityStart); var opacityEnd = parseFloat(el.dataset.opacityEnd); var translateXStart = parseInt(el.dataset.translatexStart, 10); var translateXEnd = parseInt(el.dataset.translatexEnd, 10); var translateYStart = parseInt(el.dataset.translateyStart, 10); var translateYEnd = parseInt(el.dataset.translateyEnd, 10); var scaleStart = parseFloat(el.dataset.scaleStart); var scaleEnd = parseFloat(el.dataset.scaleEnd); var updates = {}; if (!isNaN(opacityStart) && !isNaN(opacityEnd)) { updates.opacity = { end: opacityEnd, start: opacityStart }; } if (!isNaN(translateXStart) && !isNaN(translateXEnd)) { updates.translateX = { end: translateXEnd, start: translateXStart }; } if (!isNaN(translateYStart) && !isNaN(translateYEnd)) { updates.translateY = { end: translateYEnd, start: translateYStart }; } if (!isNaN(scaleStart) && !isNaN(scaleEnd)) { updates.scale = { end: scaleEnd, start: scaleStart }; } if (typeof end === 'undefined' || typeof start === 'undefined' || Object.keys(updates) === 0) { return null; } return { el: el, end: end, offset: offset, relative: relative, start: start, updates: updates }; }).filter(function (x) { return x; }); }; var elY = function elY(el) { return scrollY() + el.getBoundingClientRect().top; }; var init = function init() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$className = _ref.className, className = _ref$className === undefined ? 'js-parallaxis' : _ref$className; var els = elements(className); if (els.length) { var updateFunc = update(els); updateOffsetsOnResize(els); updateFunc(); window.addEventListener('scroll', function () { return (0, _raf2.default)(updateFunc); }); } }; var interpolate = function interpolate(start, end, progress) { var p = difference(start, end) * progress; return start > end ? start - p : start + p; }; var interval = function interval(start, end, current) { return difference(start, current) / difference(start, end); }; var limit = function limit(min, max, value) { return Math.max(Math.min(value, max), min); }; var prefixedTransformProp = function prefixedTransformProp() { var el = document.createElement('div'); var vendors = ['Webkit', 'webkit', 'Moz', 'moz', 'ms', 'o']; if (el.style.transform != null) { return 'transform'; } for (var v in vendors) { var prop = vendors[v] + 'Transform'; if (typeof el.style[prop] !== 'undefined') { return prop; } } }; var scrollY = function scrollY() { return parseInt(window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0, 10); }; var update = function update(els) { var transformProp = prefixedTransformProp(); return function () { var y = scrollY(); els.map(function (_ref2) { var el = _ref2.el, end = _ref2.end, offset = _ref2.offset, start = _ref2.start, updates = _ref2.updates; var s = offset + start; var e = offset + end; var state = cache.get(el); if (y >= s && y <= e || state !== 'before' && y < s || state !== 'after' && y > e) { var translateX = 0; var translateY = 0; var scale = 1; var current = limit(s, e, y); var i = interval(s, e, current); if (updates.opacity) { var _updates$opacity = updates.opacity, _end = _updates$opacity.end, _start = _updates$opacity.start; var opacity = interpolate(_start, _end, i).toFixed(2); el.style.opacity = opacity; } if (updates.translateX) { var _updates$translateX = updates.translateX, _end2 = _updates$translateX.end, _start2 = _updates$translateX.start; translateX = parseInt(interpolate(_start2, _end2, i), 10); } if (updates.translateY) { var _updates$translateY = updates.translateY, _end3 = _updates$translateY.end, _start3 = _updates$translateY.start; translateY = parseInt(interpolate(_start3, _end3, i), 10); } if (updates.scale) { var _updates$scale = updates.scale, _end4 = _updates$scale.end, _start4 = _updates$scale.start; scale = interpolate(_start4, _end4, i).toFixed(2); } el.style[transformProp] = 'translate3d(' + translateX + 'px, ' + translateY + 'px, 0) scale(' + scale + ')'; if (y < s) { cache.set(el, 'before'); } else if (y > e) { cache.set(el, 'after'); } else { cache.set(el, 'during'); } } }); }; }; var updateOffsetsOnResize = function updateOffsetsOnResize(els) { var updateOffsets = function updateOffsets() { return els.map(function (x) { if (x.relative) { x.offset = elY(x.el); } }); }; var d = void 0; window.addEventListener('resize', function () { window.clearTimeout(d); d = window.setTimeout(updateOffsets, 50); }); }; exports.default = init;