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>