UNPKG

@animxyz/vue

Version:

AnimXYZ is a composable animation library that makes your site shine

335 lines (285 loc) 9.27 kB
/** * VueAnimXyz v0.6.6 * Copyright (c) 2020-present Ingram Projects * Released under the MIT License. * https://animxyz.com */ import { mergeData as mergeData$1 } from 'vue-functional-data-merge'; import clsx from 'clsx'; function deleteUndefined (obj) { Object.keys(obj).forEach(function (key) { if (obj[key] === undefined) { delete obj[key]; } }); } function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function (obj) { return typeof obj; }; } else { _typeof = function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function getXyzDurationForMode (mode, duration) { switch (_typeof(duration)) { case 'number': return duration; case 'string': return duration; case 'object': if (duration === null) return null; return duration[mode]; } return null; } function getXyzElementMode (el) { if (el.classList.contains('xyz-appear')) { return 'appear'; } if (el.classList.contains('xyz-in')) { return 'in'; } if (el.classList.contains('xyz-out')) { return 'out'; } return null; } function clearXyzElementProperties(el) { if (el._xyzAppearObserver) { el._xyzAppearObserver.disconnect(); } if (el._xyzAnimTimeout) { clearTimeout(el._xyzAnimTimeout); } el.removeEventListener('animationend', el._xyzAnimEnd); el.removeEventListener('animationcancelled', el._xyzAnimEnd); delete el._xyzAppearObserver; delete el._xyzAnimTimeout; delete el._xyzAnimEnd; } function getXyzAnimationHook (duration, appearVisible) { return function (el, done) { clearXyzElementProperties(el); function xyzAnimDone() { clearXyzElementProperties(el); done(); } var mode = getXyzElementMode(el); function runAnim() { var modeDuration = getXyzDurationForMode(mode, duration); if (typeof modeDuration === 'number') { el._xyzAnimTimeout = setTimeout(xyzAnimDone, modeDuration); return; } var xyzModeKeyframes = "xyz-".concat(mode, "-keyframes"); var xyzEls = new Set([el]); if (modeDuration === 'auto') { var xyzNestedEls = el.querySelectorAll(".xyz-nested, .xyz-".concat(mode, "-nested")); xyzNestedEls.forEach(xyzEls.add, xyzEls); } function removeXyzEl(xyzEl) { xyzEls.delete(xyzEl); if (xyzEls.size === 0) { xyzAnimDone(); } } // After one tick remove any elements that are dont have active animations el._xyzAnimTimeout = setTimeout(function () { xyzEls.forEach(function (xyzEl) { // Remove if element isnt visible var visible = xyzEl.offsetParent || xyzEl.getClientRects().length; if (!visible) { removeXyzEl(xyzEl); } // Remove if element has xyz animation overridden var animationName = window.getComputedStyle(xyzEl).getPropertyValue('animation-name'); if (animationName.indexOf(xyzModeKeyframes) === -1) { removeXyzEl(xyzEl); } }); }); el._xyzAnimEnd = function (event) { if (event.animationName === xyzModeKeyframes) { removeXyzEl(event.target); } }; el.addEventListener('animationend', el._xyzAnimEnd, false); el.addEventListener('animationcancelled', el._xyzAnimEnd, false); } if (mode === 'appear' && appearVisible) { var observerOptions = Object.assign({}, appearVisible); el.classList.add('xyz-paused-all'); el._xyzAppearObserver = new IntersectionObserver(function (entries, observer) { entries.forEach(function (entry) { if (entry.isIntersecting) { el.classList.remove('xyz-paused-all'); observer.disconnect(); runAnim(); } }); }, observerOptions); el._xyzAppearObserver.observe(el); } else { runAnim(); } }; } var xyzTransitionClasses = { appearFrom: 'xyz-appear-from', appearActive: 'xyz-appear', appearTo: 'xyz-appear-to', inFrom: 'xyz-in-from', inActive: 'xyz-in', inTo: 'xyz-in-to', outFrom: 'xyz-out-from', outActive: 'xyz-out', outTo: 'xyz-out-to' }; var xyzTransitionProps = { appear: Boolean, appearVisible: [Boolean, Object], duration: [Number, String, Object], mode: String, appearClass: String, appearActiveClass: String, appearToClass: String, enterClass: String, enterActiveClass: String, enterToClass: String, leaveClass: String, leaveActiveClass: String, leaveToClass: String }; var xyzTransitionGroupProps = Object.assign({}, xyzTransitionProps, { tag: { type: String, default: 'div' }, moveClass: String }); function mergeData() { var data1 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; var data2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return mergeData$1(data1, data2); } function getXyzTransitionData(data) { deleteUndefined(data.attrs); data.attrs.appear = Boolean(data.attrs.appear || data.attrs.appearVisible); var _data$attrs = data.attrs, appear = _data$attrs.appear, appearVisible = _data$attrs.appearVisible, duration = _data$attrs.duration; var animationHook = getXyzAnimationHook(duration, appearVisible); var transitionData = { attrs: { css: true, type: 'animation', appearClass: xyzTransitionClasses.appearFrom, appearActiveClass: xyzTransitionClasses.appearActive, appearToClass: xyzTransitionClasses.appearTo, enterClass: xyzTransitionClasses.inFrom, enterActiveClass: xyzTransitionClasses.inActive, enterToClass: xyzTransitionClasses.inTo, leaveClass: xyzTransitionClasses.outFrom, leaveActiveClass: xyzTransitionClasses.outActive, leaveToClass: xyzTransitionClasses.outTo }, on: { enter: animationHook, leave: animationHook } }; if (appear) { transitionData.on.appear = animationHook; } var mergedData = mergeData(transitionData, data); delete mergedData.attrs.appearVisible; delete mergedData.attrs.duration; return mergedData; } var XyzTransition = { name: 'XyzTransition', functional: true, props: xyzTransitionProps, render: function render(createElement, context) { var _context$data = context.data, data = _context$data === void 0 ? {} : _context$data, _context$props = context.props, props = _context$props === void 0 ? {} : _context$props, _context$children = context.children, children = _context$children === void 0 ? [] : _context$children; var newData = getXyzTransitionData(Object.assign({}, data, { attrs: Object.assign({}, data.attrs, props) })); children.forEach(function (node) { // Iterate through children and merge transition directives and styles node.data = mergeData(data, node.data); }); return createElement('transition', newData, children); } }; function getTransitionRawChildren(children) { return children.filter(function (node) { return node.tag && node.key != null && String(node.key).indexOf('__vlist') !== 0; }); } var XyzTransitionGroup = { name: 'XyzTransitionGroup', functional: true, props: xyzTransitionGroupProps, render: function render(createElement, context) { var _context$data = context.data, data = _context$data === void 0 ? {} : _context$data, _context$props = context.props, props = _context$props === void 0 ? {} : _context$props, _context$children = context.children, children = _context$children === void 0 ? [] : _context$children; var newData = getXyzTransitionData(Object.assign({}, data, { attrs: Object.assign({}, data.attrs, props) })); var rawChildren = getTransitionRawChildren(children); rawChildren.forEach(function (node, index) { // Iterate through children and apply xyz indexes node.data = mergeData({ staticStyle: { '--xyz-index': index, '--xyz-index-rev': children.length - index - 1 } }, node.data); }); return createElement('transition-group', newData, children); } }; function updateDirective(el, _ref) { var value = _ref.value; el.setAttribute('xyz', clsx(el._xyzOriginal, value)); } var xyz = { bind: function bind(el) { el._xyzOriginal = el.getAttribute('xyz'); updateDirective.apply(void 0, arguments); }, update: updateDirective }; var VueAnimXyz = { install: function install(Vue) { Vue.component('XyzTransition', XyzTransition); Vue.component('XyzTransitionGroup', XyzTransitionGroup); Vue.directive('xyz', xyz); } }; // Auto-install when vue is found (eg. in browser via <script> tag) var GlobalVue = null; if (typeof window !== 'undefined') { GlobalVue = window.Vue; } else if (typeof global !== 'undefined') { GlobalVue = global.Vue; } if (GlobalVue) { GlobalVue.use(VueAnimXyz); } export default VueAnimXyz; export { XyzTransition, XyzTransitionGroup, xyz };