在uniapp、vue中实现角度选择器,组件可直接使用

在这里简单记录一下,在uniapp和vue中如何实现角度选择器,以防之后需要使用

实现原理:主要是通过对容器绑定鼠标按下,离开,移动,移出容器事件,通过获取容器的原点坐标,用户在容器内按下移动时获取鼠标的偏移量,通过计算转化角度问题,最后实现功能。话不多说直接上代码:

注意:目前uniapp应该只能在H5使用,因为手机端没有鼠标事件,需要做对应更改

<template>
//在uniapp中将div替换成view
	<div>
		<!-- 鼠标按下@mousedown  鼠标松开@mouseup  鼠标离开容器@mouseleave  鼠标移动@mousemove-->
		<div class="box" ref="box" @mousedown="mousedown = true" @mouseup="mousedown = false"
			@mouseleave="mousedown = false" @mousemove="mousemove">
			<div class="container" :style="{transform:'rotate('+angle+'deg)'}">
				<div class="point"></div>
			</div>
			<div class="content">
				{
   
   { angle+'°' }}
			</div>
		</div>
	</div>
</template>

<script>
	export default {
		data() {
			return {
				angle: 0, //旋转角度
				mousedown: false, // 判断鼠标是否按下
			}
		},

		methods: {
			// 鼠标移动事件
			mousemove() {
				// 判断用户是否在容器内按下后移动鼠标
				if (this.mousedown) {
					let box = this.$refs.box
                    //let box = this.$refs.box.$el 如果在uniapp中使用则需要提换成这个
					let centerX = -~(box.offsetHeight || box.height) / 2;
					let centerY = -~(box.offsetWidth || box.width) / 2;
					let angle = this.calculate(event.offsetX, event.offsetY, centerX, centerY);
					this.angle = -~angle
					//如果需要封装成组件则
					// this.$emit('方法名', '数据')
				}
			},
			// 计算
			calculate(x, y, centerX, centerY) { //根据当前坐标和中心坐标计算角度
				const radians = Math.atan2(x - centerX, y - centerY);
				return (radians * (180 / Math.PI) * -1) + 180;
			},
		}
	}
</script>
<style lang="scss" scoped>
	.box {
		border-radius: 50%;
		background-color: pink;
		width: 200px;
		height: 200px;
		border: 1px solid #000;
		display: flex;
		align-items: center;
		justify-content: center;
		cursor: pointer;

		// 标点
		.container {
			height: 100%;
			padding: 1px 0;
			box-sizing: border-box;
			pointer-events: none; //必须要加

			.point {
				height: 15px;
				width: 15px;
				border-radius: 50%;
				background-color: red;
			}
		}

		// 文字提示
		.content {
			position: absolute;
			font-size: 16px;
			color: #5b748e;
			font-weight: bold;
			pointer-events: none;
		}
	}
</style>

如果需要封装成组件的形式则需要添加this.$emit('angele',this.angle)使用,在父组件进行监听

<template>
	<div>
		<angle @angle="angle"></angle>
	</div>
</template>

<script>
	import angle from '你的地址'
	export default {
		data() {
			return {

			}
		},
		components: {
			angle
		},
		methods: {
			angle(val) {
				console.log(val)
			},
		}
	}
</script>

<style lang="scss" scoped>

</style>

猜你喜欢

转载自blog.csdn.net/A1123352950/article/details/133939637