generated from eternallycyf/ims-monorepo-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7654dac
commit c1a0740
Showing
12 changed files
with
354 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
const context = new AudioContext(); | ||
|
||
const osc = context.createOscillator(); | ||
osc.frequency.value = 220; | ||
osc.type = 'square'; | ||
osc.start(); | ||
|
||
const volume = context.createGain(); | ||
volume.gain.value = 0.5; | ||
|
||
const out = context.destination; | ||
|
||
const nodes = new Map(); | ||
|
||
nodes.set('a', osc); | ||
nodes.set('b', volume); | ||
nodes.set('c', out); | ||
|
||
export function isRunning() { | ||
return context.state === 'running'; | ||
} | ||
|
||
export function toggleAudio() { | ||
return isRunning() ? context.suspend() : context.resume(); | ||
} | ||
|
||
export function updateAudioNode(id: string, data: Record<string, any>) { | ||
const node = nodes.get(id); | ||
|
||
for (const [key, val] of Object.entries(data)) { | ||
if (node[key] instanceof AudioParam) { | ||
node[key].value = val; | ||
} else { | ||
node[key] = val; | ||
} | ||
} | ||
} | ||
|
||
export function removeAudioNode(id: string) { | ||
const node = nodes.get(id); | ||
|
||
node.disconnect(); | ||
node.stop?.(); | ||
|
||
nodes.delete(id); | ||
} | ||
|
||
export function connect(sourceId: string, targetId: string) { | ||
const source = nodes.get(sourceId); | ||
const target = nodes.get(targetId); | ||
|
||
window.osc = osc; | ||
source.connect(target); | ||
} | ||
|
||
export function disconnect(sourceId: string, targetId: string) { | ||
const source = nodes.get(sourceId); | ||
const target = nodes.get(targetId); | ||
source.disconnect(target); | ||
} | ||
|
||
export function createAudioNode(id: string, type: string, data: Record<string, any>) { | ||
switch (type) { | ||
case 'osc': { | ||
const node = context.createOscillator(); | ||
node.frequency.value = data.frequency; | ||
node.type = data.type; | ||
node.start(); | ||
|
||
nodes.set(id, node); | ||
break; | ||
} | ||
|
||
case 'volume': { | ||
const node = context.createGain(); | ||
node.gain.value = data.gain; | ||
|
||
nodes.set(id, node); | ||
break; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { | ||
addEdge, | ||
Background, | ||
BackgroundVariant, | ||
Connection, | ||
Controls, | ||
Edge, | ||
EdgeTypes, | ||
MiniMap, | ||
Node, | ||
OnConnect, | ||
Panel, | ||
ReactFlow, | ||
useEdgesState, | ||
useNodesState, | ||
} from '@xyflow/react'; | ||
import '@xyflow/react/dist/style.css'; | ||
import { connect, createAudioNode } from './Audio'; | ||
import { OscillatorNode } from './components/OscillatorNode'; | ||
import { OutputNode } from './components/OutputNode'; | ||
import { VolumeNode } from './components/VolumeNode'; | ||
|
||
const initialNodes: Node[] = [ | ||
{ | ||
id: 'a', | ||
type: 'osc', | ||
data: { frequency: 220, type: 'square' }, | ||
position: { x: 200, y: 0 }, | ||
}, | ||
{ | ||
id: 'b', | ||
type: 'volume', | ||
data: { gain: 0.5 }, | ||
position: { x: 150, y: 250 }, | ||
}, | ||
{ | ||
id: 'c', | ||
type: 'out', | ||
data: {}, | ||
position: { x: 350, y: 400 }, | ||
}, | ||
]; | ||
|
||
const initialEdges: Edge[] = []; | ||
|
||
const nodeTypes = { | ||
osc: OscillatorNode, | ||
volume: VolumeNode, | ||
out: OutputNode, | ||
}; | ||
|
||
export default function Flow() { | ||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); | ||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); | ||
|
||
const onConnect = (params: Connection) => { | ||
connect(params.source, params.target); | ||
setEdges((eds) => addEdge(params, 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, type, data, position }]); | ||
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: 'auto', height: '100vh' }}> | ||
<ReactFlow | ||
nodes={nodes} | ||
edges={edges} | ||
onNodesChange={onNodesChange} | ||
onEdgesChange={onEdgesChange} | ||
onConnect={onConnect} | ||
nodeTypes={nodeTypes} | ||
fitView | ||
> | ||
<Controls /> | ||
<MiniMap /> | ||
<Background variant={BackgroundVariant.Lines} /> | ||
<Panel className={'space-x-4'} position="top-right"> | ||
<button type="button" className={'p-[4px] rounded bg-white shadow'} onClick={addOscNode}> | ||
添加振荡器节点 | ||
</button> | ||
<button | ||
type="button" | ||
className={'p-[4px] rounded bg-white shadow'} | ||
onClick={addVolumeNode} | ||
> | ||
添加音量节点 | ||
</button> | ||
</Panel> | ||
</ReactFlow> | ||
</div> | ||
); | ||
} |
55 changes: 55 additions & 0 deletions
55
packages/ims-view-pc/src/components/Flow/components/OscillatorNode.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import { Handle, Position, useReactFlow } from '@xyflow/react'; | ||
import { ChangeEvent, ChangeEventHandler, useState } from 'react'; | ||
import { updateAudioNode } from '../Audio'; | ||
|
||
export interface OscillatorNodeProps { | ||
id: string; | ||
data: { | ||
frequency: number; | ||
type: string; | ||
}; | ||
} | ||
|
||
export function OscillatorNode({ id, data }: OscillatorNodeProps) { | ||
const [frequency, setFrequency] = useState(data.frequency); | ||
const [type, setType] = useState(data.type); | ||
|
||
const changeFrequency: ChangeEventHandler<HTMLInputElement> = (e) => { | ||
setFrequency(+e.target.value); | ||
updateAudioNode(id, { frequency: +e.target.value }); | ||
}; | ||
|
||
const changeType: ChangeEventHandler<HTMLSelectElement> = (e) => { | ||
setType(e.target.value); | ||
updateAudioNode(id, { type: e.target.value }); | ||
}; | ||
|
||
return ( | ||
<div className={'bg-white shadow-xl'}> | ||
<p className={'rounded-t-md p-[8px] bg-pink-500 text-white'}>振荡器节点</p> | ||
<div className={'flex flex-col p-[8px]'}> | ||
<span>频率</span> | ||
<input | ||
className="nodrag" | ||
type="range" | ||
min="10" | ||
max="1000" | ||
value={frequency} | ||
onChange={changeFrequency} | ||
/> | ||
<span className={'text-right'}>{frequency}赫兹</span> | ||
</div> | ||
<hr className={'mx-[4px]'} /> | ||
<div className={'flex flex-col p-[8px]'}> | ||
<p>波形</p> | ||
<select value={type} onChange={changeType}> | ||
<option value="sine">正弦波</option> | ||
<option value="triangle">三角波</option> | ||
<option value="sawtooth">锯齿波</option> | ||
<option value="square">方波</option> | ||
</select> | ||
</div> | ||
<Handle className="w-[10px] h-[10px]" type="source" position={Position.Bottom} /> | ||
</div> | ||
); | ||
} |
26 changes: 26 additions & 0 deletions
26
packages/ims-view-pc/src/components/Flow/components/OutputNode.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { Handle, Position } from '@xyflow/react'; | ||
import { useState } from 'react'; | ||
import { toggleAudio } from '../Audio'; | ||
|
||
export function OutputNode() { | ||
const [isRunning, setIsRuning] = useState(false); | ||
|
||
return ( | ||
<div className={'bg-white shadow-xl p-[20px]'}> | ||
<Handle className="w-[10px] h-[10px]" type="target" position={Position.Top} /> | ||
|
||
<div> | ||
<p>输出节点</p> | ||
<button | ||
type="button" | ||
onClick={() => { | ||
setIsRuning((isRunning) => !isRunning); | ||
toggleAudio(); | ||
}} | ||
> | ||
{isRunning ? <span role="img">🔈</span> : <span role="img">🔇</span>} | ||
</button> | ||
</div> | ||
</div> | ||
); | ||
} |
42 changes: 42 additions & 0 deletions
42
packages/ims-view-pc/src/components/Flow/components/VolumeNode.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { Handle, Position } from '@xyflow/react'; | ||
import { ChangeEvent, ChangeEventHandler, useState } from 'react'; | ||
import { updateAudioNode } from '../Audio'; | ||
|
||
export interface VolumeNodeProps { | ||
id: string; | ||
data: { | ||
gain: number; | ||
}; | ||
} | ||
|
||
export function VolumeNode({ id, data }: VolumeNodeProps) { | ||
const [gain, setGain] = useState(data.gain); | ||
|
||
const changeGain: ChangeEventHandler<HTMLInputElement> = (e) => { | ||
setGain(+e.target.value); | ||
updateAudioNode(id, { gain: +e.target.value }); | ||
}; | ||
|
||
return ( | ||
<div className={'rounded-md bg-white shadow-xl'}> | ||
<Handle type="target" className="w-[10px] h-[10px]" position={Position.Top} /> | ||
|
||
<p className={'rounded-t-md p-[4px] bg-blue-500 text-white'}>音量节点</p> | ||
<div className={'flex flex-col p-[4px]'}> | ||
<p>Gain</p> | ||
<input | ||
className="nodrag" | ||
type="range" | ||
min="0" | ||
max="1" | ||
step="0.01" | ||
value={gain} | ||
onChange={changeGain} | ||
/> | ||
<p className={'text-right'}>{gain.toFixed(2)}</p> | ||
</div> | ||
|
||
<Handle type="source" className="w-[10px] h-[10px]" position={Position.Bottom} /> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { Flow } from 'ims-view-pc'; | ||
import React from 'react'; | ||
|
||
const Demo = () => { | ||
return ( | ||
<> | ||
<Flow /> | ||
</> | ||
); | ||
}; | ||
export default Demo; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
--- | ||
title: Flow | ||
description: 流程图 | ||
group: | ||
title: 其他 | ||
toc: content | ||
--- | ||
|
||
## Flow 流程图 | ||
|
||
## 示例 | ||
|
||
<code transform="true" src="./demo/index.tsx">Flow</code> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
import Flow from './Flow'; | ||
export default Flow; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export interface FlowProps {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.