Drag to change the side
Dragme
Component Source
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
const box = ref({ x: 0, y: 100 });
const isDragging = ref(false);
const dragStart = ref({ x: 0, y: 0 });
const containerRef = ref<HTMLElement | null>(null);
function onMouseDown(event: MouseEvent) {
isDragging.value = true;
const container = containerRef.value;
if (!container) return;
const rect = container.getBoundingClientRect();
dragStart.value = {
x: event.clientX - rect.left - box.value.x,
y: event.clientY - rect.top - box.value.y,
};
}
function onMouseMove(event: MouseEvent) {
if (!isDragging.value) return;
const container = containerRef.value;
if (!container) return;
const rect = container.getBoundingClientRect();
const elementWidth = 80;
let newX = event.clientX - rect.left - dragStart.value.x;
let newY = event.clientY - rect.top - dragStart.value.y;
// Keep within bounds
newX = Math.max(0, Math.min(newX, rect.width - elementWidth));
newY = Math.max(0, Math.min(newY, rect.height - 80));
box.value = { x: newX, y: newY };
}
function onMouseUp() {
if (!isDragging.value) return;
isDragging.value = false;
const container = containerRef.value;
if (!container) return;
const rect = container.getBoundingClientRect();
const elementWidth = 80;
const centerX = box.value.x + elementWidth / 2;
if (centerX < rect.width / 2) {
box.value.x = 0;
} else {
box.value.x = rect.width - elementWidth;
}
}
onMounted(() => {
window.addEventListener("mousemove", onMouseMove);
window.addEventListener("mouseup", onMouseUp);
});
onUnmounted(() => {
window.removeEventListener("mousemove", onMouseMove);
window.removeEventListener("mouseup", onMouseUp);
});
</script>
<template>
<div class="p-5 flex items-center justify-center bg-pink-600">
<div
ref="containerRef"
class="relative w-[600px] h-[400px] border-2 border-cyan-400"
>
<div
class="absolute left-1/2 top-0 bottom-0 border-l-2 border-dotted border-cyan-300"
></div>
<div
class="absolute w-[80px] h-[80px] bg-violet-600 select-none"
:style="{
left: box.x + 'px',
top: box.y + 'px',
}"
@mousedown="onMouseDown"
>
Dragme
</div>
</div>
</div>
</template>