acud
Version:
acg react 组件库
219 lines (218 loc) • 9.69 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _react = _interopRequireWildcard(require("react"));
var _classnames = _interopRequireDefault(require("classnames"));
var _configProvider = require("../config-provider");
var _switch = _interopRequireDefault(require("./switch"));
var _indicator = _interopRequireDefault(require("./indicator"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
var Carousel = function Carousel(_ref) {
var className = _ref.className,
style = _ref.style,
children = _ref.children,
_ref$dotPosition = _ref.dotPosition,
dotPosition = _ref$dotPosition === void 0 ? 'bottom' : _ref$dotPosition,
_ref$playInterval = _ref.playInterval,
playInterval = _ref$playInterval === void 0 ? 5000 : _ref$playInterval,
_ref$autoplay = _ref.autoplay,
autoplay = _ref$autoplay === void 0 ? true : _ref$autoplay,
_ref$width = _ref.width,
width = _ref$width === void 0 ? 1920 : _ref$width,
_ref$dotType = _ref.dotType,
dotType = _ref$dotType === void 0 ? 'dot' : _ref$dotType,
_ref$animationTime = _ref.animationTime,
animationTime = _ref$animationTime === void 0 ? 400 : _ref$animationTime,
multi = _ref.multi,
_ref$showNumber = _ref.showNumber,
showNumber = _ref$showNumber === void 0 ? 3 : _ref$showNumber,
_ref$multiShift = _ref.multiShift,
multiShift = _ref$multiShift === void 0 ? false : _ref$multiShift,
indicatorStyle = _ref.indicatorStyle,
_ref$infinite = _ref.infinite,
infinite = _ref$infinite === void 0 ? true : _ref$infinite;
var carouselRef = (0, _react.useRef)();
var timer = (0, _react.useRef)();
var _useState = (0, _react.useState)(false),
_useState2 = (0, _slicedToArray2["default"])(_useState, 2),
isHover = _useState2[0],
setIsHover = _useState2[1];
var _React$useContext = _react["default"].useContext(_configProvider.ConfigContext),
getPrefixCls = _React$useContext.getPrefixCls;
var prefixCls = getPrefixCls('carousel');
// 判断子元素是否是数组,如果不是,那就不存在轮播的情况
var childrenIsArray = (0, _react.useMemo)(function () {
return Array.isArray(children);
}, [children]);
// 因为要实现无缝轮播,所以前后会增加一个key。例如对用户看到有3张图片,但渲染中前后会添加得到5张
var extraCount = multi ? showNumber : 1;
var _useState3 = (0, _react.useState)({
lastKey: extraCount,
currentKey: extraCount
}),
_useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
_useState4$ = _useState4[0],
lastKey = _useState4$.lastKey,
currentKey = _useState4$.currentKey,
setKey = _useState4[1];
var length = Array.isArray(children) ? children.length : undefined;
var next = (0, _react.useCallback)(function () {
// 向右滑动,最后一帧无缝滑动到第一帧使用的是额外添加的帧,滑动动画结束后,立刻切换到原始帧
if (infinite) {
if (currentKey === length + extraCount) {
setKey({
lastKey: currentKey,
currentKey: extraCount
});
setTimeout(function () {
// 重置掉自动轮播
clearTimeout(timer.current);
var nextKey = extraCount + (multiShift ? extraCount : 1);
setKey({
lastKey: extraCount,
currentKey: nextKey > length + extraCount ? length + extraCount : nextKey
});
}, 100);
} else {
var nextKey = currentKey + (multiShift ? extraCount : 1);
setKey({
lastKey: currentKey,
currentKey: nextKey > length + extraCount ? length + extraCount : nextKey
});
}
} else {
var _nextKey = currentKey + (multiShift ? extraCount : 1);
setKey({
lastKey: currentKey,
currentKey: _nextKey > length + extraCount ? length + extraCount : _nextKey
});
}
}, [currentKey, extraCount, length, multiShift, infinite]);
// 向左滑动,第一帧无缝滑动到最后一帧使用的是额外添加的帧,滑动动画结束后,立刻切换到原始帧
var prev = (0, _react.useCallback)(function () {
if (infinite) {
if (currentKey === 0) {
setKey({
lastKey: currentKey,
currentKey: length
});
setTimeout(function () {
// 重置掉自动轮播
clearTimeout(timer.current);
var nextKey = length - (multiShift ? extraCount : 1);
setKey({
lastKey: length,
currentKey: nextKey < 0 ? 0 : length - (multiShift ? extraCount : 1)
});
});
} else {
var nextKey = currentKey - (multiShift ? extraCount : 1);
setKey({
lastKey: currentKey,
currentKey: nextKey < 0 ? 0 : currentKey - (multiShift ? extraCount : 1)
});
}
} else {
var _nextKey2 = currentKey - (multiShift ? extraCount : 1);
setKey({
lastKey: currentKey,
currentKey: _nextKey2 < 0 ? 0 : _nextKey2
});
}
}, [currentKey, extraCount, length, multiShift, infinite]);
// 监听是否hover热区,hover情况下不会自动轮播
(0, _react.useEffect)(function () {
carouselRef.current.addEventListener('mouseover', function () {
setIsHover(true);
});
carouselRef.current.addEventListener('mouseleave', function () {
setIsHover(false);
});
});
// 自动轮播
(0, _react.useEffect)(function () {
clearTimeout(timer.current);
if (length > 1 && autoplay && !isHover) {
timer.current = setTimeout(next, playInterval);
}
return function () {
return clearTimeout(timer.current);
};
}, [autoplay, length, playInterval, next, isHover]);
var getDuration = (0, _react.useCallback)(function () {
// next中立即切换的情况
if (lastKey === length + extraCount && currentKey === extraCount) {
return '0s';
}
// prev中立即切换的情况
if (lastKey === 0 && currentKey === length) {
return '0s';
}
// 正常切换的情况
return "".concat(animationTime / 1000, "s");
}, [lastKey, length, extraCount, currentKey, animationTime]);
// 渲染的元素数组,首位增加实现无缝轮播
var renderChildren = (0, _react.useMemo)(function () {
var elements = Array.isArray(children) ? children : [children];
if (elements.length >= 1) {
var extraPre = elements.slice(elements.length - extraCount);
var extraPost = elements.slice(0, extraCount);
elements = [].concat((0, _toConsumableArray2["default"])(extraPre), (0, _toConsumableArray2["default"])(elements), (0, _toConsumableArray2["default"])(extraPost));
}
return elements;
}, [children, extraCount]);
var cardWidth = (0, _react.useMemo)(function () {
if (multi) {
return (width - 4 * (extraCount - 1)) / extraCount;
}
return width;
}, [multi, width, extraCount]);
var getLeft = function getLeft(idx) {
return (multi ? cardWidth + 8 : cardWidth) * (idx - currentKey);
};
var wrapperClassName = (0, _classnames["default"])(prefixCls, className, (0, _defineProperty2["default"])({}, "".concat(prefixCls, "-multi"), multi));
var isPrevDisabled = !infinite && currentKey === extraCount;
var isNextDisabled = !infinite && currentKey === length;
return /*#__PURE__*/_react["default"].createElement("div", {
ref: carouselRef,
style: style,
className: wrapperClassName
}, childrenIsArray ? /*#__PURE__*/_react["default"].createElement(_react["default"].Fragment, null, /*#__PURE__*/_react["default"].createElement(_switch["default"], {
prefixCls: prefixCls,
next: next,
prev: prev,
isPrevDisabled: isPrevDisabled,
isNextDisabled: isNextDisabled
}), !multi && /*#__PURE__*/_react["default"].createElement(_indicator["default"], {
prefixCls: prefixCls,
setKey: setKey,
length: length,
currentKey: currentKey,
autoplay: autoplay,
playInterval: playInterval,
dotPosition: dotPosition,
dotType: dotType,
multi: multi,
showNumber: showNumber,
style: indicatorStyle
}), /*#__PURE__*/_react["default"].createElement("div", {
className: "".concat(prefixCls, "-content")
}, /*#__PURE__*/_react["default"].createElement("ul", null, renderChildren.map(function (child, idx) {
return /*#__PURE__*/_react["default"].createElement("li", {
key: idx,
style: {
left: getLeft(idx),
width: cardWidth,
transitionDuration: getDuration()
}
}, child);
})))) : children);
};
var _default = exports["default"] = Carousel;