UNPKG

react-marquee-slider-vertical

Version:

The marquee slider of your wildest dreams. Only for React.js ⛺

170 lines 10.2 kB
"use strict"; var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }; 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; }; var __spreadArray = (this && this.__spreadArray) || function (to, from) { for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) to[j] = from[i]; return to; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); var react_1 = __importStar(require("react")); var styled_components_1 = __importStar(require("styled-components")); var Child_1 = __importDefault(require("./Child")); var util_1 = require("./util"); var Container = styled_components_1.default.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n justify-content: center;\n flex-wrap: nowrap;\n"], ["\n position: relative;\n width: 100%;\n height: 100%;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n justify-content: center;\n flex-wrap: nowrap;\n"]))); var marqueeAnim = styled_components_1.keyframes(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n 0% {\n transform: translate(0, 0);\n }\n\n 100% {\n transform: translate(0, 100%);\n }\n"], ["\n 0% {\n transform: translate(0, 0);\n }\n\n 100% {\n transform: translate(0, 100%);\n }\n"]))); var Mirror = styled_components_1.default.div(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n min-width: 100%;\n flex-shrink: 0;\n animation-name: ", ";\n animation-direction: ", ";\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n animation-play-state: ", ";\n"], ["\n min-width: 100%;\n flex-shrink: 0;\n animation-name: ", ";\n animation-direction: ", ";\n animation-timing-function: linear;\n animation-iteration-count: infinite;\n animation-play-state: ", ";\n"])), marqueeAnim, function (props) { return (props.direction === "rtl" ? "reverse" : "normal"); }, function (props) { return (props.paused ? "paused" : "running"); }); var NESTED_UPDATE_LIMIT = 50; // Let's try to prevent rerenders as much as possible var Marquee = react_1.default.memo(function (_a) { var children = _a.children, direction = _a.direction, velocity = _a.velocity, scatterRandomly = _a.scatterRandomly, resetAfterTries = _a.resetAfterTries, onInit = _a.onInit, onFinish = _a.onFinish; var _b = react_1.useState(0), retryAfterExceedingUpdateDepthTrigger = _b[0], setRetryAfterExceedingUpdateDepthTrigger = _b[1]; var _c = react_1.useState(0), animationDuration = _c[0], setAnimationDuration = _c[1]; var _d = react_1.useState(0), nestedUpdateCount = _d[0], setNestedUpdateCount = _d[1]; var _e = react_1.useState(0), totalTries = _e[0], setTotalTries = _e[1]; var _f = react_1.useState({ width: 0, height: 0 }), containerSize = _f[0], setContainerSize = _f[1]; var _g = react_1.useState([]), childrenPosition = _g[0], setChildrenPosition = _g[1]; var containerRef = react_1.useRef(null); var marqueeRef = react_1.useRef(null); var isInitRender = react_1.useRef(true); react_1.useEffect(function () { if (isInitRender.current) { onInit(); isInitRender.current = false; } }, [onInit]); react_1.useEffect(function () { if (scatterRandomly) { setContainerSize({ width: containerRef.current.clientWidth, height: containerRef.current.clientHeight, }); } }, [scatterRandomly]); react_1.useEffect(function () { // Don't change the state if if (!isNaN(velocity) && velocity > 0) { setAnimationDuration(containerRef.current.clientHeight / velocity); } }, [velocity]); react_1.useEffect(function () { if (scatterRandomly && nestedUpdateCount < NESTED_UPDATE_LIMIT) { var siblings = marqueeRef.current.childNodes; if (siblings.length > 0) { var containerRect = containerRef.current.getBoundingClientRect(); var childRect = siblings[siblings.length - 1].getBoundingClientRect(); if (util_1.outOfContainerBounds(childRect, containerRect)) { setChildrenPosition(function (state) { return state.slice(0, -1); }); setNestedUpdateCount(nestedUpdateCount + 1); setTotalTries(totalTries + 1); } else { var hasOverlaps = false; for (var i = 0; i + 1 < siblings.length; i++) { var rect1 = siblings[i].getBoundingClientRect(); var rect2 = siblings[siblings.length - 1].getBoundingClientRect(); if (util_1.doesOverlap(rect1, rect2, containerRect)) { hasOverlaps = true; setChildrenPosition(function (state) { return state.slice(0, -1); }); setNestedUpdateCount(nestedUpdateCount + 1); setTotalTries(totalTries + 1); } } if (!hasOverlaps && siblings.length === childrenPosition.length && childrenPosition.length === children.length) { onFinish({ totalTries: totalTries }); } } } if (containerSize.width > 0 && containerSize.height > 0 && childrenPosition.length < children.length) { setChildrenPosition(function (state) { return __spreadArray(__spreadArray([], state), [ { x: util_1.randomIntFromInterval(0, containerSize.width), y: util_1.randomIntFromInterval(0, containerSize.height), }, ]); }); setNestedUpdateCount(nestedUpdateCount + 1); setTotalTries(totalTries + 1); } // reset if (totalTries > 0 && totalTries % resetAfterTries === 0) { setChildrenPosition([]); } } }, [nestedUpdateCount, childrenPosition, containerSize, scatterRandomly]); react_1.useEffect(function () { if (nestedUpdateCount >= NESTED_UPDATE_LIMIT) { var resetRenderTimer_1 = setTimeout(function () { setNestedUpdateCount(0); setRetryAfterExceedingUpdateDepthTrigger(retryAfterExceedingUpdateDepthTrigger + 1); }); return function () { return clearTimeout(resetRenderTimer_1); }; } }, [nestedUpdateCount, retryAfterExceedingUpdateDepthTrigger]); var renderChild = function (child, index, isOriginal) { var pos; if (childrenPosition[index] !== undefined) { pos = childrenPosition[index]; } return (react_1.default.createElement(Child_1.default, __assign({ key: (isOriginal ? "child-original" : "child-clone") + "-" + index }, pos, { scatterRandomly: scatterRandomly }), child)); }; var filteredChildren = children.filter(function (child, index) { return scatterRandomly ? childrenPosition[index] !== undefined : true; }); var animatedStyle = { animationDuration: animationDuration + "s" }; return (react_1.default.createElement(Container, { ref: containerRef }, react_1.default.createElement(Mirror, { style: __assign(__assign({}, animatedStyle), (velocity === 0 ? { transform: "translateY(0)" } : {})), direction: direction, paused: velocity === 0 }, filteredChildren.map(function (c, i) { return renderChild(c, i, false); })), react_1.default.createElement(Mirror, { ref: marqueeRef, style: __assign(__assign({}, animatedStyle), (velocity === 0 ? { transform: "translateY(0)" } : {})), direction: direction, paused: velocity === 0 }, filteredChildren.map(function (c, i) { return renderChild(c, i, true); })), react_1.default.createElement(Mirror, { style: __assign(__assign({}, animatedStyle), (velocity === 0 ? { transform: "translateY(0)" } : {})), direction: direction, paused: velocity === 0 }, filteredChildren.map(function (c, i) { return renderChild(c, i, false); })))); }); Marquee.defaultProps = { direction: "rtl", velocity: 30, scatterRandomly: false, // the more elements, the higher you should put this. // change in hundred or thousand steps even resetAfterTries: 100, onInit: function () { }, onFinish: function () { }, }; exports.default = Marquee; var templateObject_1, templateObject_2, templateObject_3; //# sourceMappingURL=Marquee.js.map