react-scroll-animation-wrapper
Version:
create animated react wrapper component
212 lines • 9.08 kB
JavaScript
;
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