当前位置: 代码网 > it编程>编程语言>Javascript > vue+css如何实现圆环渐变仪表盘

vue+css如何实现圆环渐变仪表盘

2024年09月08日 Javascript 我要评论
整体效果主要原理渐变圆环设置如下css代码可实现出环形渐变效果.box{ background:conic-gradient(from 0deg at 50% 50%,#eee 0deg,yel

整体效果

主要原理

渐变圆环

设置如下css代码可实现出环形渐变效果

.box{
    background:conic-gradient(from 0deg at 50% 50%,#eee 0deg,yelllow 180deg,red 360deg)
}
  • 效果图

添加圆角以及内部圆形居中遮挡即可实现圆环效果

  • 效果图

仪表盘效果

添加若干个环绕圆点旋转的元素,组成仪表盘,融合背景色将底色圆环覆盖掉,就得到了仪表盘效果。

1.div结构

<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>
      <!-- 拖动按钮 -->
      <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",
/** 组件参数  */
  props: {
    /** 默认值 */
    default: {
      type: number,
      default: 0,
    },
    /** 直径 */
    diameter: {
      type: number,
      default: 200,
    },
    /** 点间隔 */
    dotwidth: {
      type: number,
      default: 4,
    },
    /** 点高度 */
    dotheight: {
      type: number,
      default: 8,
    },
    /** 滑块直径 */
    sliderdiameter: {
      type: number,
      default: 20,
    },
    /** 滑块颜色 */
    slidercolor: {
      type: string,
      default: "red",
    },
    /** 点数量 */
    dotcount: {
      type: number,
      default: 72,
    },
    /** 渐变色 */
    rampcolor: {
      type: array,
      default: function () {
        return ["#ddd", "#faba2a", "#f24c4f"];
      },
    },
    /** 环形默认颜色 */
    defaultcolor: {
      type: string,
      default: "#ddd",
    },
    /** 背景颜色 */
    bgcolor: {
      type: string,
      default: "#fff",
    },
    /** 渐变跟随 */
    follow: {
      type: boolean,
      default: true,
    },
  },
  data() {
    return {
      value: 0,
    };
  },
  methods: {
    /** ## 组件方法 */
    /** 获取进度 */
    getvalue(){
      return this.value/360;
    }
  },
  created() {
    this.value = this.default;
  },
  mounted() {
    /** 滑块滑动功能 */
    this.$refs.slider.onmousedown = (e) => {
      const cricle = this.$refs.cricle;
      /** 获取位置(坐标轴原点) */
      let client = cricle.getboundingclientrect();
      let x0 = client.x + cricle.offsetwidth / 2;
      let y0 = client.y + cricle.offsetheight / 2;
      /** 阻止默认事件 */
      let ev = e || window.event;
      ev.preventdefault ? ev.preventdefault() : (ev.returnvalue = false);
      /** 鼠标移动 */
      document.onmousemove = (el) => {
        let move = el ? el : window.event;
        /** 鼠标位置 */
        let x = move.x - x0;
        let y = y0 - move.y;
        /** 计算角度 */
        let deg = (math.atan(y / x) / 2 / math.pi) * 360;
        if (x >= 0) {
          if (this.value >= 270) {
            /** 象限跳跃优化 */
            this.value = 360;
          } else {
            this.value = 90 - deg;
          }
        } else {
          if (this.value <= 90) {
            this.value = 0;
          } else {
            this.value = 270 - deg;
          }
        }
      };
      /** 鼠标松开 */
      document.onmouseup = () => {
        /** 取消订阅鼠标移动事件 */
        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>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com