UNPKG

lm-noticebar

Version:

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

148 lines (108 loc) 3.75 kB
import React from 'react' import PropTypes from 'prop-types' class AutoPlay extends React.PureComponent { constructor() { super(); this.state = { currentSlide: 0 }; this.timer = null; } componentDidMount() { const {children, height} = this.props; this.allSlides = React.Children.count(children); if (this.props.useLineHeight) { const contHeight = this.dom.getBoundingClientRect().height; const firstChildHeight = this.dom.children[0].getBoundingClientRect().height; this.allSlides = Math.ceil((contHeight - firstChildHeight + height) / height) - 1; } this.allSlides > 1 && this.startPlay(this.state.currentSlide) } componentWillUnmount () { clearTimeout(this.timer); } startPlay(startIndex, time) { const { speed = 3000 } = this.props; this.timer = setTimeout(() => { if (startIndex < this.allSlides) { this.setState({ currentSlide: startIndex + 1 }, () => { this.startPlay(startIndex + 1, speed) }) } else { clearTimeout(this.timer); this.setState({ currentSlide: 0 }); this.startPlay(0, 100) } }, time || speed) } getStyle() { const { height = 18 } = this.props; let ht = height * this.state.currentSlide + 'px'; if (this.state.currentSlide === 0) { return { WebkitTransform: `translate3d(0, 0, 0)`, transform: `translate3d(0, 0, 0)`, WebkitTransition: 'none', transition: 'none' } } return { WebkitTransform: `translate3d(0, -${ht}, 0)`, transform: `translate3d(0, -${ht}, 0)` } } _cloneChildren(children) { const {height, useLineHeight} = this.props; return children.map((item, index) => { return React.cloneElement(item, { key: index, style: { ...(useLineHeight ? {lineHeight: `${height}px`} : {height: `${height}px`}), ...item.props.style } }) }) } render() { const { children, useLineHeight } = this.props; // todo: 默认在useLineHeight情况下数据会多余一行, 优化 const isObjectChildren = Object.prototype.toString.call(children) === '[object Object]'; const childrenCount = React.Children.count(children); const childrenArr = childrenCount === 1 && isObjectChildren? [children] : children; return ( <div className="m-autoplay-wrap" ref={ (dom) => {this.dom = dom} } style={{ WebkitTransition: '-webkit-transform 1s', transition: 'transform 1s', ...(this.getStyle()), overflow: 'hidden', }} > { childrenCount > 1 || useLineHeight ? this._cloneChildren(childrenArr.concat(childrenArr[0])) : children } </div> ) } } AutoPlay.propTypes = { height: PropTypes.number, speed: PropTypes.number, useLineHeight: PropTypes.bool // 适用于每条数据数据过多情况下,用lineHeight表示height }; AutoPlay.defaultProps = { height: 18, speed: 3000, useLineHeight: false }; export default AutoPlay