vue实现双摇杆
Vue 实现双摇杆
基本思路
在Vue中实现双摇杆功能通常需要结合Canvas或DOM元素监听触摸/鼠标事件。核心逻辑包括摇杆位置计算、事件触发和UI渲染。
实现步骤
1. 创建摇杆组件
<template>
<div class="joystick-container">
<div class="joystick-background" ref="bg"></div>
<div class="joystick-thumb" ref="thumb"></div>
</div>
</template>
2. 样式设置
.joystick-container {
position: relative;
width: 100px;
height: 100px;
}
.joystick-background {
width: 100%;
height: 100%;
border-radius: 50%;
background: rgba(0,0,0,0.2);
}
.joystick-thumb {
position: absolute;
width: 40px;
height: 40px;
border-radius: 50%;
background: rgba(255,255,255,0.5);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
3. 摇杆逻辑实现
export default {
mounted() {
this.initJoystick();
},
methods: {
initJoystick() {
const bg = this.$refs.bg;
const thumb = this.$refs.thumb;
const handleStart = (e) => {
e.preventDefault();
this.isActive = true;
this.updatePosition(e);
};
const handleMove = (e) => {
if (!this.isActive) return;
this.updatePosition(e);
};
const handleEnd = () => {
this.isActive = false;
thumb.style.transform = 'translate(-50%, -50%)';
};
bg.addEventListener('touchstart', handleStart);
bg.addEventListener('mousedown', handleStart);
document.addEventListener('touchmove', handleMove);
document.addEventListener('mousemove', handleMove);
document.addEventListener('touchend', handleEnd);
document.addEventListener('mouseup', handleEnd);
},
updatePosition(e) {
const bg = this.$refs.bg;
const thumb = this.$refs.thumb;
const rect = bg.getBoundingClientRect();
const centerX = rect.left + rect.width/2;
const centerY = rect.top + rect.height/2;
let clientX, clientY;
if (e.type.includes('touch')) {
clientX = e.touches[0].clientX;
clientY = e.touches[0].clientY;
} else {
clientX = e.clientX;
clientY = e.clientY;
}
const deltaX = clientX - centerX;
const deltaY = clientY - centerY;
const distance = Math.sqrt(deltaX*deltaX + deltaY*deltaY);
const maxDistance = rect.width/2;
let ratio = 1;
if (distance > maxDistance) {
ratio = maxDistance / distance;
}
const x = deltaX * ratio;
const y = deltaY * ratio;
thumb.style.transform = `translate(calc(-50% + ${x}px), calc(-50% + ${y}px))`;
// 触发自定义事件
this.$emit('move', {
x: x / maxDistance,
y: y / maxDistance
});
}
}
}
4. 双摇杆集成
<template>
<div class="game-container">
<Joystick
class="left-joystick"
@move="handleLeftMove"
/>
<Joystick
class="right-joystick"
@move="handleRightMove"
/>
</div>
</template>
<script>
import Joystick from './Joystick.vue';
export default {
components: { Joystick },
methods: {
handleLeftMove(data) {
// 处理左摇杆移动
console.log('Left:', data);
},
handleRightMove(data) {
// 处理右摇杆移动
console.log('Right:', data);
}
}
}
</script>
5. 移动端适配
.game-container {
position: fixed;
bottom: 20px;
width: 100%;
display: flex;
justify-content: space-between;
padding: 0 20px;
box-sizing: border-box;
}
.left-joystick {
left: 20px;
}
.right-joystick {
right: 20px;
}
进阶优化
性能优化
- 使用requestAnimationFrame进行平滑渲染
- 节流事件处理频率
功能扩展
- 添加摇杆力度反馈
- 实现摇杆自动回中
- 添加触摸区域限制
事件处理
- 支持自定义事件回调
- 添加摇杆状态(active/inactive)变化事件
这种实现方式适用于大多数需要双摇杆控制的游戏或交互应用,可根据具体需求调整摇杆大小、灵敏度和反馈效果。







