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