Vue + CSS實(shí)現(xiàn)漸變柵格進(jìn)度條效果
進(jìn)度條作為可視化大屏系統(tǒng)中展示數(shù)據(jù)狀態(tài)的關(guān)鍵元素,其視覺效果直接影響用戶的使用體驗(yàn),而傳統(tǒng)的進(jìn)度條往往呈現(xiàn)出固定的樣式,缺乏視覺吸引力。在這種場(chǎng)景下,一種基于Vue和CSS實(shí)現(xiàn)漸變柵格進(jìn)度條的方法應(yīng)運(yùn)而生,該方法將進(jìn)度條劃分為多個(gè)柵格單元,每個(gè)單元格顏色漸變并且連續(xù),可以根據(jù)不同的場(chǎng)景配置個(gè)性化屬性,具有極高的靈活度和交互性,可以調(diào)整顏色、柵格數(shù)量、間隔、寬度、高度、圓角、數(shù)值、標(biāo)簽、刻度等屬性,并同時(shí)具有平滑的過渡效果,特別適用于可視化大屏系統(tǒng)中。
1 原理
1.1 劃分柵格單元
首先定義一個(gè)父容器,用于容納所有柵格,然而柵格的數(shù)量不定,所以需要設(shè)置彈性布局,使得任意數(shù)量的柵格能夠自動(dòng)均勻平鋪。樣式合適位置預(yù)留響應(yīng)式變量,保證屬性的可配置性。
與此同時(shí),給每個(gè)柵格加上平滑的過渡動(dòng)畫,確保每次數(shù)據(jù)發(fā)生變化引起圖表變化時(shí)能夠平滑過渡,而并非跳躍式突變,增強(qiáng)了用戶的交互體驗(yàn)和視覺感受,同時(shí)能夠引導(dǎo)用戶注意力,突出變化部分的重要內(nèi)容或功能。如下圖。
1.2 顏色漸變
為了解決漸變柵格百分比條中柵格之間存在空隙而顏色可以連續(xù)的問題,需要利用CSS的兩個(gè)重要屬性:background屬性和偽元素。
首先,將每個(gè)柵格的背景色設(shè)置相同。接著,調(diào)整background的size為柵格數(shù)量倍的寬度,調(diào)整position來指定背景的位置,將每個(gè)柵格的背景色都在上一個(gè)柵格的基礎(chǔ)上,偏移一個(gè)柵格的距離。為了實(shí)現(xiàn)這一效果,還需將柵格設(shè)置為溢出隱藏,并確保背景色不重復(fù),如下圖。
由于進(jìn)度條分為已完成和未完成兩部分,而上述過程僅實(shí)現(xiàn)了所有柵格的連續(xù)漸變,無法突顯出進(jìn)度,所以需要控制漸變色在指定位置結(jié)束。然而,目前的方案似乎無法實(shí)現(xiàn)漸變色截?cái)嗟男Ч?,因此我們嘗試使用遮罩。具體而言,就是將每個(gè)柵格都增加一個(gè)偽元素,將其完全覆蓋在柵格上,根據(jù)計(jì)算的比例,已完成部分的偽元素背景色設(shè)置為透明,將漸變色顯示出來,未完成部分的則設(shè)置為默認(rèn)背景色,將下方的漸變色進(jìn)行遮罩。
偽元素可以通過CSS自定義屬性進(jìn)行變量的綁定,在字符串前加上兩根連接線“–”,可以將該字符串聲明為CSS自定義屬性,然后通過var()函數(shù)讀取變量,最后使用Vue的動(dòng)態(tài)style和模板字符串傳入,這樣,這個(gè)動(dòng)態(tài)屬性便可以根據(jù)數(shù)據(jù)的變化動(dòng)態(tài)的渲染偽元素了。如下圖。
1.3 標(biāo)簽與刻度
為了最大程度上不影響原有柵格進(jìn)度條的層級(jí)結(jié)構(gòu),標(biāo)簽與刻度這種附加屬性我們選擇了絕對(duì)定位。新建一個(gè)盒子,保持與柵格的父容器寬度相同,添加進(jìn)度開始值、結(jié)束值作為左右刻度,結(jié)合當(dāng)前值可以計(jì)算出進(jìn)度的百分比,同時(shí)根據(jù)柵格間距和當(dāng)前值等屬性可以計(jì)算出標(biāo)簽的位置。如下圖。
2 實(shí)現(xiàn)方法
有了前面的思路鋪墊,現(xiàn)在來著手實(shí)現(xiàn)。
2.1 可配置屬性
首先我們需要配置用戶可自定義修改的屬性,并給予默認(rèn)值,這些屬性通過綁定響應(yīng)式變量的方式來實(shí)現(xiàn)實(shí)時(shí)刷新。
最小值、最大值即進(jìn)度條最左側(cè)和最右側(cè)的位置,默認(rèn)為0和2,當(dāng)前值即進(jìn)度所在的位置,默認(rèn)為1.66。
柵格數(shù)量指的是總共劃分多少個(gè)柵格,數(shù)量不同,每個(gè)柵格所代表的比例也將發(fā)生改變,默認(rèn)為10。
柵格間距是每個(gè)柵格之間空余的距離,單位為百分比,默認(rèn)為2%。
漸變色是從起始顏色到終止顏色的色彩變化,形成一種流暢的過渡效果,增強(qiáng)視覺吸引力,默認(rèn)為#6AE5BB到#3C7DDF的過渡。
背景色則可以認(rèn)為是進(jìn)度未完成的部分,默認(rèn)使用顏色#AAAAAA作為區(qū)分。
數(shù)值的展示方式分為真實(shí)值和百分比值兩種,切換后標(biāo)簽和刻度隨之改變,其字體、字號(hào)、顏色、小數(shù)點(diǎn)也可自定義。
此外,柵格的圓角、高度、標(biāo)簽的偏移及其顯隱等屬性也在相應(yīng)位置插入了變量提供給用戶自定義修改。
2.2 數(shù)據(jù)初始化
在頁面加載之前,需要進(jìn)行數(shù)據(jù)的初始化,提前計(jì)算部分屬性。
通過最小值、最大值、當(dāng)前值計(jì)算出當(dāng)前值所占比例(valuePercent),默認(rèn)比例為(1.66-0)/(2-0)*100%=83%。
通過柵格的個(gè)數(shù)計(jì)算每個(gè)柵格代表的比例(perGridPercent),默認(rèn)每個(gè)柵格代表100%/10=10%。
通過valuePercent和perGridPercent得到完整顯示漸變色的柵格個(gè)數(shù)(completeGridNum)。Math.floor(83%/10%)=8,也就意味著前8個(gè)柵格的偽元素遮罩層的背景色,可以直接設(shè)置透明。
而余下的一個(gè)不足以完整顯示漸變色的柵格,我們需要計(jì)算漸變色的部分占整個(gè)柵格的比例(remainingGridPercent)。用completeGridNum乘以perGridPercent,得到完整顯示的比例,再用valuePercent減去完整顯示的比例,得到剩余需要覆蓋的部分,最后除以perGridPercent,即(83%-8*10%)/10%=30%,也就是說,余下的漸變色只需占據(jù)一個(gè)柵格的30%。
通過柵格間隔(interval)和柵格數(shù)量(number)得到每個(gè)柵格的實(shí)際寬度(perGridWidth),即用100%減去interval乘以number-1,得到所有柵格的實(shí)際寬度,隨后除以number,interval默認(rèn)為2%,(100%-2%*(10-1))/10=8.2%。Vue的計(jì)算屬性可以根據(jù)依賴關(guān)系進(jìn)行計(jì)算并緩存,所以我們可以用computed來計(jì)算柵格的實(shí)際寬度,由于柵格的間隔和數(shù)量都是響應(yīng)式變量,所以寬度也是響應(yīng)式的。
通過(completeGridNum+ remainingGridPercent)perGridWidth+completeGridNuminterval,不難算出標(biāo)簽絕對(duì)定位下距離左端的位置,即(8+30%)8.2%+82%=84.06%。
2.3 開始繪制
通過Vue的v-for指令,得到指定數(shù)量的柵格。通過:style=“`–barWidth:${perGridWidth}`”,將實(shí)際寬度傳入組件內(nèi)部,然后使用該值給柵格和偽元素遮罩的寬度賦值,具體為"width:var(–barWidth)"。
接下來,利用CSS從左至右的線性漸變色,均勻的平鋪到所有的柵格上,即 “background:linear-gradient(to right,${beginColor},${overColor}) ${(i-1)perGridWidth}/${number100}% no-repeat”。這里的beginColor,overColor為漸變起始和終止顏色,i為柵格的序號(hào)。每個(gè)柵格的背景色都為擴(kuò)展了number倍的漸變色,不同的則是各自的偏移量,都偏移了(i-1)*perGridWidth。
然后就是添加遮罩層,通過computed計(jì)算屬性,可以根據(jù)i值大小,動(dòng)態(tài)返回背景色的字符串。當(dāng)小于等于completeGridNum時(shí),返回透明色;當(dāng)?shù)扔赾ompleteGridNum+1時(shí),通過線性漸變,按百分比分配透明色和背景色,即`linear-gradient(to right,transparent r e m a i n i n g G r i d P e r c e n t , {remainingGridPercent}, remainingGridPercent,{backColor} ${remainingGridPercent})`,其中backColor為柵格背景色,意味著從左側(cè)開始,直到達(dá)到remainingGridPercent指定的位置時(shí),顏色保持透明色。在remainingGridPercent位置之后,顏色保持為背景色;其他情況下返回背景色。
最后,為柵格和其偽元素遮罩添加"transition: all 1s"的過渡動(dòng)畫。
核心代碼
<div class="grid-progress-container"> <div class="grid-progress-bar" v-for="i in state.mergedConfig.bar.number" :style="`--barRadius:${state.mergedConfig.bar.radius}px; --barHeight:${state.mergedConfig.bar.height}px; --barWidth:${perGridWidth}%; --barBackground:${renderBack(i)}; background:linear-gradient(to right,${state.mergedConfig.bar.preColor},${state.mergedConfig.bar.suffixColor}) ${ (i - 1) * perGridWidth }% / ${state.mergedConfig.bar.number * 100 + '%'} no-repeat;`" ></div> </div> const initData = () => { // 當(dāng)前值所占比例(100%) state.valuePercent = ((state.mergedConfig.dataset.value - state.mergedConfig.dataset.min) / (state.mergedConfig.dataset.max - state.mergedConfig.dataset.min)) * 100 // 每一個(gè)柵格比例(100%) state.perGridPercent = 100 / state.mergedConfig.bar.number // 完整渲染的柵格個(gè)數(shù) state.renderGridNum = Math.floor(state.valuePercent / state.perGridPercent) // 不完整渲染的柵格剩余比例(1) state.remainingGridPercent = (state.valuePercent - state.renderGridNum * state.perGridPercent) / state.perGridPercent } const perGridWidth = computed(() => { return (100 - state.mergedConfig.bar.interval * (state.mergedConfig.bar.number - 1)) / state.mergedConfig.bar.number }) const renderBack = (i: number) => { if (state.remainingGridPercent === 0) { if (i <= state.renderGridNum) return 'transparent' else return `${state.mergedConfig.bar.backColor}` } else { if (i <= state.renderGridNum) { return 'transparent' } else if (i === state.renderGridNum + 1) { return `linear-gradient(to right,transparent ${state.remainingGridPercent * 100}%,${ state.mergedConfig.bar.backColor } ${state.remainingGridPercent * 100}%)` } else { return `${state.mergedConfig.bar.backColor}` } } }
.grid-progress-container { width: 100%; padding: 60px; display: flex; justify-content: space-between; .grid-progress-bar { height: var(--barHeight); width: var(--barWidth); border-radius: var(--barRadius); transition: all 1s; position: relative; &::before { position: absolute; content: ''; height: 100%; width: 100%; background: var(--barBackground); border-radius: var(--barRadius); transition: all 1s; } } }
到此這篇關(guān)于Vue + CSS實(shí)現(xiàn)漸變柵格進(jìn)度條的文章就介紹到這了,更多相關(guān)vue漸變柵格進(jìn)度條內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue實(shí)現(xiàn)漸變色進(jìn)度條的代碼
- vue實(shí)現(xiàn)簡(jiǎn)潔文件上傳進(jìn)度條功能
- Vue項(xiàng)目實(shí)現(xiàn)文件下載進(jìn)度條功能
- vue進(jìn)度條組件實(shí)現(xiàn)代碼(可拖拽可點(diǎn)擊)
- vue項(xiàng)目中如何使用video.js實(shí)現(xiàn)視頻播放與視頻進(jìn)度條打點(diǎn)
- Vue?實(shí)現(xiàn)接口進(jìn)度條示例詳解
- Vue使用NProgress實(shí)現(xiàn)頁面頂部的進(jìn)度條顯示效果
- Vue如何實(shí)現(xiàn)簡(jiǎn)單的時(shí)間軸與時(shí)間進(jìn)度條
- Vue+Axios實(shí)現(xiàn)文件上傳自定義進(jìn)度條
- Vue文件下載進(jìn)度條的實(shí)現(xiàn)過程
相關(guān)文章
Vue監(jiān)聽使用方法和過濾器實(shí)現(xiàn)
這篇文章主要介紹了Vue監(jiān)聽使用方法和過濾器實(shí)現(xiàn),過濾器為頁面中數(shù)據(jù)進(jìn)行強(qiáng)化,具有局部過濾器和全局過濾器2022-06-06淺談Vue-cli單文件組件引入less,sass,css樣式的不同方法
下面小編就為大家分享一篇淺談Vue-cli單文件組件引入less,sass,css樣式的不同方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-03-03vue項(xiàng)目創(chuàng)建步驟及路由router
本文主要給大家分享了vue項(xiàng)目的創(chuàng)建步驟以及vue路由router的相關(guān)知識(shí)點(diǎn),非常的實(shí)用,有需要的小伙伴可以來參考下2020-01-01Vue 中 a標(biāo)簽上href無法跳轉(zhuǎn)的解決方式
今天小編大家分享一篇Vue 中 a標(biāo)簽上href無法跳轉(zhuǎn)的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-11-11