vue+css如何實(shí)現(xiàn)圓環(huán)漸變儀表盤
整體效果

主要原理
漸變圓環(huán)
設(shè)置如下css代碼可實(shí)現(xiàn)出環(huán)形漸變效果
.box{
background:conic-gradient(from 0deg at 50% 50%,#eee 0deg,yelllow 180deg,red 360deg)
}
- 效果圖

添加圓角以及內(nèi)部圓形居中遮擋即可實(shí)現(xiàn)圓環(huán)效果
- 效果圖

儀表盤效果
添加若干個(gè)環(huán)繞圓點(diǎn)旋轉(zhuǎn)的元素,組成儀表盤,融合背景色將底色圓環(huán)覆蓋掉,就得到了儀表盤效果。
1.div結(jié)構(gòu)
<div class="scale">
<div
class="s-item"
v-for="item in 72"
:key="'item-' + item"
>
</div>
</div>2.scss
.scale {
border-radius: 50%;
width: 100%;
height: 100%;
position: absolute;
.s-item {
position: absolute;
width: 1px;
height: 2px;
background-color: #fff;
left:50%;
top: 0px;
transform-origin: 0 24px;
}
@for $i from 0 through 72 {
.s-item:nth-child(#{$i + 1}) {
transform: rotate($i * 5deg);
}
}
}- 形式圖

- 效果圖

全部代碼
<template>
<div
class="gauge"
:style="{
width: diameter + 'px',
height: diameter + 'px',
background: bgColor,
}"
>
<div class="cricle" ref="cricle">
<!-- 色塊圈 -->
<div
class="s-color"
:style="
follow
? {
background: `conic-gradient(from 0deg at 50% 50%,${
rampColor[0]
} 0deg,${rampColor[1]} ${value / 2}deg,${
rampColor[2]
} ${value}deg,${defaultColor} ${value}deg)`,
}
: {
background: `conic-gradient(from 0deg at 50% 50%,${rampColor[0]} 0deg,${rampColor[1]} 50%,${rampColor[2]}`,
}
"
>
<div
class="follow"
v-if="!follow"
:style="{
background: `conic-gradient(from 0deg at 50% 50%,transparent 0deg,transparent ${value}deg,${defaultColor} ${value}deg)`,
}"
></div>
<div
class="mask"
:style="{
width: `calc(100% - ${dotHeight}px *2)`,
height: `calc(100% - ${dotHeight}px *2)`,
background: bgColor,
}"
></div>
</div>
<!-- 拖動(dòng)按鈕 -->
<div
class="slider"
:style="{
transform: `rotate(${value}deg)`,
width: sliderDiameter + 'px',
height: `calc(50% - ${dotHeight / 2}px + ${sliderDiameter / 2}px)`,
left: `calc(50% - ${sliderDiameter / 2}px)`,
top: `calc((${sliderDiameter / 2}px - ${dotHeight / 2}px) *-1)`,
}"
>
<div
class="btn"
ref="slider"
:style="{
width: sliderDiameter + 'px',
height: sliderDiameter + 'px',
background: sliderColor,
}"
></div>
</div>
<!-- 儀表盤 -->
<div class="bar scale">
<div
class="s-item"
v-for="item in dotCount"
:key="'item-' + item"
:style="{
'transform-origin': `2px calc(${diameter}px/2 + 1px)`,
width: dotWidth + 'px',
height: diameter / 2 + 'px',
transform: `rotate(${(item * 360) / dotCount}deg)`,
background: bgColor,
}"
></div>
</div>
</div>
</div>
</template><script>
export default {
name: "gauge",
/** 組件參數(shù) */
props: {
/** 默認(rèn)值 */
default: {
type: Number,
default: 0,
},
/** 直徑 */
diameter: {
type: Number,
default: 200,
},
/** 點(diǎn)間隔 */
dotWidth: {
type: Number,
default: 4,
},
/** 點(diǎn)高度 */
dotHeight: {
type: Number,
default: 8,
},
/** 滑塊直徑 */
sliderDiameter: {
type: Number,
default: 20,
},
/** 滑塊顏色 */
sliderColor: {
type: String,
default: "red",
},
/** 點(diǎn)數(shù)量 */
dotCount: {
type: Number,
default: 72,
},
/** 漸變色 */
rampColor: {
type: Array,
default: function () {
return ["#ddd", "#faba2a", "#f24c4f"];
},
},
/** 環(huán)形默認(rèn)顏色 */
defaultColor: {
type: String,
default: "#ddd",
},
/** 背景顏色 */
bgColor: {
type: String,
default: "#fff",
},
/** 漸變跟隨 */
follow: {
type: Boolean,
default: true,
},
},
data() {
return {
value: 0,
};
},
methods: {
/** ## 組件方法 */
/** 獲取進(jìn)度 */
getValue(){
return this.value/360;
}
},
created() {
this.value = this.default;
},
mounted() {
/** 滑塊滑動(dòng)功能 */
this.$refs.slider.onmousedown = (e) => {
const cricle = this.$refs.cricle;
/** 獲取位置(坐標(biāo)軸原點(diǎn)) */
let client = cricle.getBoundingClientRect();
let x0 = client.x + cricle.offsetWidth / 2;
let y0 = client.y + cricle.offsetHeight / 2;
/** 阻止默認(rèn)事件 */
let ev = e || window.event;
ev.preventDefault ? ev.preventDefault() : (ev.returnValue = false);
/** 鼠標(biāo)移動(dòng) */
document.onmousemove = (el) => {
let move = el ? el : window.event;
/** 鼠標(biāo)位置 */
let x = move.x - x0;
let y = y0 - move.y;
/** 計(jì)算角度 */
let deg = (Math.atan(y / x) / 2 / Math.PI) * 360;
if (x >= 0) {
if (this.value >= 270) {
/** 象限跳躍優(yōu)化 */
this.value = 360;
} else {
this.value = 90 - deg;
}
} else {
if (this.value <= 90) {
this.value = 0;
} else {
this.value = 270 - deg;
}
}
};
/** 鼠標(biāo)松開 */
document.onmouseup = () => {
/** 取消訂閱鼠標(biāo)移動(dòng)事件 */
document.onmousemove = null;
document.onmouseup = null;
};
};
},
};
</script><style lang="scss" scoped>
.box {
width: 100%;
height: 100%;
position: absolute;
}
.gauge {
padding: 5px;
//background-color: white;
position: relative;
.cricle {
width: calc(100% - 10px);
height: calc(100% - 10px);
position: absolute;
left: 50%;
top: 50%;
transform: translateY(-50%) translate(-50%);
.slider {
//background-color: pink;
width: 20px;
height: calc(50% + 6px);
position: absolute;
z-index: 10;
overflow: hidden;
transform-origin: 50% 100%;
top: -6px;
transform: rotate(140deg);
left: calc(50% - 10px);
.btn {
position: absolute;
cursor: pointer;
top: 0px;
width: 20px;
height: 20px;
// background-color: red;
border-radius: 50%;
}
}
.s-color {
z-index: 5; //5
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
.follow{
@extend .box;
// position: absolute;
// width: calc(100% + 2px );
// height: calc(100% + 2px);
left:50%;
top:50%;
transform: translate(-50%,-50%);
z-index: 6;
border-radius: 50%;
}
.mask {
content: "";
display: block;
position: absolute;
//background-color: #fff;
z-index: 9;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
}
}
.bar {
transform: rotate(0deg);
transform-origin: 0 100px;
}
.scale {
border-radius: 50%;
width: calc(100% + 2px);
height: calc(100% + 2px);
position: absolute;
z-index: 9;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
.s-item {
position: absolute;
//background-color: #fff;
left: calc(50% - 2px);
top: 0px;
}
// @for $i from 0 through 72 {
// .s-item:nth-child(#{$i + 1}) {
// transform: rotate($i * 5deg);
// }
// }
}
}
}
</style>總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解基于mpvue微信小程序下載遠(yuǎn)程圖片到本地解決思路
這篇文章主要介紹了詳解基于mpvue微信小程序下載遠(yuǎn)程圖片到本地解決思路,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-05-05
vue中各選項(xiàng)及鉤子函數(shù)執(zhí)行順序詳解
今天小編就為大家分享一篇vue中各選項(xiàng)及鉤子函數(shù)執(zhí)行順序詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
Antd-vue Table組件添加Click事件,實(shí)現(xiàn)點(diǎn)擊某行數(shù)據(jù)教程
這篇文章主要介紹了Antd-vue Table組件添加Click事件,實(shí)現(xiàn)點(diǎn)擊某行數(shù)據(jù)教程,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-11-11
Vue模擬響應(yīng)式原理底層代碼實(shí)現(xiàn)的示例
最近去面試的人都會(huì)有這個(gè)體會(huì),去年面試官只問我怎么用vue,今年開始問我vue響應(yīng)式原理,本文就詳細(xì)的介紹一下2021-08-08
基于Vue2實(shí)現(xiàn)數(shù)字縱向滾動(dòng)效果
這篇文章主要為大家詳細(xì)介紹了如何基于Vue2實(shí)現(xiàn)數(shù)字縱向滾動(dòng)效果,從而達(dá)到顯示計(jì)時(shí)器滾動(dòng)效果,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03

