Implement the angle selector in uniapp and vue, and the components can be used directly

Here is a brief record of how to implement the angle selector in uniapp and vue in case you need to use it later.

Implementation principle: Mainly by binding the mouse press, leave, move, and move out of the container events. By obtaining the origin coordinates of the container, the user obtains the offset of the mouse when pressing and moving within the container, and calculates the conversion angle problem. Finally implement the function. Without further ado, let’s get straight to the code:

Note: Currently uniapp should only be used in H5, because there are no mouse events on the mobile phone, and corresponding changes need to be made.

<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>

If you need to encapsulate it into a component, you need to add this.$emit('angele',this.angle) and monitor it in the parent component.

<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>

Guess you like

Origin blog.csdn.net/A1123352950/article/details/133939637