UNPKG

lm-noticebar

Version:

* 作者:kanghongyan * 邮箱:khongyan@gmail.com * 版本:**`1.0.3`**

199 lines (139 loc) 5.05 kB
import React from 'react' import PropTypes from 'prop-types' const gap = 2; // 留出dis间隔 class AutoPlay extends React.PureComponent { constructor() { super(); this.state = {}; this.timer = null; this.loopIndex = 0; } componentDidMount() { let contWh = this.dom.children[0].getBoundingClientRect().width; let scrollWh = this.dom.children[0].scrollWidth; if (Math.ceil(scrollWh) > Math.ceil(contWh)) { this.startPlay(this.dom.children[0]) } } componentWillUnmount () { clearTimeout(this.timer); } startPlay = (dom) => { let contWh = dom.getBoundingClientRect().width; // container长度 let domWh = dom.scrollWidth; // 内容长度 /** * * @param scrollWh 需要滚动的距离 * @param duration 延迟时间 * @private */ const _play = (scrollWh, duration) => { this.timer = setTimeout(() => { const currentTransform = window.getComputedStyle(dom).transform || window.getComputedStyle(dom).webkitTransform; if (currentTransform !== 'none' && +currentTransform.split(',')[4].trim() <= (-domWh)) { // 滚动完毕: 将内容移动到最右侧、立即_play const posScale = this._getPositionScale(this.loopIndex, 1); this._resetStyle(posScale, () => { _play(domWh + contWh * posScale - gap, 60) }) } else { let time = this.props.speed * scrollWh; this.setState({ 'WebkitTransition': `-webkit-transform ${time}s linear`, 'transition': `transform ${time}s linear`, 'WebkitTransform': `translate3d(-${domWh}px, 0, 0)`, 'transform': `translate3d(-${domWh}px, 0, 0)` }, () => { // 每隔500ms检查一次是否已经滚动完毕 _play(domWh, 500) }) } }, duration) }; // _play(domWh, 1000) this._initStyle((posScale) => { _play(domWh + contWh * posScale , 1000); }) }; _cloneChildren(children) { const {height, style} = this.props; const isObjectChildren = Object.prototype.toString.call(children) === '[object Object]'; const childrenArr = isObjectChildren ? [children] : children return childrenArr.map((item, index) => { return React.cloneElement(item, { key: index, style: { height: height, ...style, ...this.state, whiteSpace: 'nowrap', } }) }) } _initStyle = (cd = () => {}) => { const { startPosition } = this.props; if (!startPosition) { return cd(0); } const posScale = this._percentToDecimal(startPosition, 0); this._resetStyle(posScale, cd) } _resetStyle = (scale, cd = () => {}) => { const contWh = this.dom.children[0].getBoundingClientRect().width; // container长度 const _gap = scale !== 0 ? gap : 0; this.setState({ 'WebkitTransition': 'none', 'transition': `none`, 'WebkitTransform': `translate3d(${contWh * scale - _gap}px, 0, 0)`, 'transform': `translate3d(${contWh * scale - _gap}px, 0, 0)`, }, () => { cd(scale); }) } _getPositionScale = (loopIndex, defaultValue = 0) => { const { loopPosition = [] } = this.props; if (loopPosition && loopPosition.length) { this.loopIndex = (loopIndex + 1) >= loopPosition.length ? 0 : loopIndex + 1; return loopPosition.length > loopIndex ? this._percentToDecimal(loopPosition[loopIndex], defaultValue) : defaultValue; } return defaultValue; } _percentToDecimal = (percent, defaultValue = 0) => { try { let str = (percent + '').replace("%", ""); return str / 100; } catch(e) { return defaultValue; } } render() { const { children, } = this.props; return ( <div className="m-autoplay-wrap" style={{overflow: 'hidden',}} ref={(ele) => { this.dom=ele ; }} > { this._cloneChildren(children) } </div> ) } } AutoPlay.propTypes = { speed: PropTypes.number, style: PropTypes.object, height: PropTypes.number }; AutoPlay.defaultProps = { speed: 1.0 / 20, // 每秒移动多少像素 style: {}, height: 20 }; export default AutoPlay