From a8e6805a80c21a8905b6da4824728842c228b0e5 Mon Sep 17 00:00:00 2001 From: xjq7 Date: Fri, 10 Jan 2025 11:04:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E9=9F=B3=E4=B9=90=E5=BE=8B=E5=8A=A8):=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B3=A2=E5=BD=A2=E5=8A=A8=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/marching-music/constants.ts | 8 +- src/pages/marching-music/index.tsx | 14 +- src/pages/marching-music/marching-music.ts | 150 ++++++++++++++++++--- 3 files changed, 142 insertions(+), 30 deletions(-) diff --git a/src/pages/marching-music/constants.ts b/src/pages/marching-music/constants.ts index 3a64c44..4816dac 100644 --- a/src/pages/marching-music/constants.ts +++ b/src/pages/marching-music/constants.ts @@ -345,7 +345,7 @@ function genKeyboardData() { width: 50, height: 50, fill: '#ccccd6', - type: '[{', + type: '{[', text: { label: ['{', '['], fontSize: 14, @@ -541,7 +541,7 @@ function genKeyboardData() { width: 50, height: 50, fill: '#ccccd6', - type: '《<', + type: '<', text: { label: ['<'], fontSize: 16, @@ -551,7 +551,7 @@ function genKeyboardData() { width: 50, height: 50, fill: '#ccccd6', - type: '》>', + type: '>', text: { label: ['>'], fontSize: 16, @@ -623,7 +623,7 @@ function genKeyboardData() { width: 290, height: 50, fill: '#ccccd6', - type: 'whitespace', + type: 'space', }, { width: 65, diff --git a/src/pages/marching-music/index.tsx b/src/pages/marching-music/index.tsx index 418633b..50aea3d 100644 --- a/src/pages/marching-music/index.tsx +++ b/src/pages/marching-music/index.tsx @@ -11,7 +11,7 @@ export default function Component() { const marchingMusicRef = useRef(); const inputRef = useRef(); const [file, setFile] = useState(); - const [rhythmMode, setRhythmMode] = useState('spectrogram'); + const [rhythmMode, setRhythmMode] = useState('wave'); const rhythmModeRef = useRef(); const lightInterval = useRef(); @@ -66,7 +66,9 @@ export default function Component() { analyser.getByteFrequencyData(dataArray); marchingMusicRef.current.drawBarLight(dataArray); } else { - // marchingMusicRef.current.drawWaveLight(); + const dataArray = new Uint8Array(analyser.frequencyBinCount); + analyser.getByteTimeDomainData(dataArray); + marchingMusicRef.current.drawWaveLight(dataArray); } }, 96); }; @@ -127,10 +129,10 @@ export default function Component() { label: '频谱', value: 'spectrogram', }, - // { - // label: '波形', - // value: 'wave', - // }, + { + label: '波形', + value: 'wave', + }, ]} placeholder="律动模式" > diff --git a/src/pages/marching-music/marching-music.ts b/src/pages/marching-music/marching-music.ts index 37575e4..0726cdb 100644 --- a/src/pages/marching-music/marching-music.ts +++ b/src/pages/marching-music/marching-music.ts @@ -1,4 +1,6 @@ import { Group, Leafer, PointerEvent, Rect, Text } from 'leafer-ui'; +import { Animate } from '@leafer-in/animate'; + import { keyboards } from './constants'; interface IMarchingMusicConfig {} @@ -12,6 +14,7 @@ export class MarchingMusic { color: string = colors[0]; center?: Rect; container?: Group; + waveData?: Rect[][]; constructor(config: IMarchingMusicConfig) { this.config = config; @@ -24,18 +27,14 @@ export class MarchingMusic { update(config: Partial) { this.config = { ...this.config, ...config }; - this.reDraw(); - } - - draw() { - this.reDraw(); + this.draw(); } destroy() { this.leafer.destroy(); } - reDraw() { + draw() { if (this.container) this.leafer.remove(this.container); this.start = { x: (window.innerWidth - 860) / 2, @@ -90,6 +89,79 @@ export class MarchingMusic { }); this.drawKeyboard(); + this.calWaveData(); + } + + calWaveData() { + const steps = [ + ['t', '^6', '&7', 'u', 'h', 'g'], + ['%5', 'f5', 'f6', 'f7', '*8', 'i', 'j', 'n', 'b', 'v', 'f', 'r'], + ['¥$4', 'f4', 'e', 'd', 'c', 'space', 'f8', '(9', 'o', 'k', 'm'], + ['f3', '#3', 'w', 's', 'x', 'f9', ')0', 'p', 'l', '<', 'space'], + [ + 'f2', + '@2', + 'q', + 'a', + 'z', + 'left command', + 'f10', + '——-', + '{[', + ':;', + '>', + 'right command', + ], + [ + 'f1', + '!1', + 'Tab', + 'Caps Lock', + 'left shift', + 'left option', + 'f11', + '+=', + ']}', + '"', + '?/', + 'right option', + ], + [ + 'esc', + 'fn', + 'control', + '~·', + 'f12', + 'back', + '|\\', + 'enter', + 'right shift', + 'top arrow', + 'left arrow', + ], + ['figure', 'bottom arrow', 'right arrow'], + ]; + + const stepsLevel = steps.reduce((acc, cur, idx) => { + cur.forEach((val) => { + acc.set(val, idx); + }); + return acc; + }, new Map()); + + this.waveData = [[], [], [], [], [], [], [], []]; + + this.container.children.forEach((keyboard) => { + const { isBoard, type } = keyboard.data; + + if (isBoard) { + const level = stepsLevel.get(type); + + if (level !== undefined) { + this.waveData[level].push(keyboard as Rect); + } + } + }); } drawKeyboard() { @@ -166,7 +238,7 @@ export class MarchingMusic { } drawBarLight(audiosData: Uint8Array) { - const keyboards = this.leafer.children[0].children; + const keyboards = this.container.children; const segmentSize = 64; @@ -215,29 +287,67 @@ export class MarchingMusic { }); } - drawWaveLight() { - // const { x, y, width, height } = this.center; - - const firstRound = []; - - this.container.children.forEach((keyboard) => { - if (['t', '^6', '&7', 'u', 'h', 'g'].includes(keyboard.data.type)) { - firstRound.push(keyboard); + drawWaveLight(dataArray: Uint8Array) { + // 强度 + let intensity = 0; + + for (let i = 0; i < dataArray.length; i++) { + if (dataArray[i] > 200 || dataArray[i] < 50) { + intensity = 3; + break; + } else if (dataArray[i] > 175 || dataArray[i] < 75) { + intensity = 2; + break; + } else if (dataArray[i] > 150 || dataArray[i] < 50) { + intensity = 1; + break; } - }); + } - firstRound.forEach((keyboard) => { - if (true) { + if (intensity === 1) { + this.waveData[0].forEach((keyboard) => { keyboard.shadow = { x: 0, y: 0, blur: 12, color: this.color, }; - } else { + }); + this.waveData[1].forEach((keyboard) => { keyboard.shadow = undefined; + }); + } else if (intensity === 2) { + this.waveData[0].concat(this.waveData[1]).forEach((keyboard) => { + keyboard.shadow = { + x: 0, + y: 0, + blur: 12, + color: this.color, + }; + }); + } else if (intensity === 3) { + let i = 1; + while (i <= 6) { + this.waveData[i].forEach((keyboard) => { + new Animate( + keyboard, + [ + { + shadow: { + x: 0, + y: 0, + blur: 12, + color: this.color, + }, + }, + { shadow: undefined }, + ], + { duration: 1, delay: 0.12 * i } + ); + }); + i++; } - }); + } this.center.shadow = { x: 0,