UNPKG

react-scroll-animation-wrapper

Version:
212 lines 9.08 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.ScrollAnimation = void 0; var react_1 = __importStar(require("react")); var lodash_1 = require("lodash"); var ScrollAnimation = function (_a) { var animateInStr = _a.animateIn, animateOutStr = _a.animateOut, afterAnimatedIn = _a.afterAnimatedIn, afterAnimatedOut = _a.afterAnimatedOut, _b = _a.offset, offset = _b === void 0 ? 150 : _b, _c = _a.duration, duration = _c === void 0 ? 1 : _c, _d = _a.delay, delay = _d === void 0 ? 0 : _d, _e = _a.initiallyVisible, initiallyVisible = _e === void 0 ? false : _e, _f = _a.animateOnce, animateOnce = _f === void 0 ? false : _f, style = _a.style, scrollableParentSelector = _a.scrollableParentSelector, className = _a.className, _g = _a.animatePreScroll, animatePreScroll = _g === void 0 ? true : _g, children = _a.children, _h = _a.animateOnlyOnScrollDown, animateOnlyOnScrollDown = _h === void 0 ? true : _h; var _j = (0, react_1.useState)({ classes: "animated", style: { animationDuration: duration + "s", opacity: initiallyVisible ? 1 : 0, }, }), state = _j[0], setState = _j[1]; var animating = false; var delayedAnimationTimeout; var callbackTimeout; var scrollableParent; var nodeRef = (0, react_1.useRef)(null); var handleScroll = function () { if (!animating) { var currentVis = getVisibility(); if (visibilityHasChanged(visibility, currentVis)) { clearTimeout(delayedAnimationTimeout); if (!currentVis.onScreen) { setState({ classes: "animated", style: { animationDuration: duration + "s", opacity: initiallyVisible ? 1 : 0, }, }); } else if (currentVis.inViewport && animateIn) { animateIn(afterAnimatedIn); } else if (currentVis.onScreen && visibility.inViewport && animateOut && state.style.opacity === 1) { animateOut(afterAnimatedOut); } visibility = currentVis; } } }; var listener = (0, lodash_1.throttle)(handleScroll, 50); var visibility = { onScreen: false, inViewport: false, }; var classes = className ? className + " " + state.classes : state.classes; var getElementTop = function (elm) { var yPos = 0; while (elm && elm.offsetTop !== undefined && elm.clientTop !== undefined) { yPos += elm.offsetTop + elm.clientTop; elm = elm.offsetParent; } return yPos; }; var getScrollPos = function () { var _a, _b; return ((_a = scrollableParent) === null || _a === void 0 ? void 0 : _a.pageYOffset) !== undefined ? scrollableParent.pageYOffset : (_b = scrollableParent) === null || _b === void 0 ? void 0 : _b.scrollTop; }; var getScrollableParentHeight = function () { var _a; return ((_a = scrollableParent) === null || _a === void 0 ? void 0 : _a.innerHeight) ? scrollableParent.innerHeight : scrollableParent.clientHeight; }; var getViewportTop = function () { return getScrollPos() + offset; }; var getViewportBottom = function () { return getScrollPos() + getScrollableParentHeight() - offset; }; var isInViewport = function (y) { return y >= getViewportTop() && y <= getViewportBottom(); }; var isAboveViewport = function (y) { return y < getViewportTop(); }; var isBelowViewport = function (y) { return y > getViewportBottom(); }; var inViewport = function (elementTop, elementBottom) { return animateOnlyOnScrollDown ? isInViewport(elementTop) || isAboveViewport(elementTop) : isInViewport(elementTop) || isInViewport(elementBottom) || (isAboveViewport(elementTop) && isBelowViewport(elementBottom)); }; var onScreen = function (elementTop, elementBottom) { return animateOnlyOnScrollDown ? !isBelowScreen(elementTop) : !isAboveScreen(elementBottom) && !isBelowScreen(elementTop); }; var isAboveScreen = function (y) { return y < getScrollPos(); }; var isBelowScreen = function (y) { return y > getScrollPos() + getScrollableParentHeight(); }; var getVisibility = function () { var _a, _b; var elementTop = getElementTop(nodeRef.current) - getElementTop(scrollableParent); var elementBottom = elementTop + ((_b = (_a = nodeRef === null || nodeRef === void 0 ? void 0 : nodeRef.current) === null || _a === void 0 ? void 0 : _a.clientHeight) !== null && _b !== void 0 ? _b : 0); return { inViewport: inViewport(elementTop, elementBottom), onScreen: onScreen(elementTop, elementBottom), }; }; (0, react_1.useEffect)(function () { var parentSelector = scrollableParentSelector; scrollableParent = parentSelector ? document.querySelector(parentSelector) : window; if (scrollableParent && scrollableParent.addEventListener) { scrollableParent.addEventListener("scroll", listener); } if (animatePreScroll) { handleScroll(); } return function () { clearTimeout(delayedAnimationTimeout); clearTimeout(callbackTimeout); if (window && window.removeEventListener) { window.removeEventListener("scroll", listener); } }; }, []); var visibilityHasChanged = function (previousVis, currentVis) { return previousVis.inViewport !== currentVis.inViewport || previousVis.onScreen !== currentVis.onScreen; }; var animate = function (animation, callback) { delayedAnimationTimeout = setTimeout(function () { animating = true; setState({ classes: "animated " + animation, style: { animationDuration: duration + "s", }, }); callbackTimeout = setTimeout(callback, duration * 1000); }, delay); }; var animateIn = function (callback) { animate(animateInStr, function () { if (!animateOnce) { setState(function (prev) { return (__assign(__assign({}, prev), { style: { animationDuration: duration + "s", opacity: 1, } })); }); animating = false; } var vis = getVisibility(); if (callback) { callback(vis); } }); }; var animateOut = function (callback) { animate(animateOutStr, function () { setState({ classes: "animated", style: { animationDuration: duration + "s", opacity: 0, }, }); var vis = getVisibility(); if (vis.inViewport && animateIn) { animateIn(afterAnimatedIn); } else { animating = false; } if (callback) { callback(vis); } }); }; return (react_1.default.createElement("div", { ref: nodeRef, className: classes, style: __assign(__assign({}, state.style), style) }, children)); }; exports.ScrollAnimation = ScrollAnimation; exports.default = exports.ScrollAnimation; //# sourceMappingURL=index.js.map