@nutui/nutui-react
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
113 lines (112 loc) • 4.47 kB
JavaScript
import { _ as _object_spread } from "@swc/helpers/_/_object_spread";
import { _ as _object_spread_props } from "@swc/helpers/_/_object_spread_props";
import { _ as _object_without_properties } from "@swc/helpers/_/_object_without_properties";
import React, { useEffect, useRef, useImperativeHandle } from "react";
import classNames from "classnames";
import { ComponentDefaults } from "../../utils/typings";
var defaultProps = _object_spread_props(_object_spread({}, ComponentDefaults), {
list: [],
interval: 500,
loop: true,
duration: 3000,
rows: 3,
gapY: 10
});
var classPrefix = "nut-barrage";
var InternalBarrage = function(props, ref) {
var _ref = _object_spread({}, defaultProps, props), className = _ref.className, interval = _ref.interval, loop = _ref.loop, list = _ref.list, duration = _ref.duration, rows = _ref.rows, gapY = _ref.gapY, restProps = _object_without_properties(_ref, [
"className",
"interval",
"loop",
"list",
"duration",
"rows",
"gapY"
]);
var barrageBody = useRef(null);
var barrageContainer = useRef(null);
var barrageCWidth = useRef(0);
var timer = useRef(0);
var index = useRef(0);
var times = useRef([]);
var historyIndex = useRef(-1);
var classes = classNames(classPrefix, className);
useImperativeHandle(ref, function() {
return {
add: function(word) {
var _index = index.current % list.length;
if (!loop && index.current === list.length) {
list.splice(list.length, 0, word);
} else {
list.splice(_index, 0, word);
}
}
};
});
useEffect(function() {
if (barrageBody.current) {
barrageCWidth.current = barrageBody.current.offsetWidth;
}
setTimeout(function() {
var _barrageBody_current;
(_barrageBody_current = barrageBody.current) === null || _barrageBody_current === void 0 ? void 0 : _barrageBody_current.style.setProperty('--move-distance', "-".concat(barrageCWidth.current, "px"));
index.current = 0;
run();
}, 300);
return function() {
clearInterval(timer.current);
};
}, [
list
]);
var run = function() {
clearInterval(timer.current);
var intervalCache = interval;
var _index = (loop ? index.current % list.length : index.current) % rows;
var result = times.current[_index] - rows * interval;
if (result > 0) {
intervalCache += result;
}
timer.current = window.setTimeout(function() {
play();
}, intervalCache);
};
var play = function() {
if (!loop && index.current >= list.length) {
return;
}
var _index = loop ? index.current % list.length : index.current;
var el = document.createElement("div");
var currentIndex = _index % rows;
if (currentIndex <= historyIndex.current || historyIndex.current === 3 && currentIndex !== 0 || Math.abs(currentIndex - historyIndex.current) !== 1) {
currentIndex = historyIndex.current + 1 >= rows ? 0 : historyIndex.current + 1;
}
historyIndex.current = currentIndex;
el.innerHTML = list[_index];
el.classList.add('barrage-item');
barrageContainer.current.appendChild(el);
var width = el.offsetWidth;
var height = el.offsetHeight;
el.classList.add('move');
var elScrollDuration = Math.ceil(width / barrageCWidth.current * duration);
times.current[currentIndex] = elScrollDuration;
el.style.animationDuration = "".concat(duration + elScrollDuration, "ms");
el.style.top = "".concat(currentIndex * (height + gapY) + 20, "px");
el.style.width = "".concat(width, "px");
el.addEventListener('animationend', function() {
;
barrageContainer.current.removeChild(el);
});
index.current++;
run();
};
return /*#__PURE__*/ React.createElement("div", _object_spread({
className: classes,
ref: barrageBody
}, restProps), /*#__PURE__*/ React.createElement("div", {
ref: barrageContainer,
className: "bContainer"
}));
};
export var Barrage = /*#__PURE__*/ React.forwardRef(InternalBarrage);
Barrage.displayName = 'NutBarrage';