1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
| import "./App.css"; import { connect, createAudioNode, removeAudioNode } from "./audio"; import { OscillatorNode } from "./components/OscillatorNode"; import { VolumeNode } from "./components/VolumeNode"; import { addEdge, Background, BackgroundVariant, Connection, Controls, Edge, MiniMap, Node, Panel, ReactFlow, useEdgesState, useNodesState, } from "@xyflow/react"; import "@xyflow/react/dist/style.css"; import { OutputNode } from "./components/OutputNode"; import { CustomEdge } from "./components/CustomEdge"; const initialNodes: Node[] = [ { id: "a", type: "osc", data: { frequency: 220, type: "square" }, position: { x: 200, y: 0 }, }, { id: "b", type: "vol", data: { gain: 0.5 }, position: { x: 150, y: 250 }, }, { id: "c", type: "out", data: {}, position: { x: 350, y: 400 }, }, ];
const initialEdges: Edge[] = []; const nodeType = { vol: VolumeNode, osc: OscillatorNode, out: OutputNode, };
function App() { const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); const onConnect = (parmas: Connection) => { connect(parmas.source, parmas.target); setEdges((eds) => addEdge({ ...parmas, type: "custom" }, eds)); };
function addOscNode() { const id = Math.random().toString().slice(2, 8); const position = { x: 0, y: 0 }; const type = "osc"; const data = { frequency: 400, type: "sine" };
setNodes([...nodes, { id, position, type, data }]); createAudioNode(id, type, data); } function addVolumeNode() { const id = Math.random().toString().slice(2, 8); const data = { gain: 0.5 }; const position = { x: 0, y: 0 }; const type = "volume";
setNodes([...nodes, { id, type, data, position }]); createAudioNode(id, type, data); } return ( <> <div style={{ width: " 100vw", height: "100vh" }}> <ReactFlow nodes={nodes} edges={edges} onNodesChange={onNodesChange} onEdgesChange={onEdgesChange} onConnect={onConnect} nodeTypes={nodeType} edgeTypes={{ custom: CustomEdge, }} onNodesDelete={(nodes) => { for (const { id } of nodes) { removeAudioNode(id); } }} fitView > <Controls /> <MiniMap /> <Background variant={BackgroundVariant.Lines} /> <Panel className={"space-x-4"} position="top-right"> <button className={"p-[4px] rounded bg-white shadow"} onClick={addOscNode} > 添加振荡器节点 </button> <button className={"p-[4px] rounded bg-white shadow"} onClick={addVolumeNode} > 添加音量节点 </button> </Panel> </ReactFlow> </div> </> ); }
export default App;
|