gpt4 book ai didi

javascript - HTML5 Canvas 画一个圆圈并随着音乐移动?

转载 作者:行者123 更新时间:2023-12-04 09:56:36 24 4
gpt4 key购买 nike

我能够在圆圈周围画线。我有 AudioContext API 设置的基本实现。

我面临的问题是调用 lineTo 时这条线只会增长但不会缩小。我受此启发 https://www.kkhaydarov.com/audio-visualizer/ .我将这段代码翻译成 https://codesandbox.io/s/hungry-tereshkova-1pf0c?runonclick=1&file=/src/Visualizer.js:713-725这是一个 React.js 版本。

如果您运行该代码,您将看到音乐播放,然后条形将增长一次,然后它们会粘住。他们拒绝收缩然后随着节拍成长。

我不确定我哪里出错了或者我在该代码中缺少什么。它似乎与示例中的其他代码非常相似。

enter image description here

这是 Visualizer 组件的完整代码。

import React, { useEffect, useRef } from "react";

let frequencyArray = [];
let analyser;

const Visualizer = () => {
const canvasRef = useRef(null);
const requestRef = useRef(null);

useEffect(() => {
initAudio();
requestRef.current = requestAnimationFrame(drawCanvas);
return () => cancelAnimationFrame(requestRef.current);

// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const initAudio = () => {
const audio = new Audio();
audio.src =
"https://s3.us-west-2.amazonaws.com/storycreator.uploads/ck9kpb5ss0xf90132mgf8z893?client_id=d8976b195733c213f3ead34a2d95d1c1";
audio.crossOrigin = "anonymous";
audio.load();

const context = new (window.AudioContext || window.webkitAudioContext)();
analyser = context.createAnalyser();
const source = context.createMediaElementSource(audio);

source.connect(analyser);
analyser.connect(context.destination);

frequencyArray = new Uint8Array(analyser.frequencyBinCount);
audio.play();
};

// draw the whole thing
const drawCanvas = () => {
if (canvasRef.current) {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
const radius = 200;
const bars = 100;

drawCircle(canvas, ctx, radius);

analyser.getByteFrequencyData(frequencyArray);

for (var i = 0; i < bars; i++) {
const height = frequencyArray[i] * 0.3;

drawLine(
{
i,
bars,
height,
radius
},
canvas,
ctx
);
}

requestRef.current = requestAnimationFrame(drawCanvas);
}
};

// draw the main circle
const drawCircle = (canvas, ctx, radius) => {
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;

ctx.save();
ctx.beginPath();
ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
ctx.fillStyle = "white";
ctx.fill();
ctx.strokeStyle = "#dddddd";
ctx.lineWidth = 5;
ctx.stroke();
ctx.restore();
};

// dray lines around the circle
const drawLine = (opts, canvas, ctx) => {
const { i, radius, bars, height } = opts;
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
const lineWidth = 10;
const rads = (Math.PI * 2) / bars;

const x = centerX + Math.cos(rads * i) * (radius + lineWidth);
const y = centerY + Math.sin(rads * i) * (radius + lineWidth);
const endX = centerX + Math.cos(rads * i) * (radius + height);
const endY = centerY + Math.sin(rads * i) * (radius + height);

// draw the bar
ctx.strokeStyle = "#ddd";
ctx.lineWidth = lineWidth;
ctx.lineCap = "round";
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(endX, endY);
ctx.stroke();
};

return (
<canvas
ref={canvasRef}
style={{ background: "#f5f5f5" }}
width={window.innerWidth}
height={window.innerHeight}
/>
);
};

export default Visualizer;

最佳答案

您刚刚错过了 clearRect在你的代码中......
没有它,我们看到线条的增长只是因为任何后面的较短的线条都不会覆盖前面的线条,它们仍然被绘制,只是我们没有看到它。

这是工作代码:

https://codesandbox.io/s/dry-cdn-ghu4m?file=/src/Visualizer.js:1247-1276

我硬编码了 ctx.clearRect(0,0, 1000,1000)只是为了向您展示它有效,但您应该在那里使用 Canvas 尺寸,其他一切看起来都不错。

唯一的建议是以某种方式移动:

const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");

在 drawCanvas 函数之外的某个全局位置,
这些在每次运行时都不会改变,只需设置一次就可以了。

关于javascript - HTML5 Canvas 画一个圆圈并随着音乐移动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61903270/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com