lm-noticebar
Version:
* 作者:kanghongyan * 邮箱:khongyan@gmail.com * 版本:**`1.0.3`**
148 lines (108 loc) • 3.75 kB
JavaScript
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