multi cards
All checks were successful
Deploy App / build (push) Successful in 2m4s
Deploy App / deploy (push) Successful in 21s

This commit is contained in:
valere
2026-02-11 16:49:34 +01:00
parent 620112d9ba
commit 399519d1d4
8 changed files with 276 additions and 105 deletions

View File

@@ -6,10 +6,13 @@
<b v-else>normal</b>
</button>
<button @click="Rewind">
rewind
Rewind
</button>
<button @click="Wind">
Wind
</button>
<!-- <div>{{ progressPercentage }}</div> -->
<div>{{ currentSpeed }}</div>
<div>{{ (currentSpeed).toFixed(2) }}</div>
</div>
<div class="disc" ref="discRef" id="disc">
<div class="bobine" :style="{
@@ -31,6 +34,7 @@ import type { Card } from '~~/types/types'
import { ref, onMounted, onUnmounted, watch, computed, nextTick } from 'vue'
import Disc from '~/utils/platine/disc'
import Sampler from '~/utils/platine/sampler'
import { duration } from 'drizzle-orm/gel-core';
const props = defineProps<{ card?: Card, autoplay?: boolean }>()
const autoplay = props.autoplay ?? false
@@ -184,9 +188,97 @@ const Reverse = () => {
const Rewind = async () => {
if (!disc.value || !sampler.value) return
Reverse()
play()
// Sauvegarder l'état actuel
disc.value.isStopped() ? play() : null
const wasPlaying = !disc.value.isStopped()
const currentSpeed = disc.value.playbackSpeed
// Fonction pour l'effet de scratch/pull up
const scratchEffect = async () => {
// Ralentir progressivement
const slowDownDuration = 300 // ms
const startTime = performance.now()
const startSpeed = wasPlaying ? currentSpeed : 0.1
const slowDown = (timestamp: number) => {
const elapsed = timestamp - startTime
const progress = Math.min(elapsed / slowDownDuration, 1)
// Courbe d'accélération pour un effet plus naturel
const easeOut = 1 - Math.pow(1 - progress, 2)
// Ralentir progressivement jusqu'à presque l'arrêt
const newSpeed = startSpeed * (1 - easeOut) + 0.05
sampler.value?.setPlaybackRate(newSpeed)
if (progress < 1) {
requestAnimationFrame(slowDown)
} else {
// Une fois ralenti, effectuer le rembobinage
performRewind()
}
}
requestAnimationFrame(slowDown)
}
const performRewind = () => {
// Mettre en pause la lecture actuelle
if (wasPlaying) {
sampler.value?.pause()
}
// Remettre à zéro la position
sampler.value?.play(0)
disc.value?.setAngle(0)
// Effet de scratch rapide
const scratchDuration = 200 // ms
const scratchStart = performance.now()
const scratch = (timestamp: number) => {
const elapsed = timestamp - scratchStart
const progress = Math.min(elapsed / scratchDuration, 1)
// Créer un effet de scratch en variant la vitesse
if (progress < 0.5) {
// Phase de scratch vers l'arrière
const scratchProgress = progress * 2
const scratchSpeed = 1 - (scratchProgress * 1.8) // Ralenti jusqu'à -0.8
sampler.value?.setPlaybackRate(scratchSpeed)
} else {
// Phase de pull up
const pullProgress = (progress - 0.5) * 2
const pullSpeed = -0.8 + (pullProgress * 1.8) // Accélère de -0.8 à 1.0
sampler.value?.setPlaybackRate(pullSpeed)
}
if (progress < 1) {
requestAnimationFrame(scratch)
} else {
// Remettre la vitesse normale à la fin
sampler.value?.setPlaybackRate(1)
// Si c'était en lecture avant, relancer la lecture
if (wasPlaying) {
setTimeout(() => {
sampler.value?.play(0)
}, 50)
}
}
}
requestAnimationFrame(scratch)
}
// Démarrer l'effet
scratchEffect()
}
const Wind = () => {
disc.value.secondsPlayed = duration
sampler.value.secondsPlayed = duration
}
const handleKeyDown = (e: KeyboardEvent) => {
@@ -237,7 +329,7 @@ watch(() => props.card, (newCard) => {
.disc {
pointer-events: auto;
position: fixed;
position: absolute;
background-color: transparent;
position: relative;
aspect-ratio: 1;