Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/455.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript HTML5画布在圆圈中画线,并随着音乐移动?_Javascript_Html_Reactjs_Canvas - Fatal编程技术网

Javascript HTML5画布在圆圈中画线,并随着音乐移动?

Javascript HTML5画布在圆圈中画线,并随着音乐移动?,javascript,html,reactjs,canvas,Javascript,Html,Reactjs,Canvas,我能画一条围绕圆圈的线。我有AudioContext API设置的基本实现 我面临的问题是,当调用lineTo时,该行只会增长,而不会收缩。这让我深受鼓舞。我正在将这段代码翻译成React.js版本 如果你运行代码,你会看到音乐播放,然后酒吧将增长一次,然后他们坚持。他们拒绝收缩,然后随着节奏成长 我不知道我哪里出错了,或者我在代码中遗漏了什么。它似乎与示例中的其他代码非常相似 下面是可视化工具组件的完整代码 import React, { useEffect, useRef } from "

我能画一条围绕圆圈的线。我有AudioContext API设置的基本实现

我面临的问题是,当调用
lineTo
时,该行只会增长,而不会收缩。这让我深受鼓舞。我正在将这段代码翻译成React.js版本

如果你运行代码,你会看到音乐播放,然后酒吧将增长一次,然后他们坚持。他们拒绝收缩,然后随着节奏成长

我不知道我哪里出错了,或者我在代码中遗漏了什么。它似乎与示例中的其他代码非常相似

下面是可视化工具组件的完整代码

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;
import React,{useffect,useRef}来自“React”;
let frequencyArray=[];
let分析仪;
常量可视化工具=()=>{
const canvasRef=useRef(null);
const requestRef=useRef(null);
useffect(()=>{
initAudio();
requestRef.current=requestAnimationFrame(drawCanvas);
return()=>cancelAnimationFrame(requestRef.current);
//eslint禁用下一行react HOOK/deps
}, []);
常量initAudio=()=>{
const audio=新音频();
audio.src=
"https://s3.us-west-2.amazonaws.com/storycreator.uploads/ck9kpb5ss0xf90132mgf8z893?client_id=d8976b195733c213f3ead34a2d95d1c1";
audio.crossOrigin=“匿名”;
load();
const context=new(window.AudioContext | | window.webkitadiocontext)();
Analyzer=context.createAnalyzer();
const source=context.createMediaElementSource(音频);
源。连接(分析仪);
分析器.连接(上下文.目的地);
frequencyArray=新的UINT8阵列(分析仪。frequencyBinCount);
音频播放();
};
//把整件事都画出来
const drawCanvas=()=>{
如果(canvasRef.current){
const canvas=canvasRef.current;
const ctx=canvas.getContext(“2d”);
常数半径=200;
常数棒=100;
drawCircle(画布、ctx、半径);
分析仪。GetByTefFrequencyData(频率阵列);
对于(变量i=0;i{
const centerX=canvas.width/2;
const centerY=canvas.height/2;
ctx.save();
ctx.beginPath();
ctx.弧(中心x,中心y,半径,0,2*Math.PI,假);
ctx.fillStyle=“白色”;
ctx.fill();
ctx.strokeStyle=“#dddddd”;
ctx.lineWidth=5;
ctx.stroke();
ctx.restore();
};
//绕着圆圈画线
常量绘制线=(选项、画布、ctx)=>{
常数{i,半径,条形,高度}=选项;
const centerX=canvas.width/2;
const centerY=canvas.height/2;
常数线宽=10;
常数rads=(Math.PI*2)/bar;
常数x=中心x+数学cos(rads*i)*(半径+线宽);
常数y=中心y+数学sin(rads*i)*(半径+线宽);
常数endX=中心x+数学cos(rads*i)*(半径+高度);
常数=centerY+数学sin(rads*i)*(半径+高度);
//划清界限
ctx.strokeStyle=“#ddd”;
ctx.lineWidth=线宽;
ctx.lineCap=“圆形”;
ctx.beginPath();
ctx.moveTo(x,y);
ctx.lineTo(endX,endY);
ctx.stroke();
};
返回(
);
};
导出默认可视化工具;

您刚刚在代码中遗漏了一个
clearRect

没有这一点,我们只能看到线条增长,因为后面的任何短线条都不会覆盖前面的线条,它们仍然会被画出来,只是我们看不到而已

以下是工作代码:

我硬编码了一个
ctx.clearRect(0,010011000)
只是为了向您展示它的工作原理,但是您应该在那里使用画布尺寸,其他一切看起来都很好

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

const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
drawCanvas函数之外的全局某处,

这些代码不会在每次运行时都更改,只需设置一次就好了。

基于浏览器的代码编辑器很棘手。老实说,我对codesandbox印象深刻,它不可能100%完美。我把它放在
drawCanvas
的顶部,效果非常好。太棒了。谢谢你指出。基于浏览器的一切都很棘手。。。或者只是简单的困难,甚至有时令人兴奋的复杂。。。工作安全鼓点。