UNPKG

react-three-d

Version:

A versatile React library designed to simplify the process of creating and manipulating 3D shapes using CSS.

197 lines 11.6 kB
"use strict"; 'use client'; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var react_1 = tslib_1.__importStar(require("react")); function getUnit(unit) { var _a; return ((_a = unit.match(/^(\d+)(\D+)$/)) === null || _a === void 0 ? void 0 : _a.slice(1)) || []; } function getTransform(params) { var theta = 360 / params.count; var angle = theta * params.index * -1; var fn = params.isHorizontal ? 'rotateY' : 'rotateX'; var size = getUnit(params.isHorizontal ? params.width : params.height)[0]; var radius = Math.round(+size / 2 / Math.tan(Math.PI / params.count)); return "translateZ(".concat(-radius, "px) ").concat(fn, "(").concat(angle, "deg)"); } function useResizeObserver(ref) { var _a = (0, react_1.useState)([0, 0]), dimensions = _a[0], setDimensions = _a[1]; (0, react_1.useEffect)(function () { var targetElement = (ref === null || ref === void 0 ? void 0 : ref.current) || document.body; var resizeObserver = new ResizeObserver(function (_a) { var entry = _a[0]; setDimensions([entry.contentRect.width, entry.contentRect.height]); }); resizeObserver.observe(targetElement); return function () { resizeObserver.unobserve(targetElement); }; }, [ref]); return dimensions; } function Gallery(_a) { var children = _a.children, _b = _a.isInfiniteMode, isInfiniteMode = _b === void 0 ? false : _b, _c = _a.isNavigation, isNavigation = _c === void 0 ? true : _c, _d = _a.itemsToScroll, itemsToScroll = _d === void 0 ? 1 : _d, mouseSwipeRatio = _a.mouseSwipeRatio, mouseSwipeTreshold = _a.mouseSwipeTreshold, onChange = _a.onChange, _e = _a.responsiveProps, responsiveProps = _e === void 0 ? [] : _e, _f = _a.selectedIndex, selectedIndex = _f === void 0 ? 0 : _f, _g = _a.selectedProps, _h = _g === void 0 ? {} : _g, selectedCellClassName = _h.className, selectedProps = tslib_1.__rest(_h, ["className"]), _j = _a.swipeRatio, swipeRatio = _j === void 0 ? 1 : _j, swipeTreshold = _a.swipeTreshold, touchSwipeRatio = _a.touchSwipeRatio, touchSwipeTreshold = _a.touchSwipeTreshold, props = tslib_1.__rest(_a, ["children", "isInfiniteMode", "isNavigation", "itemsToScroll", "mouseSwipeRatio", "mouseSwipeTreshold", "onChange", "responsiveProps", "selectedIndex", "selectedProps", "swipeRatio", "swipeTreshold", "touchSwipeRatio", "touchSwipeTreshold"]); var items = react_1.Children.toArray(children); var count = react_1.Children.count(children); var lastIndex = count - 1; var sceneRef = (0, react_1.useRef)(null); var carouselRef = (0, react_1.useRef)(null); var isDraggingRef = (0, react_1.useRef)(false); var dragStartPosRef = (0, react_1.useRef)(0); var windowWidth = useResizeObserver()[0]; var propsByWindowWidth = responsiveProps.reduce(function (result, _a) { if (_a === void 0) { _a = {}; } var _b = _a.minWidth, minWidth = _b === void 0 ? 0 : _b, _c = _a.maxWidth, maxWidth = _c === void 0 ? null : _c, item = tslib_1.__rest(_a, ["minWidth", "maxWidth"]); return windowWidth >= minWidth && (!maxWidth || windowWidth < maxWidth) ? tslib_1.__assign(tslib_1.__assign({}, result), item) : result; }, props); var _k = windowWidth ? propsByWindowWidth : props, height = _k.height, _l = _k.isHorizontal, isHorizontal = _l === void 0 ? true : _l, perspective = _k.perspective, style = _k.style, width = _k.width, restProps = tslib_1.__rest(_k, ["height", "isHorizontal", "perspective", "style", "width"]); var getNextSlideIndex = (0, react_1.useCallback)(function (direction) { if (direction === 'forward') { var nextIndex = selectedIndex + itemsToScroll; var isOnEnd = nextIndex > lastIndex; var newSlideIndex = isOnEnd ? (isInfiniteMode ? nextIndex - lastIndex - 1 : lastIndex) : nextIndex; return newSlideIndex; } if (direction === 'backward') { var nextIndex = selectedIndex - itemsToScroll; var isOnStart = nextIndex < 0; var newSlideIndex = isOnStart ? (isInfiniteMode ? lastIndex + 1 + nextIndex : 0) : nextIndex; return newSlideIndex; } return selectedIndex; }, [selectedIndex, itemsToScroll, lastIndex, isInfiniteMode]); var updateActiveSlideIndex = (0, react_1.useCallback)(function (newIndex) { if (newIndex !== selectedIndex) { var newTransform = getTransform({ count: count, index: newIndex, isHorizontal: isHorizontal, width: width, height: height, }); carouselRef.current.style.transform = newTransform; } if (onChange) { onChange(newIndex); } }, [selectedIndex, onChange, count, isHorizontal, width, height]); (0, react_1.useEffect)(function () { var element = carouselRef.current; // eslint-disable-next-line @typescript-eslint/no-unused-vars function handleSwipe(_event) { isDraggingRef.current = true; } function handleSwipeEnd(event) { var _a; document.removeEventListener('mousemove', handleSwipe); document.removeEventListener('mouseup', handleSwipeEnd); document.removeEventListener('touchmove', handleSwipe); document.removeEventListener('touchend', handleSwipeEnd); if (isDraggingRef.current) { var isTouch = !!((_a = event.changedTouches) === null || _a === void 0 ? void 0 : _a[0]); var dragPos = isTouch ? event.changedTouches[event.changedTouches.length - 1].clientX : event.clientX; var mousePosDiff = (dragStartPosRef.current - dragPos) * ((isTouch ? touchSwipeRatio : mouseSwipeRatio) || swipeRatio); var quarter = +getUnit(isHorizontal ? width : height)[0] / 4; var treshold = (isTouch ? touchSwipeTreshold : mouseSwipeTreshold) || swipeTreshold || quarter; var nextActiveSlide = mousePosDiff > treshold ? { index: getNextSlideIndex('forward'), direction: 'forward', } : mousePosDiff < -treshold ? { index: getNextSlideIndex('backward'), direction: 'backward', } : { index: selectedIndex, direction: 'forward', }; updateActiveSlideIndex(nextActiveSlide.index); } dragStartPosRef.current = 0; isDraggingRef.current = false; } function handleSwipeStart(event) { var _a, _b; var isTouch = !!((_a = event.touches) === null || _a === void 0 ? void 0 : _a[0]); dragStartPosRef.current = isTouch ? (_b = event.touches) === null || _b === void 0 ? void 0 : _b[0].clientX : event.clientX; if (isTouch) { document.addEventListener('touchmove', handleSwipe); document.addEventListener('touchend', handleSwipeEnd); } else { document.addEventListener('mousemove', handleSwipe); document.addEventListener('mouseup', handleSwipeEnd); } } if (isNavigation) { element === null || element === void 0 ? void 0 : element.addEventListener('touchstart', handleSwipeStart, { passive: true }); element === null || element === void 0 ? void 0 : element.addEventListener('mousedown', handleSwipeStart); element === null || element === void 0 ? void 0 : element.addEventListener('dragstart', handleSwipeEnd); } return function () { isDraggingRef.current = false; dragStartPosRef.current = 0; document.removeEventListener('mousemove', handleSwipe); document.removeEventListener('mouseup', handleSwipeEnd); document.removeEventListener('touchmove', handleSwipe); document.removeEventListener('touchend', handleSwipeEnd); element === null || element === void 0 ? void 0 : element.removeEventListener('touchstart', handleSwipeStart); element === null || element === void 0 ? void 0 : element.removeEventListener('mousedown', handleSwipeStart); element === null || element === void 0 ? void 0 : element.removeEventListener('dragstart', handleSwipeEnd); }; }, [ getNextSlideIndex, height, isHorizontal, isInfiniteMode, isNavigation, mouseSwipeRatio, mouseSwipeTreshold, selectedIndex, swipeRatio, swipeTreshold, touchSwipeRatio, touchSwipeTreshold, updateActiveSlideIndex, width, ]); var carouselTransform = getTransform({ count: count, index: selectedIndex, isHorizontal: isHorizontal, width: width, height: height, }); return (react_1.default.createElement("div", tslib_1.__assign({ style: tslib_1.__assign(tslib_1.__assign({}, style), { position: 'relative', width: width, height: height, perspective: perspective }), ref: sceneRef }, restProps), react_1.default.createElement("div", { style: { height: '100%', position: 'absolute', WebkitTransformStyle: 'preserve-3d', MozTransformStyle: 'preserve-3d', transformStyle: 'preserve-3d', width: '100%', WebkitTransition: '-webkit-transform 400ms ease-in-out', MozTransition: '-moz-transform 400ms ease-in-out', transition: 'transform 400ms ease-in-out', WebkitTransform: carouselTransform, transform: carouselTransform, }, ref: carouselRef }, items.map(function (item, index, _a) { var length = _a.length; var _b = item.props, _c = _b === void 0 ? {} : _b, _d = _c.className, cellClassName = _d === void 0 ? '' : _d, _e = _c.style, cellStyle = _e === void 0 ? {} : _e, cellComponentProps = tslib_1.__rest(_c, ["className", "style"]), cellComponentData = tslib_1.__rest(item, ["props"]); var isActive = index === selectedIndex; var className = "".concat(cellClassName, " ").concat(isActive ? selectedCellClassName : '').trim() || undefined; var _f = getUnit(isHorizontal ? width : height), value = _f[0], unit = _f[1]; var fn = isHorizontal ? 'rotateY' : 'rotateX'; var rotate = (360 / length) * index; var translate = +value / 2 / Math.tan(Math.PI / length); var cellProps = tslib_1.__assign(tslib_1.__assign({ role: 'cell', className: className, style: tslib_1.__assign(tslib_1.__assign({}, cellStyle), { height: '100%', left: '0', position: 'absolute', top: '0', width: '100%', WebkitTransform: "".concat(fn, "(").concat(rotate, "deg) translateZ(").concat(translate).concat(unit, ")"), transform: "".concat(fn, "(").concat(rotate, "deg) translateZ(").concat(translate).concat(unit, ")") }) }, cellComponentProps), (isActive ? selectedProps : {})); return tslib_1.__assign({ props: cellProps }, cellComponentData); })))); } exports.default = (0, react_1.memo)(Gallery); //# sourceMappingURL=Gallery.js.map