parent
7b1cf7509f
commit
839a80b3ac
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { QueueItemSource } from '~/types'
|
import type { QueueItemSource } from '~/types'
|
||||||
|
|
||||||
import { whenever, watchDebounced, useCurrentElement, useScrollLock, useFullscreen, useIdle, refAutoReset } from '@vueuse/core'
|
import { whenever, watchDebounced, useCurrentElement, useScrollLock, useFullscreen, useIdle, refAutoReset, useStorage } from '@vueuse/core'
|
||||||
import { nextTick, ref, computed, watchEffect, onMounted } from 'vue'
|
import { nextTick, ref, computed, watchEffect, onMounted } from 'vue'
|
||||||
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
|
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
|
||||||
import { useGettext } from 'vue3-gettext'
|
import { useGettext } from 'vue3-gettext'
|
||||||
|
@ -169,7 +169,7 @@ enum CoverType {
|
||||||
MILK_DROP
|
MILK_DROP
|
||||||
}
|
}
|
||||||
|
|
||||||
const coverType = ref(CoverType.COVER_ART)
|
const coverType = useStorage('cover-type', CoverType.COVER_ART)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useMilkDrop } from '~/composables/audio/visualizer'
|
import { useMilkDrop } from '~/composables/audio/visualizer'
|
||||||
|
|
||||||
import { onScopeDispose, ref } from 'vue'
|
import { onScopeDispose, ref, watch } from 'vue'
|
||||||
import { useRafFn } from '@vueuse/core'
|
import { useRafFn } from '@vueuse/core'
|
||||||
|
|
||||||
const milkdrop = ref()
|
const milkdrop = ref()
|
||||||
const canvas = ref()
|
const canvas = ref()
|
||||||
|
|
||||||
const { visualizer, loadRandomPreset, render } = useMilkDrop(canvas)
|
const { visualizer, loadRandomPreset, render, isVisible } = useMilkDrop(canvas)
|
||||||
|
|
||||||
const { pause } = useRafFn(render)
|
const { resume, pause } = useRafFn(render)
|
||||||
|
|
||||||
|
watch(isVisible, (visible) => visible
|
||||||
|
? resume()
|
||||||
|
: pause()
|
||||||
|
)
|
||||||
|
|
||||||
onScopeDispose(() => {
|
onScopeDispose(() => {
|
||||||
pause()
|
pause()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
|
||||||
import { AUDIO_CONTEXT, GAIN_NODE } from './audio-api'
|
import { AUDIO_CONTEXT, GAIN_NODE } from './audio-api'
|
||||||
import { useResizeObserver } from '@vueuse/core'
|
import { useResizeObserver, useStorage } from '@vueuse/core'
|
||||||
import { ref, markRaw } from 'vue'
|
import { watchEffect, ref, markRaw } from 'vue'
|
||||||
|
|
||||||
// @ts-expect-error butterchurn has no typings
|
// @ts-expect-error butterchurn has no typings
|
||||||
import butterchurnPresets from 'butterchurn-presets'
|
import butterchurnPresets from 'butterchurn-presets'
|
||||||
|
@ -11,14 +11,26 @@ import butterchurnPresets from 'butterchurn-presets'
|
||||||
import butterchurn from 'butterchurn'
|
import butterchurn from 'butterchurn'
|
||||||
|
|
||||||
export const useMilkDrop = (canvas: Ref<HTMLCanvasElement>) => {
|
export const useMilkDrop = (canvas: Ref<HTMLCanvasElement>) => {
|
||||||
const presets = Object.entries(butterchurnPresets)
|
const presets = Object.keys(butterchurnPresets)
|
||||||
const visualizer = ref()
|
const visualizer = ref()
|
||||||
|
|
||||||
const loadRandomPreset = (blendTime = 1) => {
|
const getRandomPreset = () => {
|
||||||
const index = (presets.length * Math.random()) | 0
|
const index = (presets.length * Math.random()) | 0
|
||||||
const [name, preset] = presets[index]
|
return presets[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
const presetName = useStorage<string | undefined>('milk-drop:preset', undefined)
|
||||||
|
watchEffect(() => {
|
||||||
|
const name = presetName.value
|
||||||
|
if (name === undefined) return
|
||||||
|
|
||||||
console.log(`Switching to preset: '${name}'`)
|
console.log(`Switching to preset: '${name}'`)
|
||||||
visualizer.value.loadPreset(preset, blendTime)
|
visualizer.value?.loadPreset(butterchurnPresets[name], 1)
|
||||||
|
})
|
||||||
|
|
||||||
|
const loadRandomPreset = () => {
|
||||||
|
const name = getRandomPreset()
|
||||||
|
presetName.value = name
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialize = (canvas: HTMLCanvasElement, width: number, height: number) => {
|
const initialize = (canvas: HTMLCanvasElement, width: number, height: number) => {
|
||||||
|
@ -27,17 +39,21 @@ export const useMilkDrop = (canvas: Ref<HTMLCanvasElement>) => {
|
||||||
height
|
height
|
||||||
}))
|
}))
|
||||||
|
|
||||||
loadRandomPreset(0)
|
if (presetName.value === undefined) {
|
||||||
|
presetName.value = getRandomPreset()
|
||||||
|
}
|
||||||
|
|
||||||
visualizer.value.connectAudio(GAIN_NODE)
|
visualizer.value.connectAudio(GAIN_NODE)
|
||||||
visualizer.value.setInternalMeshSize(128, 96)
|
visualizer.value.setInternalMeshSize(128, 96)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isVisible = ref(false)
|
||||||
useResizeObserver(canvas, ([entry]) => {
|
useResizeObserver(canvas, ([entry]) => {
|
||||||
const { width, height } = entry.contentRect
|
const { width, height } = entry.contentRect
|
||||||
|
|
||||||
console.log(width, height)
|
|
||||||
canvas.value.width = width
|
canvas.value.width = width
|
||||||
canvas.value.height = height
|
canvas.value.height = height
|
||||||
|
isVisible.value = !!(width * height)
|
||||||
|
|
||||||
if (visualizer.value === undefined) {
|
if (visualizer.value === undefined) {
|
||||||
initialize(entry.target as HTMLCanvasElement, width, height)
|
initialize(entry.target as HTMLCanvasElement, width, height)
|
||||||
|
@ -52,13 +68,14 @@ export const useMilkDrop = (canvas: Ref<HTMLCanvasElement>) => {
|
||||||
visualizer.value?.render()
|
visualizer.value?.render()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
loadRandomPreset(0)
|
loadRandomPreset()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
visualizer,
|
visualizer,
|
||||||
loadRandomPreset,
|
loadRandomPreset,
|
||||||
render
|
render,
|
||||||
|
isVisible
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue