react實(shí)現(xiàn)可播放的進(jìn)度條
本文實(shí)例為大家分享了react實(shí)現(xiàn)可播放進(jìn)度條的具體代碼,供大家參考,具體內(nèi)容如下
實(shí)現(xiàn)的效果圖如下:
如果所示,點(diǎn)擊播放按鈕可以播放,進(jìn)度條表示進(jìn)度
功能描述:
1. 點(diǎn)擊播放按鈕可以播放,進(jìn)度條表示進(jìn)度
2. 點(diǎn)擊暫停,進(jìn)度條停止變化
3. 可點(diǎn)擊圓點(diǎn),進(jìn)行進(jìn)度拖拽
4. 點(diǎn)擊進(jìn)度條可調(diào)節(jié)進(jìn)度
以下是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>
定義一個(gè)最大的div來(lái)包裹播放按鈕和進(jìn)度條:
播放按鈕是兩個(gè)antd的icon,通過(guò)state中的autoPlay來(lái)控制顯示哪一個(gè)icon
進(jìn)度條的中定義一個(gè)外span,是進(jìn)度條的總長(zhǎng)度,在這個(gè)span里定義一個(gè)span,是中間的滑塊,再定義一個(gè)span是可拖拽的圓點(diǎn)
以下是這部分的css樣式代碼,只要小圓點(diǎn)使用的絕對(duì)定位:
.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%; ? ? ? ? } ? ? ? } ? ? } ? }
功能實(shí)現(xiàn)的思想:
1. 點(diǎn)擊進(jìn)度條可以實(shí)現(xiàn)進(jìn)度調(diào)整
原理:點(diǎn)擊進(jìn)度條獲取點(diǎn)擊事件的pageX屬性,然后通過(guò)減去進(jìn)度條左邊的margin來(lái)計(jì)算點(diǎn)擊的進(jìn)度條的位置,因?yàn)檎麄€(gè)頁(yè)面的左邊有一個(gè)tab切換,這個(gè)tab切換可以被隱藏,所以整個(gè)進(jìn)度條的寬度是不定的,所以進(jìn)度條的滑塊要使用百分比來(lái)實(shí)現(xiàn),保證在進(jìn)度條總寬度變化時(shí)滑塊的寬度按比例變化:
clcikLine = e => { ? ? const len = this.line.clientWidth / 24; ? ? // 將整個(gè)進(jìn)度條分為24份 ? ? const windowWidth = window.innerWidth - this.line.clientWidth - this.line.offsetLeft - 20; ? ? let lineWidth; ? ? if (windowWidth > 240) { ? ? ? // 當(dāng)導(dǎo)航顯示時(shí),計(jì)算整個(gè)滑塊的寬度要減去導(dǎo)航的寬度240px ? ? ? lineWidth = e.pageX - this.line.offsetLeft - 240; ? ? } else { ? ? ? lineWidth = e.pageX - this.line.offsetLeft; ? ? } ? ? // 將最終的滑塊寬度按百分比進(jìn)行轉(zhuǎn)換 ? ? const innerWidth = Math.round(lineWidth / len); ? ? this.inner.style.width = 100 / 24 * innerWidth + '%'; ? }
2. 點(diǎn)擊播放,進(jìn)度增加,點(diǎn)擊暫停,進(jìn)度停止
handlePlay = () => { ? ? // 設(shè)置播放按鈕 ? ? this.setState({ ? ? ? autoPlay: !this.state.autoPlay, ? ? }); ? ? // 清楚定時(shí)器 ? ? clearInterval(this.timer); ? ? ? setTimeout(() => { ? ? ? if (this.state.autoPlay) { ? ? ? ? const wrapWidth = this.line.clientWidth; ? ? ? ? const innerWidth = this.inner.clientWidth; ? ? ? ? if (innerWidth < wrapWidth) { ? ? ? ? ? this.timer = setInterval(() => { ? ? ? ? ? ? // 設(shè)置定時(shí)器,每1000毫秒執(zhí)行一次,每1000毫秒滑塊長(zhǎng)度增加進(jìn)度條的1%長(zhǎng)度 ? ? ? ? ? ? this.inner.style.width = Math.round(this.inner.clientWidth / this.line.clientWidth * 100) + 1 + '%'; ? ? ? ? ? ? // 每次獲得的增加的百分比長(zhǎng)度都進(jìn)行四舍五入 ? ? ? ? ? ? if (this.inner.clientWidth >= this.line.clientWidth) { ? ? ? ? ? ? ? // 當(dāng)滑塊的長(zhǎng)度大于等于進(jìn)度條的長(zhǎng)度時(shí),清楚定時(shí)器,并且關(guān)閉播放按鈕 ? ? ? ? ? ? ? clearInterval(this.timer); ? ? ? ? ? ? ? this.setState({ ? ? ? ? ? ? ? ? autoPlay: false ? ? ? ? ? ? ? }); ? ? ? ? ? ? } ? ? ? ? ? }, 1000); ? ? ? ? } else { ? ? ? ? ? // 當(dāng)滑塊寬度大于進(jìn)度條寬度時(shí),點(diǎn)擊播放按鈕,延時(shí)1000毫秒自動(dòng)關(guān)閉播放按鈕 ? ? ? ? ? setTimeout(() => { ? ? ? ? ? ? this.setState({ ? ? ? ? ? ? ? autoPlay: false ? ? ? ? ? ? }); ? ? ? ? ? }, 1000); ? ? ? ? } ? ? ? } ? ? }, 20); ? }
3. 圓點(diǎn)可以拖拽,調(diào)整進(jìn)度條進(jìn)度
這個(gè)功能中,使用了四個(gè)事件,分別是:onMouseMove、onMouseUp、onMouseLeave放在進(jìn)度條上,onMouseDown放在可拖拽的圓點(diǎn)上。
handleMouseDown = e => { ? ? // 鼠標(biāo)按下時(shí)打開(kāi)可拖功能 ? ? this.setState({ ? ? ? drag: true, ? ? }); ? } ? ? handleMouseMove = e => { ? ? // 當(dāng)可拖拽功能打開(kāi)時(shí) ? ? if (this.state.drag) { ? ? ? // 滑塊寬度小于進(jìn)度條寬度或大于0時(shí) ? ? ? if (this.inner.clientWidth <= this.line.clientWidth || this.inner.clientWidth <= 0) { ? ? ? ? // 將進(jìn)度條分為200份 ? ? ? ? const len = this.line.clientWidth / 200; ? ? ? ? // 判斷導(dǎo)航是否隱藏 ? ? ? ? const windowWidth = window.innerWidth - this.line.clientWidth - this.line.offsetLeft - 20; ? ? ? ? let lineWidth; ? ? ? ? if (windowWidth > 240) { ? ? ? ? ? // 導(dǎo)航未隱藏 ? ? ? ? ? lineWidth = e.pageX - this.line.offsetLeft - 240; ? ? ? ? } else { ? ? ? ? ? // 導(dǎo)航隱藏 ? ? ? ? ? lineWidth = e.pageX - this.line.offsetLeft; ? ? ? ? } ? ? ? ? const innerWidth = Math.round(lineWidth / len); ? ? ? ? // 滑塊寬度每次增加或減少0.5%的寬度 ? ? ? ? this.inner.style.width = 0.5 * innerWidth + '%'; ? ? ? } ? ? } ? } ? ? handleMouseUp = e => { ? ? // 當(dāng)鼠標(biāo)放開(kāi)或者離開(kāi)進(jìn)度條時(shí)關(guān)閉拖拽功能 ? ? this.setState({ ? ? ? drag: false, ? ? }); ? }
以上基本實(shí)現(xiàn)了這個(gè)功能,播放這一塊還會(huì)再加?xùn)|西,后期再加入
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解決React報(bào)錯(cuò)React.Children.only expected to rece
這篇文章主要為大家介紹了React報(bào)錯(cuò)React.Children.only expected to receive single React element child分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01react滾動(dòng)加載useInfiniteScroll?詳解
使用useInfiniteScroll?hook可以處理檢測(cè)用戶(hù)何時(shí)滾動(dòng)到頁(yè)面底部的邏輯,并觸發(fā)回調(diào)函數(shù)以加載更多數(shù)據(jù),它還提供了一種簡(jiǎn)單的方法來(lái)管理加載和錯(cuò)誤消息的狀態(tài),今天通過(guò)實(shí)例代碼介紹下react滾動(dòng)加載useInfiniteScroll?相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧2023-09-09React通過(guò)hook實(shí)現(xiàn)封裝表格常用功能
這篇文章主要為大家詳細(xì)介紹了React通過(guò)hook封裝表格常用功能的使用,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下2023-12-12flouting?ui定位組件完美替代ant?deisgn使用詳解
這篇文章主要為大家介紹了flouting?ui定位組件完美替代ant?deisgn使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11react實(shí)現(xiàn)動(dòng)態(tài)表單
這篇文章主要為大家詳細(xì)介紹了react實(shí)現(xiàn)動(dòng)態(tài)表單,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08React Hooks與setInterval的踩坑問(wèn)題小結(jié)
本文主要介紹了React Hooks與setInterval的踩坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04React合成事件及Test Utilities在Facebook內(nèi)部進(jìn)行測(cè)試
這篇文章主要介紹了React合成事件及Test Utilities在Facebook內(nèi)部進(jìn)行測(cè)試,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12