UNPKG

react-scroll-motion

Version:
102 lines (101 loc) 5.41 kB
"use strict"; "use client"; 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; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (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 }); var react_1 = __importStar(require("react")); var constants_1 = require("./constants"); var stores_1 = require("./stores"); var utils_1 = require("./utils"); var _window = typeof window !== "undefined" ? window : undefined; var ScrollContainer = function (props) { var _a = props.snap, snap = _a === void 0 ? "none" : _a, children = props.children, _scrollParent = props.scrollParent, style = props.style, className = props.className; var scrollParent = _scrollParent || _window; var _b = (0, react_1.useState)(constants_1.initialScrollData), scrollData = _b[0], setScrollData = _b[1]; var containerRef = (0, react_1.useRef)(null); var scrollTimer = (0, react_1.useRef)(null); var scrollEvent = (0, react_1.useCallback)(function () { if (snap !== "none" && scrollTimer.current) clearTimeout(scrollTimer.current); var container = containerRef.current; if (!container) return; var currentScrollTop = scrollParent === window ? window.pageYOffset : scrollParent.scrollTop; var offsetTop = container.getBoundingClientRect().top + currentScrollTop; var currentY = currentScrollTop - offsetTop; var viewportHeight = scrollParent === window ? utils_1.environment.height : scrollParent.clientHeight; var totalPage = Array.isArray(children) ? children === null || children === void 0 ? void 0 : children.length : 1; var totalHeight = totalPage * (viewportHeight - 1); var totalProgress = currentY / totalHeight; // total page progress 0 ~ 1 var realPage = currentY / viewportHeight; // decimal page number var currentPage = Math.floor(realPage); // integer page number var currentProgress = realPage - currentPage; // current page progress setScrollData(function (scrollData) { return (__assign(__assign({}, scrollData), { currentY: currentY, viewportHeight: viewportHeight, totalPage: totalPage, totalHeight: totalHeight, totalProgress: totalProgress, realPage: realPage, currentPage: currentPage, currentProgress: currentProgress })); }); if (snap !== "none") { scrollTimer.current = setTimeout(function () { var newCurrentPage = Math.round(realPage); var newCurrentY = currentY; if (snap === "mandatory" || Math.abs(newCurrentPage - realPage) < 0.3) newCurrentY = newCurrentPage * viewportHeight; if (newCurrentY !== currentY) window.scrollTo({ top: newCurrentY + offsetTop, behavior: "smooth", }); }, 50); } }, [children, scrollParent, snap, setScrollData]); (0, react_1.useEffect)(function () { if (scrollParent) { scrollEvent(); scrollParent.addEventListener("scroll", scrollEvent); scrollParent.addEventListener("resize", scrollEvent); return function () { scrollParent.removeEventListener("scroll", scrollEvent); scrollParent.removeEventListener("resize", scrollEvent); }; } }, [scrollEvent, scrollParent]); return (react_1.default.createElement("div", { ref: containerRef, style: __assign({ margin: 0, padding: 0, userSelect: "none" }, style), className: className }, react_1.default.createElement(stores_1.ScrollDataContext.Provider, { value: scrollData }, (Array.isArray(children) && children.map(function (child, index) { return (react_1.default.createElement(stores_1.ScrollPageContext.Provider, { value: { page: index }, key: "scroll-page-".concat(index) }, child)); })) || (react_1.default.createElement(stores_1.ScrollPageContext.Provider, { value: { page: 0 } }, children))))); }; exports.default = ScrollContainer;