feat:添加奖品模块触摸拖动功能

This commit is contained in:
Zhukj
2025-11-27 18:24:32 +08:00
parent dbe9c877e0
commit 6e1b1d5317

View File

@@ -32,7 +32,9 @@
</section> </section>
<!-- 第三部分奖金设置图片形式 --> <!-- 第三部分奖金设置图片形式 -->
<section v-if="localDisplayConfig.showBonusModule" class="bonus-section card-game" @mousedown="startBonusDrag" <section v-if="localDisplayConfig.showBonusModule" class="bonus-section card-game"
@mousedown="startBonusDrag"
@touchstart="startBonusTouch"
@click.stop> @click.stop>
<div class="bonus-awards-container"> <div class="bonus-awards-container">
<div><img src="/award1.png" alt="一等奖" class="award-image"></div> <div><img src="/award1.png" alt="一等奖" class="award-image"></div>
@@ -732,7 +734,7 @@ const startDrag = (e) => {
e.preventDefault(); e.preventDefault();
}; };
// 开始拖动奖金模块 // 开始拖动奖金模块(鼠标事件)
const startBonusDrag = (e) => { const startBonusDrag = (e) => {
e.stopPropagation(); // 阻止事件冒泡 e.stopPropagation(); // 阻止事件冒泡
isBonusDragging = true; isBonusDragging = true;
@@ -745,7 +747,24 @@ const startBonusDrag = (e) => {
e.preventDefault(); e.preventDefault();
}; };
// 结束拖动 // 开始拖动奖金模块(触摸事件)
const startBonusTouch = (e) => {
e.stopPropagation(); // 阻止事件冒泡
e.preventDefault(); // 阻止默认行为,如滚动
const touch = e.touches[0];
isBonusDragging = true;
// 计算触摸点相对于元素左上角的偏移量
const rect = e.currentTarget.getBoundingClientRect();
bonusDragOffset.x = touch.clientX - rect.left;
bonusDragOffset.y = touch.clientY - rect.top;
// 提高拖动时的性能,临时禁用动画效果
e.currentTarget.style.transition = 'none';
};
// 结束拖动(鼠标和触摸事件)
const endDrag = (e) => { const endDrag = (e) => {
isDragging = false; isDragging = false;
@@ -759,7 +778,19 @@ const endDrag = (e) => {
isBonusDragging = false; isBonusDragging = false;
}; };
// 优化的拖动函数 - 使用节流减少更新频率 // 结束触摸拖动
const endTouch = (e) => {
if (isBonusDragging) {
// 恢复动画效果
const bonusElement = document.querySelector('.bonus-section');
if (bonusElement) {
bonusElement.style.transition = '';
}
}
isBonusDragging = false;
};
// 优化的拖动函数 - 使用节流减少更新频率(鼠标事件)
const drag = throttle((e) => { const drag = throttle((e) => {
if (isDragging) { if (isDragging) {
drumsPosition.value.x = e.clientX - dragOffset.x; drumsPosition.value.x = e.clientX - dragOffset.x;
@@ -797,6 +828,43 @@ const drag = throttle((e) => {
} }
}, 10); // 10ms节流约100FPS }, 10); // 10ms节流约100FPS
// 优化的触摸拖动函数 - 使用节流减少更新频率
const touchMove = throttle((e) => {
if (isBonusDragging) {
e.preventDefault(); // 阻止页面滚动
const touch = e.touches[0];
// 计算新的位置
const newX = touch.clientX - bonusDragOffset.x;
const newY = touch.clientY - bonusDragOffset.y;
// 确保元素不会被拖出视口
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
const element = document.querySelector('.bonus-section');
if (element) {
const elementWidth = element.offsetWidth;
const elementHeight = element.offsetHeight;
// 限制在视口内,添加一些边距
const limitedX = Math.max(10, Math.min(newX, windowWidth - elementWidth - 10));
const limitedY = Math.max(10, Math.min(newY, windowHeight - elementHeight - 10));
// 使用优化的更新函数更新奖金模块位置
requestAnimationFrame(() => {
bonusPosition.x = limitedX;
bonusPosition.y = limitedY;
// 直接设置元素样式确保实时更新
element.style.left = `${limitedX}px`;
element.style.top = `${limitedY}px`;
element.style.right = 'auto';
element.style.bottom = 'auto';
});
}
}
}, 10); // 10ms节流约100FPS
// 计算倒计时 // 计算倒计时
const calculateCountdown = () => { const calculateCountdown = () => {
// 使用配置的结束时间 // 使用配置的结束时间
@@ -1096,6 +1164,11 @@ onMounted(async () => {
// 添加拖放相关的事件监听 // 添加拖放相关的事件监听
document.addEventListener('mousemove', drag); document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', endDrag); document.addEventListener('mouseup', endDrag);
// 添加触摸事件监听
document.addEventListener('touchmove', touchMove, { passive: false });
document.addEventListener('touchend', endTouch);
document.addEventListener('touchcancel', endTouch);
}); });
// 监听结束时间变化在真实环境中可能需要通过props或store来监听 // 监听结束时间变化在真实环境中可能需要通过props或store来监听
@@ -1121,6 +1194,11 @@ onUnmounted(() => {
document.removeEventListener('mousemove', drag); document.removeEventListener('mousemove', drag);
document.removeEventListener('mouseup', endDrag); document.removeEventListener('mouseup', endDrag);
// 移除触摸事件监听
document.removeEventListener('touchmove', touchMove);
document.removeEventListener('touchend', endTouch);
document.removeEventListener('touchcancel', endTouch);
// 清理音频资源 // 清理音频资源
if (audioContext) { if (audioContext) {
audioContext.close(); audioContext.close();