chore(ui,stage-ui,stage-pages): now support to display visualizer in both linear and log
This commit is contained in:
@@ -12,7 +12,7 @@ import {
|
||||
updateBeatSyncParameters,
|
||||
} from '@proj-airi/stage-shared/beat-sync'
|
||||
import { Alert, AudioSpectrumVisualizer } from '@proj-airi/stage-ui/components'
|
||||
import { Button, FieldCheckbox, FieldRange } from '@proj-airi/ui'
|
||||
import { Button, FieldCheckbox, FieldRange, SelectTab } from '@proj-airi/ui'
|
||||
import { createTimeline } from 'animejs'
|
||||
import { nanoid } from 'nanoid'
|
||||
import { computed, onMounted, onUnmounted, ref, toRaw, watch } from 'vue'
|
||||
@@ -22,6 +22,11 @@ const state = ref<BeatSyncDetectorState>()
|
||||
const frequencies = ref<number[]>([])
|
||||
const totalFreqHistory = ref<number[]>([])
|
||||
const isUpdatingFrequencies = ref(false)
|
||||
const spectrumScale = ref<'linear' | 'logarithm'>('logarithm')
|
||||
const spectrumScaleOptions = [
|
||||
{ label: 'Linear', value: 'linear' as const, icon: 'i-solar:chart-2-bold-duotone' },
|
||||
{ label: 'Logarithm', value: 'logarithm' as const, icon: 'i-solar:chart-bold-duotone' },
|
||||
]
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -304,12 +309,21 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</h2>
|
||||
|
||||
<div bg="neutral/10" h-64px max-w-400px w-full overflow-hidden rounded-2xl>
|
||||
<AudioSpectrumVisualizer
|
||||
v-if="isUpdatingFrequencies"
|
||||
:frequencies="frequencies"
|
||||
h-full w-full gap-0
|
||||
bars-class="bg-primary-400/50 dark:bg-primary-500/50 rounded-none"
|
||||
<div class="max-w-400px w-full flex flex-col gap-3">
|
||||
<div bg="neutral/10" h-64px w-full overflow-hidden rounded-2xl>
|
||||
<AudioSpectrumVisualizer
|
||||
v-if="isUpdatingFrequencies"
|
||||
:frequencies="frequencies"
|
||||
:scale="spectrumScale"
|
||||
h-full w-full gap-0
|
||||
bars-class="bg-primary-400/50 dark:bg-primary-500/50 rounded-none"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<SelectTab
|
||||
v-model="spectrumScale"
|
||||
size="sm"
|
||||
:options="spectrumScaleOptions"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
const props = defineProps<{
|
||||
const props = withDefaults(defineProps<{
|
||||
frequencies: number[]
|
||||
barsClass?: string
|
||||
}>()
|
||||
scale?: 'linear' | 'logarithm'
|
||||
}>(), {
|
||||
scale: 'logarithm',
|
||||
})
|
||||
|
||||
const AMPLIFICATION = 5
|
||||
|
||||
@@ -31,7 +34,10 @@ function toLogScale(value: number) {
|
||||
function getBarHeight(frequency: number, index: number) {
|
||||
const reductionFactor = getReductionFactor(index, props.frequencies.length)
|
||||
const { minHeight, maxHeight } = getHeightBounds(props.frequencies.length)
|
||||
const scaled = toLogScale(frequency * reductionFactor) * 100
|
||||
const normalized = props.scale === 'linear'
|
||||
? Math.min(1, Math.max(0, frequency * AMPLIFICATION * reductionFactor))
|
||||
: toLogScale(frequency * reductionFactor)
|
||||
const scaled = normalized * 100
|
||||
return Math.min(maxHeight, Math.max(minHeight, scaled))
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -36,7 +36,7 @@ const rootStyle = computed(() => ({
|
||||
'--select-tab-count': String(itemCount.value),
|
||||
'--select-tab-active-index': String(Math.max(activeIndex.value, 0)),
|
||||
'--select-tab-padding': props.size === 'sm' ? '0px' : '0px',
|
||||
'--select-tab-gap': '0.5rem',
|
||||
'--select-tab-gap': '0.25rem',
|
||||
'--select-tab-indicator-opacity': activeIndex.value === -1 ? '0' : '1',
|
||||
}))
|
||||
</script>
|
||||
@@ -49,6 +49,7 @@ const rootStyle = computed(() => ({
|
||||
:class="[
|
||||
'select-tab',
|
||||
'relative', 'flex', 'w-full', 'items-stretch', 'rounded-xl',
|
||||
'overflow-hidden',
|
||||
'bg-white-400/6', 'dark:bg-neutral-900/70',
|
||||
'transition-[border-color,box-shadow,opacity]', 'duration-200', 'ease-out', 'border-2',
|
||||
'border-neutral-100', 'dark:border-neutral-800',
|
||||
|
||||
Reference in New Issue
Block a user