|
@@ -126,21 +126,19 @@ export default defineComponent({
|
|
canvasDom.width = width
|
|
canvasDom.width = width
|
|
canvasDom.height = height
|
|
canvasDom.height = height
|
|
// audio
|
|
// audio
|
|
- const audioCtx = new AudioContext()
|
|
|
|
- const analyser = audioCtx.createAnalyser()
|
|
|
|
- const source = audioCtx.createMediaElementSource(audioDom)
|
|
|
|
- analyser.fftSize = fftSize
|
|
|
|
- source.connect(analyser)
|
|
|
|
- analyser.connect(audioCtx.destination)
|
|
|
|
- const dataArray = new Uint8Array(analyser.frequencyBinCount)
|
|
|
|
|
|
+ let audioCtx : AudioContext | null = null
|
|
|
|
+ let analyser : AnalyserNode | null = null
|
|
|
|
+ let source : MediaElementAudioSourceNode | null = null
|
|
|
|
+ const dataArray = new Uint8Array(fftSize / 2)
|
|
const draw = (data: Uint8Array, ctx: CanvasRenderingContext2D, { lineGap, canvWidth, canvHeight, canvFillColor, lineColor }: propsType) => {
|
|
const draw = (data: Uint8Array, ctx: CanvasRenderingContext2D, { lineGap, canvWidth, canvHeight, canvFillColor, lineColor }: propsType) => {
|
|
if (!ctx) return
|
|
if (!ctx) return
|
|
const w = canvWidth
|
|
const w = canvWidth
|
|
const h = canvHeight
|
|
const h = canvHeight
|
|
fillCanvasBackground(ctx, w, h, canvFillColor)
|
|
fillCanvasBackground(ctx, w, h, canvFillColor)
|
|
- // 可视化
|
|
|
|
|
|
+ // 可视化
|
|
const dataLen = data.length
|
|
const dataLen = data.length
|
|
- const step = (w / 2 - lineGap * dataLen) / dataLen
|
|
|
|
|
|
+ let step = (w / 2 - lineGap * dataLen) / dataLen
|
|
|
|
+ step < 1 && (step = 1)
|
|
const midX = w / 2
|
|
const midX = w / 2
|
|
const midY = h / 2
|
|
const midY = h / 2
|
|
let xLeft = midX
|
|
let xLeft = midX
|
|
@@ -178,7 +176,7 @@ export default defineComponent({
|
|
}
|
|
}
|
|
const requestAnimationFrameFun = () => {
|
|
const requestAnimationFrameFun = () => {
|
|
requestAnimationFrame(() => {
|
|
requestAnimationFrame(() => {
|
|
- analyser.getByteFrequencyData(dataArray)
|
|
|
|
|
|
+ analyser?.getByteFrequencyData(dataArray)
|
|
draw(dataArray, canvasCtx, {
|
|
draw(dataArray, canvasCtx, {
|
|
lineGap: 2,
|
|
lineGap: 2,
|
|
canvWidth: width,
|
|
canvWidth: width,
|
|
@@ -193,13 +191,23 @@ export default defineComponent({
|
|
}
|
|
}
|
|
let isPause = true
|
|
let isPause = true
|
|
const playVisualDraw = () => {
|
|
const playVisualDraw = () => {
|
|
- isPause = false
|
|
|
|
|
|
+ if (!audioCtx) {
|
|
|
|
+ audioCtx = new AudioContext()
|
|
|
|
+ source = audioCtx.createMediaElementSource(audioDom)
|
|
|
|
+ }
|
|
|
|
+ analyser = audioCtx.createAnalyser()
|
|
|
|
+ analyser.fftSize = fftSize
|
|
|
|
+ source?.connect(analyser)
|
|
|
|
+ analyser.connect(audioCtx.destination)
|
|
audioCtx.resume()
|
|
audioCtx.resume()
|
|
|
|
+ isPause = false
|
|
requestAnimationFrameFun()
|
|
requestAnimationFrameFun()
|
|
}
|
|
}
|
|
const pauseVisualDraw = () => {
|
|
const pauseVisualDraw = () => {
|
|
isPause = true
|
|
isPause = true
|
|
- audioCtx.suspend()
|
|
|
|
|
|
+ audioCtx?.suspend()
|
|
|
|
+ source?.disconnect()
|
|
|
|
+ analyser?.disconnect()
|
|
}
|
|
}
|
|
return {
|
|
return {
|
|
playVisualDraw,
|
|
playVisualDraw,
|