add working player
This commit is contained in:
@@ -31,6 +31,8 @@ const props = withDefaults(
|
||||
{ BoxState: 'list' }
|
||||
)
|
||||
|
||||
const isDraggable = computed(() => !['list', 'hidden'].includes(BoxState.value()))
|
||||
|
||||
// --- Réfs ---
|
||||
const scene = ref<HTMLElement>()
|
||||
const box = ref<HTMLElement>()
|
||||
@@ -123,61 +125,81 @@ function tickInertia() {
|
||||
}
|
||||
|
||||
// --- Pointer events ---
|
||||
let listenersAttached = false
|
||||
|
||||
const down = (ev: PointerEvent) => {
|
||||
ev.preventDefault()
|
||||
dragging = true
|
||||
box.value?.setPointerCapture(ev.pointerId)
|
||||
lastPointer = { x: ev.clientX, y: ev.clientY, time: performance.now() }
|
||||
velocity = { x: 0, y: 0 }
|
||||
if (raf) { cancelAnimationFrame(raf); raf = null }
|
||||
}
|
||||
|
||||
const move = (ev: PointerEvent) => {
|
||||
if (!dragging) return
|
||||
ev.preventDefault()
|
||||
const now = performance.now()
|
||||
const dx = ev.clientX - lastPointer.x
|
||||
const dy = ev.clientY - lastPointer.y
|
||||
const dt = Math.max(1, now - lastPointer.time)
|
||||
|
||||
rotateY.value += dx * sensitivity
|
||||
rotateX.value -= dy * sensitivity
|
||||
rotateX.value = Math.max(-80, Math.min(80, rotateX.value))
|
||||
|
||||
velocity.x = (dx / dt) * 16 * sensitivity
|
||||
velocity.y = (-dy / dt) * 16 * sensitivity
|
||||
|
||||
lastPointer = { x: ev.clientX, y: ev.clientY, time: now }
|
||||
applyTransform(0) // immédiat pendant drag
|
||||
}
|
||||
|
||||
const end = (ev: PointerEvent) => {
|
||||
if (!dragging) return
|
||||
dragging = false
|
||||
try { box.value?.releasePointerCapture(ev.pointerId) } catch { }
|
||||
if (enableInertia && (Math.abs(velocity.x) > minVelocity || Math.abs(velocity.y) > minVelocity)) {
|
||||
if (!raf) raf = requestAnimationFrame(tickInertia)
|
||||
}
|
||||
}
|
||||
|
||||
function addListeners() {
|
||||
if (!box.value || listenersAttached) return
|
||||
box.value.addEventListener('pointerdown', down)
|
||||
box.value.addEventListener('pointermove', move)
|
||||
box.value.addEventListener('pointerup', end)
|
||||
box.value.addEventListener('pointercancel', end)
|
||||
box.value.addEventListener('pointerleave', end)
|
||||
listenersAttached = true
|
||||
}
|
||||
|
||||
function removeListeners() {
|
||||
if (!box.value || !listenersAttached) return
|
||||
box.value.removeEventListener('pointerdown', down)
|
||||
box.value.removeEventListener('pointermove', move)
|
||||
box.value.removeEventListener('pointerup', end)
|
||||
box.value.removeEventListener('pointercancel', end)
|
||||
box.value.removeEventListener('pointerleave', end)
|
||||
listenersAttached = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
applyColor()
|
||||
applyBoxState()
|
||||
if (isDraggable) addListeners()
|
||||
})
|
||||
|
||||
const down = (ev: PointerEvent) => {
|
||||
ev.preventDefault()
|
||||
dragging = true
|
||||
box.value?.setPointerCapture(ev.pointerId)
|
||||
lastPointer = { x: ev.clientX, y: ev.clientY, time: performance.now() }
|
||||
velocity = { x: 0, y: 0 }
|
||||
if (raf) { cancelAnimationFrame(raf); raf = null }
|
||||
}
|
||||
|
||||
const move = (ev: PointerEvent) => {
|
||||
if (!dragging) return
|
||||
ev.preventDefault()
|
||||
const now = performance.now()
|
||||
const dx = ev.clientX - lastPointer.x
|
||||
const dy = ev.clientY - lastPointer.y
|
||||
const dt = Math.max(1, now - lastPointer.time)
|
||||
|
||||
rotateY.value += dx * sensitivity
|
||||
rotateX.value -= dy * sensitivity
|
||||
rotateX.value = Math.max(-80, Math.min(80, rotateX.value))
|
||||
|
||||
velocity.x = (dx / dt) * 16 * sensitivity
|
||||
velocity.y = (-dy / dt) * 16 * sensitivity
|
||||
|
||||
lastPointer = { x: ev.clientX, y: ev.clientY, time: now }
|
||||
applyTransform(0) // immédiat pendant drag
|
||||
}
|
||||
|
||||
const end = (ev: PointerEvent) => {
|
||||
if (!dragging) return
|
||||
dragging = false
|
||||
try { box.value?.releasePointerCapture(ev.pointerId) } catch { }
|
||||
if (enableInertia && (Math.abs(velocity.x) > minVelocity || Math.abs(velocity.y) > minVelocity)) {
|
||||
if (!raf) raf = requestAnimationFrame(tickInertia)
|
||||
}
|
||||
}
|
||||
|
||||
box.value?.addEventListener('pointerdown', down)
|
||||
box.value?.addEventListener('pointermove', move)
|
||||
box.value?.addEventListener('pointerup', end)
|
||||
box.value?.addEventListener('pointercancel', end)
|
||||
box.value?.addEventListener('pointerleave', end)
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
cancelAnimationFrame(raf!)
|
||||
})
|
||||
onBeforeUnmount(() => {
|
||||
cancelAnimationFrame(raf!)
|
||||
removeListeners()
|
||||
})
|
||||
|
||||
// --- Watchers ---
|
||||
watch(() => props.BoxState, () => applyBoxState())
|
||||
watch(() => props.compilation, () => applyColor(), { deep: true })
|
||||
watch(() => isDraggable, (enabled) => enabled ? addListeners() : removeListeners())
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
Reference in New Issue
Block a user