function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } /*! * Observer 3.12.2 * https://greensock.com * * @license Copyright 2008-2023, GreenSock. All rights reserved. * Subject to the terms at https://greensock.com/standard-license or for * Club GreenSock members, the agreement issued with that membership. * @author: Jack Doyle, jack@greensock.com */ /* eslint-disable */ var gsap, _coreInitted, _clamp, _win, _doc, _docEl, _body, _isTouch, _pointerType, ScrollTrigger, _root, _normalizer, _eventTypes, _context, _getGSAP = function _getGSAP() { return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; }, _startup = 1, _observers = [], _scrollers = [], _proxies = [], _getTime = Date.now, _bridge = function _bridge(name, value) { return value; }, _integrate = function _integrate() { var core = ScrollTrigger.core, data = core.bridge || {}, scrollers = core._scrollers, proxies = core._proxies; scrollers.push.apply(scrollers, _scrollers); proxies.push.apply(proxies, _proxies); _scrollers = scrollers; _proxies = proxies; _bridge = function _bridge(name, value) { return data[name](value); }; }, _getProxyProp = function _getProxyProp(element, property) { return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; }, _isViewport = function _isViewport(el) { return !!~_root.indexOf(el); }, _addListener = function _addListener(element, type, func, nonPassive, capture) { return element.addEventListener(type, func, { passive: !nonPassive, capture: !!capture }); }, _removeListener = function _removeListener(element, type, func, capture) { return element.removeEventListener(type, func, !!capture); }, _scrollLeft = "scrollLeft", _scrollTop = "scrollTop", _onScroll = function _onScroll() { return _normalizer && _normalizer.isPressed || _scrollers.cache++; }, _scrollCacheFunc = function _scrollCacheFunc(f, doNotCache) { var cachingFunc = function cachingFunc(value) { // since reading the scrollTop/scrollLeft/pageOffsetY/pageOffsetX can trigger a layout, this function allows us to cache the value so it only gets read fresh after a "scroll" event fires (or while we're refreshing because that can lengthen the page and alter the scroll position). when "soft" is true, that means don't actually set the scroll, but cache the new value instead (useful in ScrollSmoother) if (value || value === 0) { _startup && (_win.history.scrollRestoration = "manual"); // otherwise the new position will get overwritten by the browser onload. var isNormalizing = _normalizer && _normalizer.isPressed; value = cachingFunc.v = Math.round(value) || (_normalizer && _normalizer.iOS ? 1 : 0); //TODO: iOS Bug: if you allow it to go to 0, Safari can start to report super strange (wildly inaccurate) touch positions! f(value); cachingFunc.cacheID = _scrollers.cache; isNormalizing && _bridge("ss", value); // set scroll (notify ScrollTrigger so it can dispatch a "scrollStart" event if necessary } else if (doNotCache || _scrollers.cache !== cachingFunc.cacheID || _bridge("ref")) { cachingFunc.cacheID = _scrollers.cache; cachingFunc.v = f(); } return cachingFunc.v + cachingFunc.offset; }; cachingFunc.offset = 0; return f && cachingFunc; }, _horizontal = { s: _scrollLeft, p: "left", p2: "Left", os: "right", os2: "Right", d: "width", d2: "Width", a: "x", sc: _scrollCacheFunc(function (value) { return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; }) }, _vertical = { s: _scrollTop, p: "top", p2: "Top", os: "bottom", os2: "Bottom", d: "height", d2: "Height", a: "y", op: _horizontal, sc: _scrollCacheFunc(function (value) { return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; }) }, _getTarget = function _getTarget(t, self) { return (self && self._ctx && self._ctx.selector || gsap.utils.toArray)(t)[0] || (typeof t === "string" && gsap.config().nullTargetWarn !== false ? console.warn("Element not found:", t) : null); }, _getScrollFunc = function _getScrollFunc(element, _ref) { var s = _ref.s, sc = _ref.sc; // we store the scroller functions in an alternating sequenced Array like [element, verticalScrollFunc, horizontalScrollFunc, ...] so that we can minimize memory, maximize performance, and we also record the last position as a ".rec" property in order to revert to that after refreshing to ensure things don't shift around. _isViewport(element) && (element = _doc.scrollingElement || _docEl); var i = _scrollers.indexOf(element), offset = sc === _vertical.sc ? 1 : 2; !~i && (i = _scrollers.push(element) - 1); _scrollers[i + offset] || _addListener(element, "scroll", _onScroll); // clear the cache when a scroll occurs var prev = _scrollers[i + offset], func = prev || (_scrollers[i + offset] = _scrollCacheFunc(_getProxyProp(element, s), true) || (_isViewport(element) ? sc : _scrollCacheFunc(function (value) { return arguments.length ? element[s] = value : element[s]; }))); func.target = element; prev || (func.smooth = gsap.getProperty(element, "scrollBehavior") === "smooth"); // only set it the first time (don't reset every time a scrollFunc is requested because perhaps it happens during a refresh() when it's disabled in ScrollTrigger. return func; }, _getVelocityProp = function _getVelocityProp(value, minTimeRefresh, useDelta) { var v1 = value, v2 = value, t1 = _getTime(), t2 = t1, min = minTimeRefresh || 50, dropToZeroTime = Math.max(500, min * 3), update = function update(value, force) { var t = _getTime(); if (force || t - t1 > min) { v2 = v1; v1 = value; t2 = t1; t1 = t; } else if (useDelta) { v1 += value; } else { // not totally necessary, but makes it a bit more accurate by adjusting the v1 value according to the new slope. This way we're not just ignoring the incoming data. Removing for now because it doesn't seem to make much practical difference and it's probably not worth the kb. v1 = v2 + (value - v2) / (t - t2) * (t1 - t2); } }, reset = function reset() { v2 = v1 = useDelta ? 0 : v1; t2 = t1 = 0; }, getVelocity = function getVelocity(latestValue) { var tOld = t2, vOld = v2, t = _getTime(); (latestValue || latestValue === 0) && latestValue !== v1 && update(latestValue); return t1 === t2 || t - t2 > dropToZeroTime ? 0 : (v1 + (useDelta ? vOld : -vOld)) / ((useDelta ? t : t1) - tOld) * 1000; }; return { update: update, reset: reset, getVelocity: getVelocity }; }, _getEvent = function _getEvent(e, preventDefault) { preventDefault && !e._gsapAllow && e.preventDefault(); return e.changedTouches ? e.changedTouches[0] : e; }, _getAbsoluteMax = function _getAbsoluteMax(a) { var max = Math.max.apply(Math, a), min = Math.min.apply(Math, a); return Math.abs(max) >= Math.abs(min) ? max : min; }, _setScrollTrigger = function _setScrollTrigger() { ScrollTrigger = gsap.core.globals().ScrollTrigger; ScrollTrigger && ScrollTrigger.core && _integrate(); }, _initCore = function _initCore(core) { gsap = core || _getGSAP(); if (gsap && typeof document !== "undefined" && document.body) { _win = window; _doc = document; _docEl = _doc.documentElement; _body = _doc.body; _root = [_win, _doc, _docEl, _body]; _clamp = gsap.utils.clamp; _context = gsap.core.context || function () {}; _pointerType = "onpointerenter" in _body ? "pointer" : "mouse"; // isTouch is 0 if no touch, 1 if ONLY touch, and 2 if it can accommodate touch but also other types like mouse/pointer. _isTouch = Observer.isTouch = _win.matchMedia && _win.matchMedia("(hover: none), (pointer: coarse)").matches ? 1 : "ontouchstart" in _win || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ? 2 : 0; _eventTypes = Observer.eventTypes = ("ontouchstart" in _docEl ? "touchstart,touchmove,touchcancel,touchend" : !("onpointerdown" in _docEl) ? "mousedown,mousemove,mouseup,mouseup" : "pointerdown,pointermove,pointercancel,pointerup").split(","); setTimeout(function () { return _startup = 0; }, 500); _setScrollTrigger(); _coreInitted = 1; } return _coreInitted; }; _horizontal.op = _vertical; _scrollers.cache = 0; export var Observer = /*#__PURE__*/function () { function Observer(vars) { this.init(vars); } var _proto = Observer.prototype; _proto.init = function init(vars) { _coreInitted || _initCore(gsap) || console.warn("Please gsap.registerPlugin(Observer)"); ScrollTrigger || _setScrollTrigger(); var tolerance = vars.tolerance, dragMinimum = vars.dragMinimum, type = vars.type, target = vars.target, lineHeight = vars.lineHeight, debounce = vars.debounce, preventDefault = vars.preventDefault, onStop = vars.onStop, onStopDelay = vars.onStopDelay, ignore = vars.ignore, wheelSpeed = vars.wheelSpeed, event = vars.event, onDragStart = vars.onDragStart, onDragEnd = vars.onDragEnd, onDrag = vars.onDrag, onPress = vars.onPress, onRelease = vars.onRelease, onRight = vars.onRight, onLeft = vars.onLeft, onUp = vars.onUp, onDown = vars.onDown, onChangeX = vars.onChangeX, onChangeY = vars.onChangeY, onChange = vars.onChange, onToggleX = vars.onToggleX, onToggleY = vars.onToggleY, onHover = vars.onHover, onHoverEnd = vars.onHoverEnd, onMove = vars.onMove, ignoreCheck = vars.ignoreCheck, isNormalizer = vars.isNormalizer, onGestureStart = vars.onGestureStart, onGestureEnd = vars.onGestureEnd, onWheel = vars.onWheel, onEnable = vars.onEnable, onDisable = vars.onDisable, onClick = vars.onClick, scrollSpeed = vars.scrollSpeed, capture = vars.capture, allowClicks = vars.allowClicks, lockAxis = vars.lockAxis, onLockAxis = vars.onLockAxis; this.target = target = _getTarget(target) || _docEl; this.vars = vars; ignore && (ignore = gsap.utils.toArray(ignore)); tolerance = tolerance || 1e-9; dragMinimum = dragMinimum || 0; wheelSpeed = wheelSpeed || 1; scrollSpeed = scrollSpeed || 1; type = type || "wheel,touch,pointer"; debounce = debounce !== false; lineHeight || (lineHeight = parseFloat(_win.getComputedStyle(_body).lineHeight) || 22); // note: browser may report "normal", so default to 22. var id, onStopDelayedCall, dragged, moved, wheeled, locked, axis, self = this, prevDeltaX = 0, prevDeltaY = 0, scrollFuncX = _getScrollFunc(target, _horizontal), scrollFuncY = _getScrollFunc(target, _vertical), scrollX = scrollFuncX(), scrollY = scrollFuncY(), limitToTouch = ~type.indexOf("touch") && !~type.indexOf("pointer") && _eventTypes[0] === "pointerdown", // for devices that accommodate mouse events and touch events, we need to distinguish. isViewport = _isViewport(target), ownerDoc = target.ownerDocument || _doc, deltaX = [0, 0, 0], // wheel, scroll, pointer/touch deltaY = [0, 0, 0], onClickTime = 0, clickCapture = function clickCapture() { return onClickTime = _getTime(); }, _ignoreCheck = function _ignoreCheck(e, isPointerOrTouch) { return (self.event = e) && ignore && ~ignore.indexOf(e.target) || isPointerOrTouch && limitToTouch && e.pointerType !== "touch" || ignoreCheck && ignoreCheck(e, isPointerOrTouch); }, onStopFunc = function onStopFunc() { self._vx.reset(); self._vy.reset(); onStopDelayedCall.pause(); onStop && onStop(self); }, update = function update() { var dx = self.deltaX = _getAbsoluteMax(deltaX), dy = self.deltaY = _getAbsoluteMax(deltaY), changedX = Math.abs(dx) >= tolerance, changedY = Math.abs(dy) >= tolerance; onChange && (changedX || changedY) && onChange(self, dx, dy, deltaX, deltaY); // in ScrollTrigger.normalizeScroll(), we need to know if it was touch/pointer so we need access to the deltaX/deltaY Arrays before we clear them out. if (changedX) { onRight && self.deltaX > 0 && onRight(self); onLeft && self.deltaX < 0 && onLeft(self); onChangeX && onChangeX(self); onToggleX && self.deltaX < 0 !== prevDeltaX < 0 && onToggleX(self); prevDeltaX = self.deltaX; deltaX[0] = deltaX[1] = deltaX[2] = 0; } if (changedY) { onDown && self.deltaY > 0 && onDown(self); onUp && self.deltaY < 0 && onUp(self); onChangeY && onChangeY(self); onToggleY && self.deltaY < 0 !== prevDeltaY < 0 && onToggleY(self); prevDeltaY = self.deltaY; deltaY[0] = deltaY[1] = deltaY[2] = 0; } if (moved || dragged) { onMove && onMove(self); if (dragged) { onDrag(self); dragged = false; } moved = false; } locked && !(locked = false) && onLockAxis && onLockAxis(self); if (wheeled) { onWheel(self); wheeled = false; } id = 0; }, onDelta = function onDelta(x, y, index) { deltaX[index] += x; deltaY[index] += y; self._vx.update(x); self._vy.update(y); debounce ? id || (id = requestAnimationFrame(update)) : update(); }, onTouchOrPointerDelta = function onTouchOrPointerDelta(x, y) { if (lockAxis && !axis) { self.axis = axis = Math.abs(x) > Math.abs(y) ? "x" : "y"; locked = true; } if (axis !== "y") { deltaX[2] += x; self._vx.update(x, true); // update the velocity as frequently as possible instead of in the debounced function so that very quick touch-scrolls (flicks) feel natural. If it's the mouse/touch/pointer, force it so that we get snappy/accurate momentum scroll. } if (axis !== "x") { deltaY[2] += y; self._vy.update(y, true); } debounce ? id || (id = requestAnimationFrame(update)) : update(); }, _onDrag = function _onDrag(e) { if (_ignoreCheck(e, 1)) { return; } e = _getEvent(e, preventDefault); var x = e.clientX, y = e.clientY, dx = x - self.x, dy = y - self.y, isDragging = self.isDragging; self.x = x; self.y = y; if (isDragging || Math.abs(self.startX - x) >= dragMinimum || Math.abs(self.startY - y) >= dragMinimum) { onDrag && (dragged = true); isDragging || (self.isDragging = true); onTouchOrPointerDelta(dx, dy); isDragging || onDragStart && onDragStart(self); } }, _onPress = self.onPress = function (e) { if (_ignoreCheck(e, 1) || e && e.button) { return; } self.axis = axis = null; onStopDelayedCall.pause(); self.isPressed = true; e = _getEvent(e); // note: may need to preventDefault(?) Won't side-scroll on iOS Safari if we do, though. prevDeltaX = prevDeltaY = 0; self.startX = self.x = e.clientX; self.startY = self.y = e.clientY; self._vx.reset(); // otherwise the t2 may be stale if the user touches and flicks super fast and releases in less than 2 requestAnimationFrame ticks, causing velocity to be 0. self._vy.reset(); _addListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, preventDefault, true); self.deltaX = self.deltaY = 0; onPress && onPress(self); }, _onRelease = self.onRelease = function (e) { if (_ignoreCheck(e, 1)) { return; } _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true); var isTrackingDrag = !isNaN(self.y - self.startY), wasDragging = self.isDragging && (Math.abs(self.x - self.startX) > 3 || Math.abs(self.y - self.startY) > 3), // some touch devices need some wiggle room in terms of sensing clicks - the finger may move a few pixels. eventData = _getEvent(e); if (!wasDragging && isTrackingDrag) { self._vx.reset(); self._vy.reset(); if (preventDefault && allowClicks) { gsap.delayedCall(0.08, function () { // some browsers (like Firefox) won't trust script-generated clicks, so if the user tries to click on a video to play it, for example, it simply won't work. Since a regular "click" event will most likely be generated anyway (one that has its isTrusted flag set to true), we must slightly delay our script-generated click so that the "real"/trusted one is prioritized. Remember, when there are duplicate events in quick succession, we suppress all but the first one. Some browsers don't even trigger the "real" one at all, so our synthetic one is a safety valve that ensures that no matter what, a click event does get dispatched. if (_getTime() - onClickTime > 300 && !e.defaultPrevented) { if (e.target.click) { //some browsers (like mobile Safari) don't properly trigger the click event e.target.click(); } else if (ownerDoc.createEvent) { var syntheticEvent = ownerDoc.createEvent("MouseEvents"); syntheticEvent.initMouseEvent("click", true, true, _win, 1, eventData.screenX, eventData.screenY, eventData.clientX, eventData.clientY, false, false, false, false, 0, null); e.target.dispatchEvent(syntheticEvent); } } }); } } self.isDragging = self.isGesturing = self.isPressed = false; onStop && !isNormalizer && onStopDelayedCall.restart(true); onDragEnd && wasDragging && onDragEnd(self); onRelease && onRelease(self, wasDragging); }, _onGestureStart = function _onGestureStart(e) { return e.touches && e.touches.length > 1 && (self.isGesturing = true) && onGestureStart(e, self.isDragging); }, _onGestureEnd = function _onGestureEnd() { return (self.isGesturing = false) || onGestureEnd(self); }, onScroll = function onScroll(e) { if (_ignoreCheck(e)) { return; } var x = scrollFuncX(), y = scrollFuncY(); onDelta((x - scrollX) * scrollSpeed, (y - scrollY) * scrollSpeed, 1); scrollX = x; scrollY = y; onStop && onStopDelayedCall.restart(true); }, _onWheel = function _onWheel(e) { if (_ignoreCheck(e)) { return; } e = _getEvent(e, preventDefault); onWheel && (wheeled = true); var multiplier = (e.deltaMode === 1 ? lineHeight : e.deltaMode === 2 ? _win.innerHeight : 1) * wheelSpeed; onDelta(e.deltaX * multiplier, e.deltaY * multiplier, 0); onStop && !isNormalizer && onStopDelayedCall.restart(true); }, _onMove = function _onMove(e) { if (_ignoreCheck(e)) { return; } var x = e.clientX, y = e.clientY, dx = x - self.x, dy = y - self.y; self.x = x; self.y = y; moved = true; (dx || dy) && onTouchOrPointerDelta(dx, dy); }, _onHover = function _onHover(e) { self.event = e; onHover(self); }, _onHoverEnd = function _onHoverEnd(e) { self.event = e; onHoverEnd(self); }, _onClick = function _onClick(e) { return _ignoreCheck(e) || _getEvent(e, preventDefault) && onClick(self); }; onStopDelayedCall = self._dc = gsap.delayedCall(onStopDelay || 0.25, onStopFunc).pause(); self.deltaX = self.deltaY = 0; self._vx = _getVelocityProp(0, 50, true); self._vy = _getVelocityProp(0, 50, true); self.scrollX = scrollFuncX; self.scrollY = scrollFuncY; self.isDragging = self.isGesturing = self.isPressed = false; _context(this); self.enable = function (e) { if (!self.isEnabled) { _addListener(isViewport ? ownerDoc : target, "scroll", _onScroll); type.indexOf("scroll") >= 0 && _addListener(isViewport ? ownerDoc : target, "scroll", onScroll, preventDefault, capture); type.indexOf("wheel") >= 0 && _addListener(target, "wheel", _onWheel, preventDefault, capture); if (type.indexOf("touch") >= 0 && _isTouch || type.indexOf("pointer") >= 0) { _addListener(target, _eventTypes[0], _onPress, preventDefault, capture); _addListener(ownerDoc, _eventTypes[2], _onRelease); _addListener(ownerDoc, _eventTypes[3], _onRelease); allowClicks && _addListener(target, "click", clickCapture, false, true); onClick && _addListener(target, "click", _onClick); onGestureStart && _addListener(ownerDoc, "gesturestart", _onGestureStart); onGestureEnd && _addListener(ownerDoc, "gestureend", _onGestureEnd); onHover && _addListener(target, _pointerType + "enter", _onHover); onHoverEnd && _addListener(target, _pointerType + "leave", _onHoverEnd); onMove && _addListener(target, _pointerType + "move", _onMove); } self.isEnabled = true; e && e.type && _onPress(e); onEnable && onEnable(self); } return self; }; self.disable = function () { if (self.isEnabled) { // only remove the _onScroll listener if there aren't any others that rely on the functionality. _observers.filter(function (o) { return o !== self && _isViewport(o.target); }).length || _removeListener(isViewport ? ownerDoc : target, "scroll", _onScroll); if (self.isPressed) { self._vx.reset(); self._vy.reset(); _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true); } _removeListener(isViewport ? ownerDoc : target, "scroll", onScroll, capture); _removeListener(target, "wheel", _onWheel, capture); _removeListener(target, _eventTypes[0], _onPress, capture); _removeListener(ownerDoc, _eventTypes[2], _onRelease); _removeListener(ownerDoc, _eventTypes[3], _onRelease); _removeListener(target, "click", clickCapture, true); _removeListener(target, "click", _onClick); _removeListener(ownerDoc, "gesturestart", _onGestureStart); _removeListener(ownerDoc, "gestureend", _onGestureEnd); _removeListener(target, _pointerType + "enter", _onHover); _removeListener(target, _pointerType + "leave", _onHoverEnd); _removeListener(target, _pointerType + "move", _onMove); self.isEnabled = self.isPressed = self.isDragging = false; onDisable && onDisable(self); } }; self.kill = self.revert = function () { self.disable(); var i = _observers.indexOf(self); i >= 0 && _observers.splice(i, 1); _normalizer === self && (_normalizer = 0); }; _observers.push(self); isNormalizer && _isViewport(target) && (_normalizer = self); self.enable(event); }; _createClass(Observer, [{ key: "velocityX", get: function get() { return this._vx.getVelocity(); } }, { key: "velocityY", get: function get() { return this._vy.getVelocity(); } }]); return Observer; }(); Observer.version = "3.12.2"; Observer.create = function (vars) { return new Observer(vars); }; Observer.register = _initCore; Observer.getAll = function () { return _observers.slice(); }; Observer.getById = function (id) { return _observers.filter(function (o) { return o.vars.id === id; })[0]; }; _getGSAP() && gsap.registerPlugin(Observer); export { Observer as default, _isViewport, _scrollers, _getScrollFunc, _getProxyProp, _proxies, _getVelocityProp, _vertical, _horizontal, _getTarget };