fix no scrolling while in dragPad

This commit is contained in:
Adrian Zürcher
2025-05-12 17:14:49 +02:00
parent 2bb3102828
commit a5303ff232

View File

@@ -4,7 +4,7 @@
<q-slider <q-slider
class="q-mr-sm" class="q-mr-sm"
vertical vertical
reverse :reverse="!props.reverseTilt"
v-model="tilt" v-model="tilt"
:min="0" :min="0"
:max="100" :max="100"
@@ -22,6 +22,7 @@
position: relative; position: relative;
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 8px; border-radius: 8px;
touch-action: none;
" "
@mousedown="startDrag" @mousedown="startDrag"
@touchstart="startTouch" @touchstart="startTouch"
@@ -32,6 +33,7 @@
</div> </div>
<q-item-label class="text-bold">Pan</q-item-label> <q-item-label class="text-bold">Pan</q-item-label>
<q-slider <q-slider
:reverse="props.reversePan"
class="q-ml-sm" class="q-ml-sm"
v-model="pan" v-model="pan"
:min="0" :min="0"
@@ -46,18 +48,22 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, defineModel } from 'vue'; import { ref, computed } from 'vue';
const pad = ref<HTMLElement | null>(null); const pad = ref<HTMLElement | null>(null);
const dragging = ref(false); const dragging = ref(false);
const pan = defineModel<number>('pan', { default: 0 }); const pan = defineModel<number>('pan', { default: 0 });
const tilt = defineModel<number>('tilt', { default: 0 }); const tilt = defineModel<number>('tilt', { default: 0 });
const props = defineProps<{
reversePan: boolean;
reverseTilt: boolean;
}>();
const markerStyle = computed(() => ({ const markerStyle = computed(() => ({
position: 'absolute' as const, position: 'absolute' as const,
top: `${2 * (100 - tilt.value)}px`, top: `${2 * (props.reverseTilt ? tilt.value : 100 - tilt.value)}px`,
left: `${2 * pan.value}px`, left: `${2 * (props.reversePan ? 100 - pan.value : pan.value)}px`,
width: '12px', width: '12px',
height: '12px', height: '12px',
borderRadius: '50%', borderRadius: '50%',
@@ -74,11 +80,6 @@ function startDrag(e: MouseEvent) {
window.addEventListener('mouseup', stopDrag); window.addEventListener('mouseup', stopDrag);
} }
function onDrag(e: MouseEvent) {
if (!dragging.value) return;
updatePosition(e);
}
function stopDrag() { function stopDrag() {
dragging.value = false; dragging.value = false;
window.removeEventListener('mousemove', onDrag); window.removeEventListener('mousemove', onDrag);
@@ -86,21 +87,29 @@ function stopDrag() {
} }
function startTouch(e: TouchEvent) { function startTouch(e: TouchEvent) {
e.preventDefault(); // ✅ block scroll
const touch = e.touches[0]; const touch = e.touches[0];
if (!touch) return; if (!touch) return;
dragging.value = true; dragging.value = true;
updatePosition(touch); updatePosition(touch);
window.addEventListener('touchmove', onTouch); window.addEventListener('touchmove', onTouch, { passive: false });
window.addEventListener('touchend', stopTouch); window.addEventListener('touchend', stopTouch);
} }
function onTouch(e: TouchEvent) { function onTouch(e: TouchEvent) {
e.preventDefault(); // ✅ block scroll
if (!dragging.value) return; if (!dragging.value) return;
const touch = e.touches[0]; const touch = e.touches[0];
if (!touch) return; if (!touch) return;
updatePosition(touch); updatePosition(touch);
} }
function onDrag(e: MouseEvent) {
e.preventDefault(); // optional, for extra safety
if (!dragging.value) return;
updatePosition(e);
}
function stopTouch() { function stopTouch() {
dragging.value = false; dragging.value = false;
window.removeEventListener('touchmove', onTouch); window.removeEventListener('touchmove', onTouch);
@@ -109,11 +118,16 @@ function stopTouch() {
function updatePosition(e: MouseEvent | Touch) { function updatePosition(e: MouseEvent | Touch) {
if (!pad.value) return; if (!pad.value) return;
const rect = pad.value.getBoundingClientRect(); const rect = pad.value.getBoundingClientRect();
const newX = Math.min(Math.max(0, e.clientX - rect.left), rect.width); const newX = Math.min(Math.max(0, e.clientX - rect.left), rect.width);
const newY = Math.min(Math.max(0, e.clientY - rect.top), rect.height); const newY = Math.min(Math.max(0, e.clientY - rect.top), rect.height);
pan.value = Math.round((newX / rect.width) * 100); pan.value = props.reversePan
tilt.value = Math.round(100 - (newY / rect.height) * 100); ? Math.round((1 - newX / rect.width) * 100)
: Math.round((newX / rect.width) * 100);
tilt.value = props.reverseTilt
? Math.round((newY / rect.height) * 100)
: Math.round(100 - (newY / rect.height) * 100);
} }
</script> </script>