vue 角度选择器

2022-07-15  本文已影响0人  littlesunn

一个角度选择器,根据别人的代码进一步增强,加入了圆弧,圆弧使用的是d3的弧度生成器;

npm i --save d3

image.png
<template>
  <div>
    <div
      class="angle-select-container"
      @mousedown="mousedown = true"
      @mouseup="mousedown = false"
      @mousemove="on_mousemove"
      @mouseleave="mousedown = false"
      ref="setup_angle"
    >
      <div class="point" ref="icon">
        <img src="~@/assets/arrow.png" alt="" width="50px" />
      </div>
      <div class="center-circle"></div>
    </div>
  </div>
</template>

<script>
import * as d3 from "d3";
const arcPath = d3.arc().innerRadius(50).outerRadius(120);

export default {
  data() {
    return {
      mousedown: false,
      angle_data: 0,
      arcPath: null,
    };
  },
  mounted() {
    this.initArcPath();
  },
  methods: {
    calculate_degree(x, y, centerX, centerY) {
      //根据当前坐标和中心坐标计算角度
      const radians = Math.atan2(x - centerX, y - centerY);
      return -radians * (180 / Math.PI) + 180
    },
    initArcPath() {
      const svg = d3
        .select(this.$refs.setup_angle)
        .append("svg")
        .attr("height", this.$refs.setup_angle.clientHeight);
      this.arcPath = svg
        .append("path")
        .attr("d", arcPath({ startAngle: 0, endAngle: 0 }))
        .attr("fill", "rgba(9,109,217,.3)")
        .attr("transform", "translate(146,146)");
      console.log(this.arcPath);
    },
    updatePath(angle) {
      let endAngle = (Math.PI / 180) * angle;
      this.arcPath.attr("d", arcPath({ startAngle: 0, endAngle }));
    },
    on_mousemove(event) {
      //鼠标移动事件(按下移动就算拖拽,在元素里移动才算,元素外移动监听)
      if (this.mousedown) {
        //表示是按下移动的
        const setup_angle = this.$refs.setup_angle;
        let centerX = -~(setup_angle.offsetHeight || setup_angle.height) / 2;
        let centerY = -~(setup_angle.offsetWidth || setup_angle.width) / 2;
        let angle = this.calculate_degree(
          event.offsetX,
          event.offsetY,
          centerX,
          centerY
        );
        this.angle_data = -~angle;

        this.$refs.icon.style.transform = `translate(-50%, -50%) rotate(${
          angle
        }deg)`;

        this.updatePath(angle);
        console.log(this.angle_data, "angle_data");
      }
    },
  },
};
</script>

<style scoped lang="scss">
.angle-select-container {
  background: rgba(9, 109, 217, 0);
  border: 3px solid #096dd9;
  width: 300px;
  height: 300px;
  border-radius: 50%;
  position: relative;
  .point,
  .center-circle {
    pointer-events: none;
    user-select: none;
    width: 50px;
    height: 100%;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    img {
      transform: tran-5px;
    }
  }
  .center-circle {
    width: 40%;
    height: 40%;
    background: rgba(9, 109, 217, 0.8);
    border-radius: 50%;
  }
  ::v-deep svg {
    position: absolute;
    left: 50%;
    top: 50%;
    height: 100%;
    transform: translate(-50%, -50%);
  }
}
</style>
上一篇下一篇

猜你喜欢

热点阅读