react实现可播放的进度条
作者:何良语
这篇文章主要为大家详细介绍了react实现可播放的进度条,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了react实现可播放进度条的具体代码,供大家参考,具体内容如下
实现的效果图如下:
如果所示,点击播放按钮可以播放,进度条表示进度
功能描述:
1. 点击播放按钮可以播放,进度条表示进度
2. 点击暂停,进度条停止变化
3. 可点击圆点,进行进度拖拽
4. 点击进度条可调节进度
以下是render部分代码:
<div className="play" ref={play => { this.play = play; }}> <span className="palyButton" onClick={this.handlePlay}><Icon type="caret-right" style={{ display: this.state.autoPlay ? 'none' : 'inline-block' }} /><Icon type="pause" style={{ display: this.state.autoPlay ? 'inline-block' : 'none' }} /></span> <span className="lineWrap" onMouseMove={this.handleMouseMove} onMouseUp={this.handleMouseUp} onMouseLeave={this.handleMouseUp} onClick={this.clcikLine} ref={line => { this.line = line; }}> <span className="lineInner" ref={inner => { this.inner = inner; }}> <span className="lineDot" onMouseDown={this.handleMouseDown} ref={dot => { this.dot = dot; }} /> </span> </span> </div>
定义一个最大的div来包裹播放按钮和进度条:
播放按钮是两个antd的icon,通过state中的autoPlay来控制显示哪一个icon
进度条的中定义一个外span,是进度条的总长度,在这个span里定义一个span,是中间的滑块,再定义一个span是可拖拽的圆点
以下是这部分的css样式代码,只要小圆点使用的绝对定位:
.play{ width: 100%; height: 30%; padding: 0 40px; margin-top: 15px; .palyButton{ margin-right: 22px; cursor: pointer; color: #1DDD92; font-size: 20px; i:last-child{ font-weight: bold; } } .lineWrap{ width: 95%; height: 14px; background-color: #2A2F4D; display: inline-block; cursor: pointer; .lineInner{ width: 10%; height: 100%; display: inline-block; background-color: #1DDD92; position: relative; .lineDot{ position: absolute; top: -3px; right: -10px; width: 20px; height: 20px; display: inline-block; background-color: #1DDD92; border: 1px solid #fff; border-radius: 50%; } } } }
功能实现的思想:
1. 点击进度条可以实现进度调整
原理:点击进度条获取点击事件的pageX属性,然后通过减去进度条左边的margin来计算点击的进度条的位置,因为整个页面的左边有一个tab切换,这个tab切换可以被隐藏,所以整个进度条的宽度是不定的,所以进度条的滑块要使用百分比来实现,保证在进度条总宽度变化时滑块的宽度按比例变化:
clcikLine = e => { const len = this.line.clientWidth / 24; // 将整个进度条分为24份 const windowWidth = window.innerWidth - this.line.clientWidth - this.line.offsetLeft - 20; let lineWidth; if (windowWidth > 240) { // 当导航显示时,计算整个滑块的宽度要减去导航的宽度240px lineWidth = e.pageX - this.line.offsetLeft - 240; } else { lineWidth = e.pageX - this.line.offsetLeft; } // 将最终的滑块宽度按百分比进行转换 const innerWidth = Math.round(lineWidth / len); this.inner.style.width = 100 / 24 * innerWidth + '%'; }
2. 点击播放,进度增加,点击暂停,进度停止
handlePlay = () => { // 设置播放按钮 this.setState({ autoPlay: !this.state.autoPlay, }); // 清楚定时器 clearInterval(this.timer); setTimeout(() => { if (this.state.autoPlay) { const wrapWidth = this.line.clientWidth; const innerWidth = this.inner.clientWidth; if (innerWidth < wrapWidth) { this.timer = setInterval(() => { // 设置定时器,每1000毫秒执行一次,每1000毫秒滑块长度增加进度条的1%长度 this.inner.style.width = Math.round(this.inner.clientWidth / this.line.clientWidth * 100) + 1 + '%'; // 每次获得的增加的百分比长度都进行四舍五入 if (this.inner.clientWidth >= this.line.clientWidth) { // 当滑块的长度大于等于进度条的长度时,清楚定时器,并且关闭播放按钮 clearInterval(this.timer); this.setState({ autoPlay: false }); } }, 1000); } else { // 当滑块宽度大于进度条宽度时,点击播放按钮,延时1000毫秒自动关闭播放按钮 setTimeout(() => { this.setState({ autoPlay: false }); }, 1000); } } }, 20); }
3. 圆点可以拖拽,调整进度条进度
这个功能中,使用了四个事件,分别是:onMouseMove、onMouseUp、onMouseLeave放在进度条上,onMouseDown放在可拖拽的圆点上。
handleMouseDown = e => { // 鼠标按下时打开可拖功能 this.setState({ drag: true, }); } handleMouseMove = e => { // 当可拖拽功能打开时 if (this.state.drag) { // 滑块宽度小于进度条宽度或大于0时 if (this.inner.clientWidth <= this.line.clientWidth || this.inner.clientWidth <= 0) { // 将进度条分为200份 const len = this.line.clientWidth / 200; // 判断导航是否隐藏 const windowWidth = window.innerWidth - this.line.clientWidth - this.line.offsetLeft - 20; let lineWidth; if (windowWidth > 240) { // 导航未隐藏 lineWidth = e.pageX - this.line.offsetLeft - 240; } else { // 导航隐藏 lineWidth = e.pageX - this.line.offsetLeft; } const innerWidth = Math.round(lineWidth / len); // 滑块宽度每次增加或减少0.5%的宽度 this.inner.style.width = 0.5 * innerWidth + '%'; } } } handleMouseUp = e => { // 当鼠标放开或者离开进度条时关闭拖拽功能 this.setState({ drag: false, }); }
以上基本实现了这个功能,播放这一块还会再加东西,后期再加入
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。