kevinsqi / react-piano Goto Github PK
View Code? Open in Web Editor NEWAn interactive piano keyboard for React
Home Page: https://www.kevinqi.com/react-piano/
License: MIT License
An interactive piano keyboard for React
Home Page: https://www.kevinqi.com/react-piano/
License: MIT License
Hi Kevin,
I'm impressed with the piano. The sounds are great!
I wonder if it might benefit from keyboard shortcuts to change the octave up/down?
Best wishes,
Dan
hello .. u can make web studio audio record and midi player and editor ?
The rounding of the downward corners always have the same diameter, which make the keys look quite silly in a very small scale.
Hey,
I have a German keyboard and so when I use your module (which is amazing btw) with keyboard shortcuts enabled, I have to press Y even though for me the respective black key should be Z.
Is there some parameter that can handle that today already, or would we have to make a change for this? Happy to help if necessary.
Currently, the component behaves both as controlled and uncontrolled.
The only mouseclick that should matter should be the one happening on the Piano rather than the whole document. Same for touch events. The problem is even that triggers a re-render.
Hi Kevin,
Thank you so much for your contribution of react-piano. I am utilizing your package to display different piano chord shapes - when a user selects a chord shape (e.g. Major), I have set those notes in Active Notes (& in turn, Active Notes highlights the 3 keys on the piano that make C Major). This all functions correctly. However, if I move my mouse over any of the highlighted keys (active), they become unhighlighted (inactive). How can I change this property such that unless a new array of Active notes is provided, the keys remain highlighted & are unaffected by mouseover? Thank you!
<PianoController firstNote="f4" secondNote="f7" soundFont={soundFont} />
<PianoController firstNote="e1" secondNote="e4" soundFont={soundFont} />
Hi there, Im using your keyboard on mobile screen, so I split it in two keyboards due to screen size.
When I'm turning note labels on or off, only note labels on bottom keyboard will be turned off or on, only after app is restarted, will both keyboards labels be turned of or on, how could I change that so that I can turn labels on both keyboards?
First thanks for this great component. It's a delight to use.
WOuld it be possible to register keyboard events on something else than "window"? In our application, we may end up having multiple piano on screen. WOuld it be possible to scope the keyboard shortcut processing to the focused piano?
Hi all,
I have attached build log.
I forked the repo and did a npm install
and got the following errors:
Quick summary:
npm ERR! In file included from ../src/common/allocator.cc:1:
npm ERR! In file included from ../../nan/nan.h:174:
npm ERR! ../../nan/nan_callbacks.h:55:23: error: no member named 'AccessorSignature' in namespace 'v8'
npm ERR! typedef v8::Localv8::AccessorSignature Sig;
npm ERR! ~~~~^
npm ERR! In file included from ../src/common/allocator.cc:1:
npm ERR! ../../nan/nan.h:2536:8: error: no matching member function for call to 'SetAccessor'
npm ERR! tpl->SetAccessor(
npm ERR! ~~~~~^~~~~~~~~~~
npm ERR! /Users/paulwilkinson/Library/Caches/node-gyp/19.3.0/include/node/v8-template.h:814:8: note: candidate function not viable: no known conversion from 'imp::Sig' (aka 'int') to 'v8::SideEffectType' for 7th argument
npm ERR! void SetAccessor(
npm ERR! ^
npm ERR! /Users/paulwilkinson/Library/Caches/node-gyp/19.3.0/include/node/v8-template.h:807:8: note: candidate function not viable: no known conversion from 'imp::NativeGetter' (aka 'void ()(v8::Localv8::Name, const v8::PropertyCallbackInfov8::Value &)') to 'v8::AccessorGetterCallback' (aka 'void ()(Localv8::String, const PropertyCallbackInfov8::Value &)') for 2nd argument
npm ERR! void SetAccessor(
npm ERR! ^
npm ERR! In file included from ../src/common/allocator.cc:1:
npm ERR! In file included from ../../nan/nan.h:2884:
npm ERR! ../../nan/nan_typedarray_contents.h:34:43: error: no member named 'GetContents' in 'v8::ArrayBuffer'
npm ERR! data = static_cast<char*>(buffer->GetContents().Data()) + byte_offset;
npm ERR! ~~~~~~~~^
npm ERR! 3 errors generated.
2023-01-03T18_26_32_656Z-debug-0.log
Dunno how else to ask that :-)
Hi there,
Thanks for this handy little library! It looks to me like playNote
and onPlayNoteInput
are both callbacks which are called when a key is pressed, and they both get passed the midi number of the note. onPlayNoteInput
gets an additional argument, prevActiveNotes
. Besides that, is there a difference between these two? Thanks!
Hello @iqnivek , i've seen this project and notice it needs a logo!
i can help with it, i'm a graphic designer and i contribute to open source projects, like this one!
i'd like to know your toughts about this proposal before proceeding.
TJ.
There should be a check for equality. PureComponent
might not be a good fix as it uses shallowCompare and that will always return true even if playNotes
has the same values but different reference. So we need to manually use shouldComponentUpdate
.
Hi, I found you can't press 6 keys at the same time in this piano. I found other piano examples be able to do so. Is this related to activeSounds setState ? Other implementations were pure js.
Numpad0-9, arrow keys and navigation keys should be allowed for more keyboard shortcuts with event.code.
How do I disable the shortcut labels displayed on the piano whenever keyboard shortcuts are enabled?
onPlayNoteInput/onStopNoteInput functions triggered logging to console even if I didn't press the key
Code:
import React, { useState } from 'react';
import { Piano, KeyboardShortcuts, MidiNumbers } from 'react-piano';
import SoundfontProvider from './soundfontProvider'
import 'react-piano/dist/styles.css';
import { getOctaves } from './services/octavesServices'
const audioContext = new (window.AudioContext || window.webkitAudioContext)();
const soundfontHostname = 'https://d1pzp51pvbm36p.cloudfront.net';
const noteRange = getOctaves(4)
const keyboardShortcuts = KeyboardShortcuts.create({
firstNote: noteRange.first,
lastNote: noteRange.last,
keyboardConfig: KeyboardShortcuts.HOME_ROW,
});
function PianoInteractive(props) {
const [isPlaying, setIsPlaying] = useState(0);
const [pressedMidiNumbers, setPressedMidiNumbers] = useState([''])
const recording = {
mode: isPlaying ? 'PLAYING' : 'RECORDING',
events: [{ "midiNumber": 53, "time": 0, "duration": 0.2 }],
currentTime: 0,
currentEvents: [{ "midiNumber": 50, "time": 0, "duration": 0.2 }, { "midiNumber": 53, "time": 0.2, "duration": 0.2 }, { "midiNumber": 55, "time": 0.4, "duration": 0.2 }, { "midiNumber": 57, "time": 0.6000000000000001, "duration": 0.2 }],
}
const onStopNoteInput = (midiNumber, { prevActiveNotes }) => {
console.log({ onStopNoteInput_prevActiveNotes: prevActiveNotes });
console.log({ onStopNoteInput: midiNumber });
};
const onPlayNoteInput = (midiNumber, { prevActiveNotes }) => {
console.log({ onStopNoteInput_onPlayNoteInput: prevActiveNotes });
console.log({ onPlayNoteInput: midiNumber });
}
const activeNotes =
recording.mode === 'PLAYING' ? [MidiNumbers.fromNote(props.note)] : null;
const onClickPlay = () => setIsPlaying(1)
const onClickStop = () => setIsPlaying(0)
return (
<>
<SoundfontProvider
instrumentName="acoustic_grand_piano"
audioContext={audioContext}
hostname={soundfontHostname}
render={({ isLoading, playNote, stopNote }) => (
<Piano
noteRange={noteRange}
width={700}
playNote={playNote}
stopNote={stopNote}
disabled={isLoading}
keyboardShortcuts={keyboardShortcuts}
activeNotes={activeNotes}
onPlayNoteInput={onPlayNoteInput}
onStopNoteInput={onStopNoteInput}
/>
)}
/>
<div>
<button onClick={onClickPlay}>Play</button>
<button onClick={onClickStop}>Stop</button>
</div>
</>
);
}
export default PianoInteractive;
The initial state of the Piano
component in src/Piano.js
is set like this:
state = {
activeNotes: [],
};
This makes it so the initial value is an empty array no matter what. I am proposing this as the fixx:
state = {
activeNotes: this.props.activeNotes || [],
};
I've confirmed this fixes it, so I'm creating a PR for the issue.
I want to show midiNumbers. But currently i can't show it for keys that don't have keyboardShortcut due to this check.
I only need the utilities like MidiNumbers, keyboardShortcuts etc. Do you think it makes sense to separate them so that they can be used in the generic projects who want to use a different UI?
Question: How do I record the input and save it so I can use it later for play along like a piano learning app?
In this case no listeners like press etc. should work but it can still be controlled from outside by passing playbackNotes
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.