| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481 |
- /*!
- Atropos
- Version: 2.0.2
- Plugin URL: https://atroposjs.com
- License: Copyright 2021-2024 | Released under the MIT License
- !*/
- var Atropos = (function () {
- 'use strict';
- function _extends() {
- _extends = Object.assign ? Object.assign.bind() : function (target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) {
- if (Object.prototype.hasOwnProperty.call(source, key)) {
- target[key] = source[key];
- }
- }
- }
- return target;
- };
- return _extends.apply(this, arguments);
- }
- /* eslint-disable no-restricted-globals */
- var $ = function $(el, sel) {
- return el.querySelector(sel);
- };
- var $$ = function $$(el, sel) {
- return el.querySelectorAll(sel);
- };
- var removeUndefinedProps = function removeUndefinedProps(obj) {
- if (obj === void 0) {
- obj = {};
- }
- var result = {};
- Object.keys(obj).forEach(function (key) {
- if (typeof obj[key] !== 'undefined') result[key] = obj[key];
- });
- return result;
- };
- var defaults = {
- alwaysActive: false,
- activeOffset: 50,
- shadowOffset: 50,
- shadowScale: 1,
- duration: 300,
- rotate: true,
- rotateTouch: true,
- rotateXMax: 15,
- rotateYMax: 15,
- rotateXInvert: false,
- rotateYInvert: false,
- stretchX: 0,
- stretchY: 0,
- stretchZ: 0,
- commonOrigin: true,
- shadow: true,
- highlight: true
- };
- function Atropos(originalParams) {
- if (originalParams === void 0) {
- originalParams = {};
- }
- var _originalParams = originalParams,
- el = _originalParams.el,
- eventsEl = _originalParams.eventsEl;
- var _originalParams2 = originalParams,
- isComponent = _originalParams2.isComponent;
- var childrenRootEl;
- var self = {
- __atropos__: true,
- params: _extends({}, defaults, {
- onEnter: null,
- onLeave: null,
- onRotate: null
- }, removeUndefinedProps(originalParams || {})),
- destroyed: false,
- isActive: false
- };
- var params = self.params;
- var rotateEl;
- var scaleEl;
- var innerEl;
- var elBoundingClientRect;
- var eventsElBoundingClientRect;
- var shadowEl;
- var highlightEl;
- var isScrolling;
- var clientXStart;
- var clientYStart;
- var queue = [];
- var queueFrameId;
- var purgeQueue = function purgeQueue() {
- queueFrameId = requestAnimationFrame(function () {
- queue.forEach(function (data) {
- if (typeof data === 'function') {
- data();
- } else {
- var element = data.element,
- prop = data.prop,
- value = data.value;
- element.style[prop] = value;
- }
- });
- queue.splice(0, queue.length);
- purgeQueue();
- });
- };
- purgeQueue();
- var $setDuration = function $setDuration(element, value) {
- queue.push({
- element: element,
- prop: 'transitionDuration',
- value: value
- });
- };
- var $setEasing = function $setEasing(element, value) {
- queue.push({
- element: element,
- prop: 'transitionTimingFunction',
- value: value
- });
- };
- var $setTransform = function $setTransform(element, value) {
- queue.push({
- element: element,
- prop: 'transform',
- value: value
- });
- };
- var $setOpacity = function $setOpacity(element, value) {
- queue.push({
- element: element,
- prop: 'opacity',
- value: value
- });
- };
- var $setOrigin = function $setOrigin(element, value) {
- queue.push({
- element: element,
- prop: 'transformOrigin',
- value: value
- });
- };
- var $on = function $on(element, event, handler, props) {
- return element.addEventListener(event, handler, props);
- };
- var $off = function $off(element, event, handler, props) {
- return element.removeEventListener(event, handler, props);
- };
- var createShadow = function createShadow() {
- var created;
- shadowEl = $(el, '.atropos-shadow');
- if (!shadowEl) {
- shadowEl = document.createElement('span');
- shadowEl.classList.add('atropos-shadow');
- created = true;
- }
- $setTransform(shadowEl, "translate3d(0,0,-" + params.shadowOffset + "px) scale(" + params.shadowScale + ")");
- if (created) {
- rotateEl.appendChild(shadowEl);
- }
- };
- var createHighlight = function createHighlight() {
- var created;
- highlightEl = $(el, '.atropos-highlight');
- if (!highlightEl) {
- highlightEl = document.createElement('span');
- highlightEl.classList.add('atropos-highlight');
- created = true;
- }
- $setTransform(highlightEl, "translate3d(0,0,0)");
- if (created) {
- innerEl.appendChild(highlightEl);
- }
- };
- var setChildrenOffset = function setChildrenOffset(_ref) {
- var _ref$rotateXPercentag = _ref.rotateXPercentage,
- rotateXPercentage = _ref$rotateXPercentag === void 0 ? 0 : _ref$rotateXPercentag,
- _ref$rotateYPercentag = _ref.rotateYPercentage,
- rotateYPercentage = _ref$rotateYPercentag === void 0 ? 0 : _ref$rotateYPercentag,
- duration = _ref.duration,
- opacityOnly = _ref.opacityOnly,
- easeOut = _ref.easeOut;
- var getOpacity = function getOpacity(element) {
- if (element.dataset.atroposOpacity && typeof element.dataset.atroposOpacity === 'string') {
- return element.dataset.atroposOpacity.split(';').map(function (v) {
- return parseFloat(v);
- });
- }
- return undefined;
- };
- $$(childrenRootEl, '[data-atropos-offset], [data-atropos-opacity]').forEach(function (childEl) {
- $setDuration(childEl, duration);
- $setEasing(childEl, easeOut ? 'ease-out' : '');
- var elementOpacity = getOpacity(childEl);
- if (rotateXPercentage === 0 && rotateYPercentage === 0) {
- if (!opacityOnly) $setTransform(childEl, "translate3d(0, 0, 0)");
- if (elementOpacity) $setOpacity(childEl, elementOpacity[0]);
- } else {
- var childElOffset = parseFloat(childEl.dataset.atroposOffset) / 100;
- if (!Number.isNaN(childElOffset) && !opacityOnly) {
- $setTransform(childEl, "translate3d(" + -rotateYPercentage * -childElOffset + "%, " + rotateXPercentage * -childElOffset + "%, 0)");
- }
- if (elementOpacity) {
- var min = elementOpacity[0],
- max = elementOpacity[1];
- var rotatePercentage = Math.max(Math.abs(rotateXPercentage), Math.abs(rotateYPercentage));
- $setOpacity(childEl, min + (max - min) * rotatePercentage / 100);
- }
- }
- });
- };
- var setElements = function setElements(clientX, clientY) {
- var isMultiple = el !== eventsEl;
- if (!elBoundingClientRect) {
- elBoundingClientRect = el.getBoundingClientRect();
- }
- if (isMultiple && !eventsElBoundingClientRect) {
- eventsElBoundingClientRect = eventsEl.getBoundingClientRect();
- }
- if (typeof clientX === 'undefined' && typeof clientY === 'undefined') {
- var rect = isMultiple ? eventsElBoundingClientRect : elBoundingClientRect;
- clientX = rect.left + rect.width / 2;
- clientY = rect.top + rect.height / 2;
- }
- var rotateX = 0;
- var rotateY = 0;
- var _elBoundingClientRect = elBoundingClientRect,
- top = _elBoundingClientRect.top,
- left = _elBoundingClientRect.left,
- width = _elBoundingClientRect.width,
- height = _elBoundingClientRect.height;
- var transformOrigin;
- if (!isMultiple) {
- var centerX = width / 2;
- var centerY = height / 2;
- var coordX = clientX - left;
- var coordY = clientY - top;
- rotateY = params.rotateYMax * (coordX - centerX) / (width / 2) * -1;
- rotateX = params.rotateXMax * (coordY - centerY) / (height / 2);
- } else {
- var _eventsElBoundingClie = eventsElBoundingClientRect,
- parentTop = _eventsElBoundingClie.top,
- parentLeft = _eventsElBoundingClie.left,
- parentWidth = _eventsElBoundingClie.width,
- parentHeight = _eventsElBoundingClie.height;
- var offsetLeft = left - parentLeft;
- var offsetTop = top - parentTop;
- var _centerX = width / 2 + offsetLeft;
- var _centerY = height / 2 + offsetTop;
- var _coordX = clientX - parentLeft;
- var _coordY = clientY - parentTop;
- rotateY = params.rotateYMax * (_coordX - _centerX) / (parentWidth - width / 2) * -1;
- rotateX = params.rotateXMax * (_coordY - _centerY) / (parentHeight - height / 2);
- transformOrigin = clientX - left + "px " + (clientY - top) + "px";
- }
- rotateX = Math.min(Math.max(-rotateX, -params.rotateXMax), params.rotateXMax);
- if (params.rotateXInvert) rotateX = -rotateX;
- rotateY = Math.min(Math.max(-rotateY, -params.rotateYMax), params.rotateYMax);
- if (params.rotateYInvert) rotateY = -rotateY;
- var rotateXPercentage = rotateX / params.rotateXMax * 100;
- var rotateYPercentage = rotateY / params.rotateYMax * 100;
- var stretchX = (isMultiple ? rotateYPercentage / 100 * params.stretchX : 0) * (params.rotateYInvert ? -1 : 1);
- var stretchY = (isMultiple ? rotateXPercentage / 100 * params.stretchY : 0) * (params.rotateXInvert ? -1 : 1);
- var stretchZ = isMultiple ? Math.max(Math.abs(rotateXPercentage), Math.abs(rotateYPercentage)) / 100 * params.stretchZ : 0;
- $setTransform(rotateEl, "translate3d(" + stretchX + "%, " + -stretchY + "%, " + -stretchZ + "px) rotateX(" + rotateX + "deg) rotateY(" + rotateY + "deg)");
- if (transformOrigin && params.commonOrigin) {
- $setOrigin(rotateEl, transformOrigin);
- }
- if (highlightEl) {
- $setDuration(highlightEl, params.duration + "ms");
- $setEasing(highlightEl, 'ease-out');
- $setTransform(highlightEl, "translate3d(" + -rotateYPercentage * 0.25 + "%, " + rotateXPercentage * 0.25 + "%, 0)");
- $setOpacity(highlightEl, Math.max(Math.abs(rotateXPercentage), Math.abs(rotateYPercentage)) / 100);
- }
- setChildrenOffset({
- rotateXPercentage: rotateXPercentage,
- rotateYPercentage: rotateYPercentage,
- duration: params.duration + "ms",
- easeOut: true
- });
- if (typeof params.onRotate === 'function') params.onRotate(rotateX, rotateY);
- };
- var activate = function activate() {
- queue.push(function () {
- return el.classList.add('atropos-active');
- });
- $setDuration(rotateEl, params.duration + "ms");
- $setEasing(rotateEl, 'ease-out');
- $setTransform(scaleEl, "translate3d(0,0, " + params.activeOffset + "px)");
- $setDuration(scaleEl, params.duration + "ms");
- $setEasing(scaleEl, 'ease-out');
- if (shadowEl) {
- $setDuration(shadowEl, params.duration + "ms");
- $setEasing(shadowEl, 'ease-out');
- }
- self.isActive = true;
- };
- var onPointerEnter = function onPointerEnter(e) {
- isScrolling = undefined;
- if (e.type === 'pointerdown' && e.pointerType === 'mouse') return;
- if (e.type === 'pointerenter' && e.pointerType !== 'mouse') return;
- if (e.type === 'pointerdown') {
- e.preventDefault();
- }
- clientXStart = e.clientX;
- clientYStart = e.clientY;
- if (params.alwaysActive) {
- elBoundingClientRect = undefined;
- eventsElBoundingClientRect = undefined;
- return;
- }
- activate();
- if (typeof params.onEnter === 'function') params.onEnter();
- };
- var onTouchMove = function onTouchMove(e) {
- if (isScrolling === false && e.cancelable) {
- e.preventDefault();
- }
- };
- var onPointerMove = function onPointerMove(e) {
- if (!params.rotate || !self.isActive) return;
- if (e.pointerType !== 'mouse') {
- if (!params.rotateTouch) return;
- e.preventDefault();
- }
- var clientX = e.clientX,
- clientY = e.clientY;
- var diffX = clientX - clientXStart;
- var diffY = clientY - clientYStart;
- if (typeof params.rotateTouch === 'string' && (diffX !== 0 || diffY !== 0) && typeof isScrolling === 'undefined') {
- if (diffX * diffX + diffY * diffY >= 25) {
- var touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
- isScrolling = params.rotateTouch === 'scroll-y' ? touchAngle > 45 : 90 - touchAngle > 45;
- }
- if (isScrolling === false) {
- el.classList.add('atropos-rotate-touch');
- if (e.cancelable) {
- e.preventDefault();
- }
- }
- }
- if (e.pointerType !== 'mouse' && isScrolling) {
- return;
- }
- setElements(clientX, clientY);
- };
- var onPointerLeave = function onPointerLeave(e) {
- elBoundingClientRect = undefined;
- eventsElBoundingClientRect = undefined;
- if (!self.isActive) return;
- if (e && e.type === 'pointerup' && e.pointerType === 'mouse') return;
- if (e && e.type === 'pointerleave' && e.pointerType !== 'mouse') return;
- if (typeof params.rotateTouch === 'string' && isScrolling) {
- el.classList.remove('atropos-rotate-touch');
- }
- if (params.alwaysActive) {
- setElements();
- if (typeof params.onRotate === 'function') params.onRotate(0, 0);
- if (typeof params.onLeave === 'function') params.onLeave();
- return;
- }
- queue.push(function () {
- return el.classList.remove('atropos-active');
- });
- $setDuration(scaleEl, params.duration + "ms");
- $setEasing(scaleEl, '');
- $setTransform(scaleEl, "translate3d(0,0, " + 0 + "px)");
- if (shadowEl) {
- $setDuration(shadowEl, params.duration + "ms");
- $setEasing(shadowEl, '');
- }
- if (highlightEl) {
- $setDuration(highlightEl, params.duration + "ms");
- $setEasing(highlightEl, '');
- $setTransform(highlightEl, "translate3d(0, 0, 0)");
- $setOpacity(highlightEl, 0);
- }
- $setDuration(rotateEl, params.duration + "ms");
- $setEasing(rotateEl, '');
- $setTransform(rotateEl, "translate3d(0,0,0) rotateX(0deg) rotateY(0deg)");
- setChildrenOffset({
- duration: params.duration + "ms"
- });
- self.isActive = false;
- if (typeof params.onRotate === 'function') params.onRotate(0, 0);
- if (typeof params.onLeave === 'function') params.onLeave();
- };
- var onDocumentClick = function onDocumentClick(e) {
- var clickTarget = e.target;
- if (!eventsEl.contains(clickTarget) && clickTarget !== eventsEl && self.isActive) {
- onPointerLeave();
- }
- };
- var initDOM = function initDOM() {
- if (typeof el === 'string') {
- el = $(document, el);
- }
- if (!el) return;
- // eslint-disable-next-line
- if (el.__atropos__) return;
- if (typeof eventsEl !== 'undefined') {
- if (typeof eventsEl === 'string') {
- eventsEl = $(document, eventsEl);
- }
- } else {
- eventsEl = el;
- }
- childrenRootEl = isComponent ? el.parentNode.host : el;
- Object.assign(self, {
- el: el
- });
- rotateEl = $(el, '.atropos-rotate');
- scaleEl = $(el, '.atropos-scale');
- innerEl = $(el, '.atropos-inner');
- // eslint-disable-next-line
- el.__atropos__ = self;
- };
- var init = function init() {
- initDOM();
- if (!el || !eventsEl) return;
- if (params.shadow) {
- createShadow();
- }
- if (params.highlight) {
- createHighlight();
- }
- if (params.rotateTouch) {
- if (typeof params.rotateTouch === 'string') {
- el.classList.add("atropos-rotate-touch-" + params.rotateTouch);
- } else {
- el.classList.add('atropos-rotate-touch');
- }
- }
- if ($(childrenRootEl, '[data-atropos-opacity]')) {
- setChildrenOffset({
- opacityOnly: true
- });
- }
- $on(document, 'click', onDocumentClick);
- $on(eventsEl, 'pointerdown', onPointerEnter);
- $on(eventsEl, 'pointerenter', onPointerEnter);
- $on(eventsEl, 'pointermove', onPointerMove);
- $on(eventsEl, 'touchmove', onTouchMove);
- $on(eventsEl, 'pointerleave', onPointerLeave);
- $on(eventsEl, 'pointerup', onPointerLeave);
- $on(eventsEl, 'lostpointercapture', onPointerLeave);
- if (params.alwaysActive) {
- activate();
- setElements();
- }
- };
- var destroy = function destroy() {
- self.destroyed = true;
- cancelAnimationFrame(queueFrameId);
- $off(document, 'click', onDocumentClick);
- $off(eventsEl, 'pointerdown', onPointerEnter);
- $off(eventsEl, 'pointerenter', onPointerEnter);
- $off(eventsEl, 'pointermove', onPointerMove);
- $off(eventsEl, 'touchmove', onTouchMove);
- $off(eventsEl, 'pointerleave', onPointerLeave);
- $off(eventsEl, 'pointerup', onPointerLeave);
- $off(eventsEl, 'lostpointercapture', onPointerLeave);
- // eslint-disable-next-line
- delete el.__atropos__;
- };
- self.destroy = destroy;
- init();
- // eslint-disable-next-line
- return self;
- }
- return Atropos;
- })();
|