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
ad8c476
commit 35320c4
Showing
8 changed files
with
266 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
import React, { | ||
FC, | ||
forwardRef, | ||
useEffect, | ||
useImperativeHandle, | ||
useMemo, | ||
useRef, | ||
useState, | ||
type ForwardRefRenderFunction, | ||
} from 'react'; | ||
import { song1, song2 } from './constant'; | ||
import './index.css'; | ||
import type { PianoHandle, PianoProps } from './interface'; | ||
|
||
const Piano: ForwardRefRenderFunction<PianoHandle, PianoProps> = (props, ref) => { | ||
const keys: Record<string, { frequency: number }> = { | ||
A: { frequency: 196 }, | ||
S: { frequency: 220 }, | ||
D: { frequency: 246 }, | ||
F: { frequency: 261 }, | ||
G: { frequency: 293 }, | ||
H: { frequency: 329 }, | ||
J: { frequency: 349 }, | ||
K: { frequency: 392 }, | ||
L: { frequency: 440 }, | ||
Z: { frequency: 493 }, | ||
X: { frequency: 523 }, | ||
C: { frequency: 587 }, | ||
V: { frequency: 659 }, | ||
}; | ||
|
||
const context = useMemo(() => new AudioContext(), []); | ||
|
||
const play = (key: string) => { | ||
const frequency = keys[key]?.frequency; | ||
if (!frequency) return; | ||
|
||
const osc = context.createOscillator(); | ||
osc.type = 'sine'; | ||
osc.frequency.value = frequency; | ||
|
||
const gain = context.createGain(); | ||
osc.connect(gain); | ||
gain.connect(context.destination); | ||
|
||
gain.gain.setValueAtTime(0, context.currentTime); | ||
gain.gain.linearRampToValueAtTime(1, context.currentTime + 0.01); | ||
|
||
osc.start(context.currentTime); | ||
|
||
gain.gain.exponentialRampToValueAtTime(0.001, context.currentTime + 1); | ||
osc.stop(context.currentTime + 1); | ||
|
||
const keyElement = document.getElementById(`key-${key}`); | ||
keyElement?.classList.add('pressed'); | ||
setTimeout(() => { | ||
keyElement?.classList.remove('pressed'); | ||
}, 100); | ||
}; | ||
|
||
useEffect(() => { | ||
const handleKeyDown = (e: KeyboardEvent) => { | ||
play(e.key.toUpperCase()); | ||
}; | ||
document.addEventListener('keydown', handleKeyDown); | ||
return () => { | ||
document.removeEventListener('keydown', handleKeyDown); | ||
}; | ||
}, []); | ||
|
||
const map: Record<number, string> = { | ||
1: 'A', | ||
2: 'S', | ||
3: 'D', | ||
4: 'F', | ||
5: 'G', | ||
6: 'H', | ||
7: 'J', | ||
8: 'K', | ||
9: 'L', | ||
10: 'Z', | ||
11: 'X', | ||
12: 'C', | ||
13: 'V', | ||
}; | ||
|
||
useImperativeHandle(ref, () => ({ | ||
playMusic, | ||
songs: { | ||
1: song1, | ||
2: song2, | ||
}, | ||
})); | ||
|
||
function playMusic(music: number[][]) { | ||
let startTime = 0; | ||
music.forEach((item) => { | ||
setTimeout(() => { | ||
play(map[item[0]]); | ||
}, startTime * 0.5); | ||
startTime += item[1]; | ||
}); | ||
} | ||
|
||
return ( | ||
<div> | ||
<section className="keys-container"> | ||
{Object.keys(keys).map((item) => ( | ||
<div className="key" key={item} id={`key-${item}`} onClick={() => play(item)}> | ||
<span>{item}</span> | ||
</div> | ||
))} | ||
</section> | ||
</div> | ||
); | ||
}; | ||
export default forwardRef(Piano); |
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,22 @@ | ||
export const song1 = [ | ||
[6, 1000], | ||
[5, 1000], | ||
[3, 1000], | ||
[5, 1000], | ||
[8, 1000], | ||
[6, 500], | ||
[5, 500], | ||
[6, 1000], | ||
]; | ||
|
||
export const song2 = [ | ||
[6, 1000], | ||
[6, 1000], | ||
[6, 1000], | ||
[3, 500], | ||
[6, 500], | ||
[5, 1000], | ||
[3, 500], | ||
[2, 500], | ||
[3, 1000], | ||
]; |
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,71 @@ | ||
import { Button, Spin } from 'antd'; | ||
import { Piano } from 'ims-view-pc'; | ||
import React, { useRef, useState, type ElementRef } from 'react'; | ||
|
||
const Demo = () => { | ||
const PinaoRef = useRef<ElementRef<typeof Piano>>(null!); | ||
|
||
const simplifiedSong = [ | ||
[8, 800], | ||
[8, 800], | ||
[8, 800], | ||
[9, 400], | ||
[9, 400], | ||
[10, 200], | ||
[10, 200], | ||
[12, 200], | ||
[12, 200], | ||
[13, 200], | ||
[13, 200], | ||
[8, 800], | ||
[9, 400], | ||
[9, 400], | ||
[10, 200], | ||
[10, 200], | ||
[12, 200], | ||
[12, 200], | ||
[8, 800], | ||
[10, 200], | ||
[9, 400], | ||
[9, 400], | ||
[8, 800], | ||
[8, 800], | ||
[8, 800], | ||
[9, 400], | ||
[9, 400], | ||
[10, 200], | ||
[10, 200], | ||
[12, 200], | ||
[12, 200], | ||
[13, 200], | ||
[13, 200], | ||
[8, 800], | ||
[9, 400], | ||
[9, 400], | ||
[10, 200], | ||
[10, 200], | ||
[12, 200], | ||
[12, 200], | ||
[8, 800], | ||
[10, 200], | ||
[9, 400], | ||
[9, 400], | ||
]; | ||
|
||
return ( | ||
<> | ||
<Piano ref={PinaoRef} /> | ||
|
||
<button type="button" onClick={() => PinaoRef.current.playMusic(PinaoRef.current.songs[1])}> | ||
世上只有妈妈好 | ||
</button> | ||
<button type="button" onClick={() => PinaoRef.current.playMusic(PinaoRef.current.songs[2])}> | ||
奢香夫人 | ||
</button> | ||
<button type="button" onClick={() => PinaoRef.current.playMusic(simplifiedSong)}> | ||
光年之外 | ||
</button> | ||
</> | ||
); | ||
}; | ||
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,29 @@ | ||
.pressed { | ||
background: #aaa; | ||
} | ||
|
||
.keys-container { | ||
display: flex; | ||
overflow: hidden; | ||
flex-direction: row; | ||
justify-content: space-between; | ||
margin: 40px auto; | ||
width: 800px; | ||
height: 400px; | ||
} | ||
|
||
.key { | ||
display: flex; | ||
align-items: center; | ||
flex: 1; | ||
justify-content: center; | ||
border: 4px solid black; | ||
background: #fff; | ||
text-align: center; | ||
font-size: 50px; | ||
line-height: 500px; | ||
} | ||
|
||
.key:hover { | ||
background: #aaa; | ||
} |
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,12 @@ | ||
--- | ||
title: Piano | ||
description: 钢琴 | ||
order: 0 | ||
toc: content | ||
demo: | ||
cols: 2 | ||
--- | ||
|
||
## Piano 钢琴 | ||
|
||
<code src="./demo/index.tsx">钢琴</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 Piano from './Piano'; | ||
export default Piano; |
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,9 @@ | ||
export interface PianoProps {} | ||
|
||
export type PianoHandle = { | ||
playMusic: (music: number[][]) => void; | ||
songs: { | ||
1: number[][]; | ||
2: number[][]; | ||
}; | ||
}; |
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