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