vendor: 17,576 bytes, lines 1-567
1/** 2 * Atropos 1.0.1 3 * Touch-friendly 3D parallax hover effects 4 * https://atroposjs.com 5 * 6 * Copyright 2021-2021 7 * 8 * Released under the MIT License 9 * 10 * Released on: October 18, 2021 11 */ 12 13(function (global, factory) { 14 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : 15 typeof define === 'function' && define.amd ? define(factory) : 16 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Atropos = factory()); 17})(this, (function () { 'use strict'; 18 19 function _extends() { 20 _extends = Object.assign || function (target) { 21 for (var i = 1; i < arguments.length; i++) { 22 var source = arguments[i]; 23 24 for (var key in source) { 25 if (Object.prototype.hasOwnProperty.call(source, key)) { 26 target[key] = source[key]; 27 } 28 } 29 } 30 31 return target; 32 }; 33 34 return _extends.apply(this, arguments); 35 } 36 37 /* eslint-disable no-restricted-globals */ 38 var $ = function $(el, sel) { 39 return el.querySelector(sel); 40 }; 41 42 var $$ = function $$(el, sel) { 43 return el.querySelectorAll(sel); 44 }; 45 46 var removeUndefinedProps = function removeUndefinedProps(obj) { 47 if (obj === void 0) { 48 obj = {}; 49 } 50 51 var result = {}; 52 Object.keys(obj).forEach(function (key) { 53 if (typeof obj[key] !== 'undefined') result[key] = obj[key]; 54 }); 55 return result; 56 }; 57 58 function Atropos(originalParams) { 59 if (originalParams === void 0) { 60 originalParams = {}; 61 } 62 63 var _originalParams = originalParams, 64 el = _originalParams.el, 65 eventsEl = _originalParams.eventsEl; 66 var self = { 67 __atropos__: true, 68 params: _extends({ 69 alwaysActive: false, 70 activeOffset: 50, 71 shadowOffset: 50, 72 shadowScale: 1, 73 duration: 300, 74 rotate: true, 75 rotateTouch: true, 76 rotateXMax: 15, 77 rotateYMax: 15, 78 rotateXInvert: false, 79 rotateYInvert: false, 80 stretchX: 0, 81 stretchY: 0, 82 stretchZ: 0, 83 commonOrigin: true, 84 shadow: true, 85 highlight: true, 86 onEnter: null, 87 onLeave: null, 88 onRotate: null 89 }, removeUndefinedProps(originalParams || {})), 90 destroyed: false, 91 isActive: false 92 }; 93 var params = self.params; 94 var rotateEl; 95 var scaleEl; 96 var innerEl; 97 var elBoundingClientRect; 98 var eventsElBoundingClientRect; 99 var shadowEl; 100 var highlightEl; 101 var isScrolling; 102 var clientXStart; 103 var clientYStart; 104 var queue = []; 105 var queueFrameId; 106 107 var purgeQueue = function purgeQueue() { 108 queueFrameId = requestAnimationFrame(function () { 109 queue.forEach(function (data) { 110 if (typeof data === 'function') { 111 data(); 112 } else { 113 var element = data.element, 114 prop = data.prop, 115 value = data.value; 116 element.style[prop] = value; 117 } 118 }); 119 queue.splice(0, queue.length); 120 purgeQueue(); 121 }); 122 }; 123 124 purgeQueue(); 125 126 var $setDuration = function $setDuration(element, value) { 127 queue.push({ 128 element: element, 129 prop: 'transitionDuration', 130 value: value 131 }); 132 }; 133 134 var $setEasing = function $setEasing(element, value) { 135 queue.push({ 136 element: element, 137 prop: 'transitionTimingFunction', 138 value: value 139 }); 140 }; 141 142 var $setTransform = function $setTransform(element, value) { 143 queue.push({ 144 element: element, 145 prop: 'transform', 146 value: value 147 }); 148 }; 149 150 var $setOpacity = function $setOpacity(element, value) { 151 queue.push({ 152 element: element, 153 prop: 'opacity', 154 value: value 155 }); 156 }; 157 158 var $setOrigin = function $setOrigin(element, value) { 159 queue.push({ 160 element: element, 161 prop: 'transformOrigin', 162 value: value 163 }); 164 }; 165 166 var $on = function $on(element, event, handler, props) { 167 return element.addEventListener(event, handler, props); 168 }; 169 170 var $off = function $off(element, event, handler, props) { 171 return element.removeEventListener(event, handler, props); 172 }; 173 174 var createShadow = function createShadow() { 175 var created; 176 shadowEl = $(el, '.atropos-shadow'); 177 178 if (!shadowEl) { 179 shadowEl = document.createElement('span'); 180 shadowEl.classList.add('atropos-shadow'); 181 created = true; 182 } 183 184 $setTransform(shadowEl, "translate3d(0,0,-" + params.shadowOffset + "px) scale(" + params.shadowScale + ")"); 185 186 if (created) { 187 rotateEl.appendChild(shadowEl); 188 } 189 }; 190 191 var createHighlight = function createHighlight() { 192 var created; 193 highlightEl = $(el, '.atropos-highlight'); 194 195 if (!highlightEl) { 196 highlightEl = document.createElement('span'); 197 highlightEl.classList.add('atropos-highlight'); 198 created = true; 199 } 200 201 $setTransform(highlightEl, "translate3d(0,0,0)"); 202 203 if (created) { 204 innerEl.appendChild(highlightEl); 205 } 206 }; 207 208 var setChildrenOffset = function setChildrenOffset(_ref) { 209 var _ref$rotateXPercentag = _ref.rotateXPercentage, 210 rotateXPercentage = _ref$rotateXPercentag === void 0 ? 0 : _ref$rotateXPercentag, 211 _ref$rotateYPercentag = _ref.rotateYPercentage, 212 rotateYPercentage = _ref$rotateYPercentag === void 0 ? 0 : _ref$rotateYPercentag, 213 duration = _ref.duration, 214 opacityOnly = _ref.opacityOnly, 215 easeOut = _ref.easeOut; 216 217 var getOpacity = function getOpacity(element) { 218 if (element.dataset.atroposOpacity && typeof element.dataset.atroposOpacity === 'string') { 219 return element.dataset.atroposOpacity.split(';').map(function (v) { 220 return parseFloat(v); 221 }); 222 } 223 224 return undefined; 225 }; 226 227 $$(el, '[data-atropos-offset], [data-atropos-opacity]').forEach(function (childEl) { 228 $setDuration(childEl, duration); 229 $setEasing(childEl, easeOut ? 'ease-out' : ''); 230 var elementOpacity = getOpacity(childEl); 231 232 if (rotateXPercentage === 0 && rotateYPercentage === 0) { 233 if (!opacityOnly) $setTransform(childEl, "translate3d(0, 0, 0)"); 234 if (elementOpacity) $setOpacity(childEl, elementOpacity[0]); 235 } else { 236 var childElOffset = parseFloat(childEl.dataset.atroposOffset) / 100; 237 238 if (!Number.isNaN(childElOffset) && !opacityOnly) { 239 $setTransform(childEl, "translate3d(" + -rotateYPercentage * -childElOffset + "%, " + rotateXPercentage * -childElOffset + "%, 0)"); 240 } 241 242 if (elementOpacity) { 243 var min = elementOpacity[0], 244 max = elementOpacity[1]; 245 var rotatePercentage = Math.max(Math.abs(rotateXPercentage), Math.abs(rotateYPercentage)); 246 $setOpacity(childEl, min + (max - min) * rotatePercentage / 100); 247 } 248 } 249 }); 250 }; 251 252 var setElements = function setElements(clientX, clientY) { 253 var isMultiple = el !== eventsEl; 254 255 if (!elBoundingClientRect) { 256 elBoundingClientRect = el.getBoundingClientRect(); 257 } 258 259 if (isMultiple && !eventsElBoundingClientRect) { 260 eventsElBoundingClientRect = eventsEl.getBoundingClientRect(); 261 } 262 263 if (typeof clientX === 'undefined' && typeof clientY === 'undefined') { 264 var rect = isMultiple ? eventsElBoundingClientRect : elBoundingClientRect; 265 clientX = rect.left + rect.width / 2; 266 clientY = rect.top + rect.height / 2; 267 } 268 269 var rotateX = 0; 270 var rotateY = 0; 271 var _elBoundingClientRect = elBoundingClientRect, 272 top = _elBoundingClientRect.top, 273 left = _elBoundingClientRect.left, 274 width = _elBoundingClientRect.width, 275 height = _elBoundingClientRect.height; 276 var transformOrigin; 277 278 if (!isMultiple) { 279 var centerX = width / 2; 280 var centerY = height / 2; 281 var coordX = clientX - left; 282 var coordY = clientY - top; 283 rotateY = params.rotateYMax * (coordX - centerX) / (width / 2) * -1; 284 rotateX = params.rotateXMax * (coordY - centerY) / (height / 2); 285 } else { 286 var _eventsElBoundingClie = eventsElBoundingClientRect, 287 parentTop = _eventsElBoundingClie.top, 288 parentLeft = _eventsElBoundingClie.left, 289 parentWidth = _eventsElBoundingClie.width, 290 parentHeight = _eventsElBoundingClie.height; 291 var offsetLeft = left - parentLeft; 292 var offsetTop = top - parentTop; 293 294 var _centerX = width / 2 + offsetLeft; 295 296 var _centerY = height / 2 + offsetTop; 297 298 var _coordX = clientX - parentLeft; 299 300 var _coordY = clientY - parentTop; 301 302 rotateY = params.rotateYMax * (_coordX - _centerX) / (parentWidth - width / 2) * -1; 303 rotateX = params.rotateXMax * (_coordY - _centerY) / (parentHeight - height / 2); 304 transformOrigin = clientX - left + "px " + (clientY - top) + "px"; 305 } 306 307 rotateX = Math.min(Math.max(-rotateX, -params.rotateXMax), params.rotateXMax); 308 if (params.rotateXInvert) rotateX = -rotateX; 309 rotateY = Math.min(Math.max(-rotateY, -params.rotateYMax), params.rotateYMax); 310 if (params.rotateYInvert) rotateY = -rotateY; 311 var rotateXPercentage = rotateX / params.rotateXMax * 100; 312 var rotateYPercentage = rotateY / params.rotateYMax * 100; 313 var stretchX = (isMultiple ? rotateYPercentage / 100 * params.stretchX : 0) * (params.rotateYInvert ? -1 : 1); 314 var stretchY = (isMultiple ? rotateXPercentage / 100 * params.stretchY : 0) * (params.rotateXInvert ? -1 : 1); 315 var stretchZ = isMultiple ? Math.max(Math.abs(rotateXPercentage), Math.abs(rotateYPercentage)) / 100 * params.stretchZ : 0; 316 $setTransform(rotateEl, "translate3d(" + stretchX + "%, " + -stretchY + "%, " + -stretchZ + "px) rotateX(" + rotateX + "deg) rotateY(" + rotateY + "deg)"); 317 318 if (transformOrigin && params.commonOrigin) { 319 $setOrigin(rotateEl, transformOrigin); 320 } 321 322 if (highlightEl) { 323 $setDuration(highlightEl, params.duration + "ms"); 324 $setEasing(highlightEl, 'ease-out'); 325 $setTransform(highlightEl, "translate3d(" + -rotateYPercentage * 0.25 + "%, " + rotateXPercentage * 0.25 + "%, 0)"); 326 $setOpacity(highlightEl, Math.max(Math.abs(rotateXPercentage), Math.abs(rotateYPercentage)) / 100); 327 } 328 329 setChildrenOffset({ 330 rotateXPercentage: rotateXPercentage, 331 rotateYPercentage: rotateYPercentage, 332 duration: params.duration + "ms", 333 easeOut: true 334 }); 335 if (typeof params.onRotate === 'function') params.onRotate(rotateX, rotateY); 336 }; 337 338 var activate = function activate() { 339 queue.push(function () { 340 return el.classList.add('atropos-active'); 341 }); 342 $setDuration(rotateEl, params.duration + "ms"); 343 $setEasing(rotateEl, 'ease-out'); 344 $setTransform(scaleEl, "translate3d(0,0, " + params.activeOffset + "px)"); 345 $setDuration(scaleEl, params.duration + "ms"); 346 $setEasing(scaleEl, 'ease-out'); 347 348 if (shadowEl) { 349 $setDuration(shadowEl, params.duration + "ms"); 350 $setEasing(shadowEl, 'ease-out'); 351 } 352 353 self.isActive = true; 354 }; 355 356 var onPointerEnter = function onPointerEnter(e) { 357 isScrolling = undefined; 358 if (e.type === 'pointerdown' && e.pointerType === 'mouse') return; 359 if (e.type === 'pointerenter' && e.pointerType !== 'mouse') return; 360 361 if (e.type === 'pointerdown') { 362 e.preventDefault(); 363 } 364 365 clientXStart = e.clientX; 366 clientYStart = e.clientY; 367 368 if (params.alwaysActive) { 369 elBoundingClientRect = undefined; 370 eventsElBoundingClientRect = undefined; 371 return; 372 } 373 374 activate(); 375 if (typeof params.onEnter === 'function') params.onEnter(); 376 }; 377 378 var onTouchMove = function onTouchMove(e) { 379 if (isScrolling === false && e.cancelable) { 380 e.preventDefault(); 381 } 382 }; 383 384 var onPointerMove = function onPointerMove(e) { 385 if (!params.rotate || !self.isActive) return; 386 387 if (e.pointerType !== 'mouse') { 388 if (!params.rotateTouch) return; 389 e.preventDefault(); 390 } 391 392 var clientX = e.clientX, 393 clientY = e.clientY; 394 var diffX = clientX - clientXStart; 395 var diffY = clientY - clientYStart; 396 397 if (typeof params.rotateTouch === 'string' && (diffX !== 0 || diffY !== 0) && typeof isScrolling === 'undefined') { 398 if (diffX * diffX + diffY * diffY >= 25) { 399 var touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI; 400 isScrolling = params.rotateTouch === 'scroll-y' ? touchAngle > 45 : 90 - touchAngle > 45; 401 } 402 403 if (isScrolling === false) { 404 el.classList.add('atropos-rotate-touch'); 405 406 if (e.cancelable) { 407 e.preventDefault(); 408 } 409 } 410 } 411 412 if (e.pointerType !== 'mouse' && isScrolling) { 413 return; 414 } 415 416 setElements(clientX, clientY); 417 }; 418 419 var onPointerLeave = function onPointerLeave(e) { 420 elBoundingClientRect = undefined; 421 eventsElBoundingClientRect = undefined; 422 if (!self.isActive) return; 423 if (e && e.type === 'pointerup' && e.pointerType === 'mouse') return; 424 if (e && e.type === 'pointerleave' && e.pointerType !== 'mouse') return; 425 426 if (typeof params.rotateTouch === 'string' && isScrolling) { 427 el.classList.remove('atropos-rotate-touch'); 428 } 429 430 if (params.alwaysActive) { 431 setElements(); 432 if (typeof params.onRotate === 'function') params.onRotate(0, 0); 433 if (typeof params.onLeave === 'function') params.onLeave(); 434 return; 435 } 436 437 queue.push(function () { 438 return el.classList.remove('atropos-active'); 439 }); 440 $setDuration(scaleEl, params.duration + "ms"); 441 $setEasing(scaleEl, ''); 442 $setTransform(scaleEl, "translate3d(0,0, " + 0 + "px)"); 443 444 if (shadowEl) { 445 $setDuration(shadowEl, params.duration + "ms"); 446 $setEasing(shadowEl, ''); 447 } 448 449 if (highlightEl) { 450 $setDuration(highlightEl, params.duration + "ms"); 451 $setEasing(highlightEl, ''); 452 $setTransform(highlightEl, "translate3d(0, 0, 0)"); 453 $setOpacity(highlightEl, 0); 454 } 455 456 $setDuration(rotateEl, params.duration + "ms"); 457 $setEasing(rotateEl, ''); 458 $setTransform(rotateEl, "translate3d(0,0,0) rotateX(0deg) rotateY(0deg)"); 459 setChildrenOffset({ 460 duration: params.duration + "ms" 461 }); 462 self.isActive = false; 463 if (typeof params.onRotate === 'function') params.onRotate(0, 0); 464 if (typeof params.onLeave === 'function') params.onLeave(); 465 }; 466 467 var onDocumentClick = function onDocumentClick(e) { 468 var clickTarget = e.target; 469 470 if (!eventsEl.contains(clickTarget) && clickTarget !== eventsEl && self.isActive) { 471 onPointerLeave(); 472 } 473 }; 474 475 var initDOM = function initDOM() { 476 if (typeof el === 'string') { 477 el = $(document, el); 478 } 479 480 if (!el) return; // eslint-disable-next-line 481 482 if (el.__atropos__) return; 483 484 if (typeof eventsEl !== 'undefined') { 485 if (typeof eventsEl === 'string') { 486 eventsEl = $(document, eventsEl); 487 } 488 } else { 489 eventsEl = el; 490 } 491 492 Object.assign(self, { 493 el: el 494 }); 495 rotateEl = $(el, '.atropos-rotate'); 496 scaleEl = $(el, '.atropos-scale'); 497 innerEl = $(el, '.atropos-inner'); // eslint-disable-next-line 498 499 el.__atropos__ = self; 500 }; 501 502 var init = function init() { 503 initDOM(); 504 if (!el || !eventsEl) return; 505 506 if (params.shadow) { 507 createShadow(); 508 } 509 510 if (params.highlight) { 511 createHighlight(); 512 } 513 514 if (params.rotateTouch) { 515 if (typeof params.rotateTouch === 'string') { 516 el.classList.add("atropos-rotate-touch-" + params.rotateTouch); 517 } else { 518 el.classList.add('atropos-rotate-touch'); 519 } 520 } 521 522 if ($(el, '[data-atropos-opacity]')) { 523 setChildrenOffset({ 524 opacityOnly: true 525 }); 526 } 527 528 $on(document, 'click', onDocumentClick); 529 $on(eventsEl, 'pointerdown', onPointerEnter); 530 $on(eventsEl, 'pointerenter', onPointerEnter); 531 $on(eventsEl, 'pointermove', onPointerMove); 532 $on(eventsEl, 'touchmove', onTouchMove); 533 $on(eventsEl, 'pointerleave', onPointerLeave); 534 $on(eventsEl, 'pointerup', onPointerLeave); 535 $on(eventsEl, 'lostpointercapture', onPointerLeave); 536 537 if (params.alwaysActive) { 538 activate(); 539 setElements(); 540 } 541 }; 542 543 var destroy = function destroy() { 544 self.destroyed = true; 545 cancelAnimationFrame(queueFrameId); 546 $off(document, 'click', onDocumentClick); 547 $off(eventsEl, 'pointerdown', onPointerEnter); 548 $off(eventsEl, 'pointerenter', onPointerEnter); 549 $off(eventsEl, 'pointermove', onPointerMove); 550 $off(eventsEl, 'touchmove', onTouchMove); 551 $off(eventsEl, 'pointerleave', onPointerLeave); 552 $off(eventsEl, 'pointerup', onPointerLeave); 553 $off(eventsEl, 'lostpointercapture', onPointerLeave); // eslint-disable-next-line 554 555 delete el.__atropos__; 556 }; 557 558 self.destroy = destroy; 559 init(); // eslint-disable-next-line 560 561 return self; 562 } 563 564 return Atropos; 565 566})); 567//# sourceMappingURL=atropos.js.map
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.