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)文章
vue router-link下劃線和顏色問(wèn)題及解決
這篇文章主要介紹了vue router-link下劃線和顏色問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08詳解基于mpvue微信小程序下載遠(yuǎn)程圖片到本地解決思路
這篇文章主要介紹了詳解基于mpvue微信小程序下載遠(yuǎn)程圖片到本地解決思路,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05vue中各選項(xiàng)及鉤子函數(shù)執(zhí)行順序詳解
今天小編就為大家分享一篇vue中各選項(xiàng)及鉤子函數(shù)執(zhí)行順序詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08Antd-vue Table組件添加Click事件,實(shí)現(xiàn)點(diǎn)擊某行數(shù)據(jù)教程
這篇文章主要介紹了Antd-vue Table組件添加Click事件,實(shí)現(xiàn)點(diǎn)擊某行數(shù)據(jù)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11Vue模擬響應(yīng)式原理底層代碼實(shí)現(xiàn)的示例
最近去面試的人都會(huì)有這個(gè)體會(huì),去年面試官只問(wèn)我怎么用vue,今年開始問(wèn)我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