react-native-piano-keyboard
Version:
A beautiful and customizable piano keyboard component for React Native
178 lines (173 loc) • 6.27 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MidiProvider = exports.useMidi = void 0;
const react_1 = __importStar(require("react"));
const react_native_1 = require("react-native");
const react_native_webview_1 = require("react-native-webview");
const Tone = __importStar(require("tone"));
const utils_1 = require("../utils");
const ToneJsWebview = `
<!DOCTYPE HTML>
<html>
<head>
<script src="http://unpkg.com/tone"></script>
<script>
const MIDI = new Tone.Sampler({
urls: {
"C1": "24.mp3",
"C2": "36.mp3",
"C3": "48.mp3",
"C4": "60.mp3",
"C5": "72.mp3",
"C6": "84.mp3",
"C7": "96.mp3",
"F1": "29.mp3",
"F2": "41.mp3",
"F3": "53.mp3",
"F4": "65.mp3",
"F5": "77.mp3",
"G5": "79.mp3",
"E4": "64.mp3",
"A4": "69.mp3",
},
attack: 0.16,
release: 1,
volume: -8,
baseUrl: "https://assets.onlinepianist.com/player/sounds/",
}).toDestination();
function triggerAttackRelease(notes, duration, time) {
const now = Tone.immediate();
MIDI.triggerAttackRelease(notes, duration, time ? time : now);
}
function triggerAttack(notes) {
const now = Tone.immediate();
MIDI.triggerAttack(notes, now);
}
function triggerRelease(notes, time) {
MIDI.triggerRelease(notes, time);
}
</script>
</head>
</html>
`;
// Provide a default context value with dummy functions (it will be replaced by the provider)
const MidiContext = (0, react_1.createContext)(undefined);
// Hook to access MidiContext in other components
const useMidi = () => {
const context = (0, react_1.useContext)(MidiContext);
if (!context) {
throw new Error("useMidi must be used within a MidiProvider");
}
return context;
};
exports.useMidi = useMidi;
const MidiProvider = ({ children }) => {
const webViewRef = (0, react_1.useRef)(null);
const [MIDI, setMIDI] = (0, react_1.useState)();
const triggerAttackRelease = (notes, duration, time) => {
if ((0, utils_1.isWeb)()) {
const now = Tone.immediate();
MIDI === null || MIDI === void 0 ? void 0 : MIDI.triggerAttackRelease(notes, duration, time ? time : now);
}
else if (webViewRef.current) {
if (time) {
webViewRef.current.injectJavaScript(`
triggerAttackRelease(${JSON.stringify(notes)}, ${JSON.stringify(duration)}, ${JSON.stringify(time)});
`);
}
else {
webViewRef.current.injectJavaScript(`
triggerAttackRelease(${JSON.stringify(notes)}, ${JSON.stringify(duration)});
`);
}
}
};
const triggerAttack = (notes) => {
if ((0, utils_1.isWeb)()) {
const now = Tone.immediate();
MIDI === null || MIDI === void 0 ? void 0 : MIDI.triggerAttack(notes, now);
}
else if (webViewRef.current) {
webViewRef.current.injectJavaScript(`
triggerAttack(${JSON.stringify(notes)});
`);
}
};
const triggerRelease = (notes, time) => {
if ((0, utils_1.isWeb)()) {
MIDI === null || MIDI === void 0 ? void 0 : MIDI.triggerRelease(notes, time);
}
else if (webViewRef.current) {
webViewRef.current.injectJavaScript(`
triggerRelease(${JSON.stringify(notes)}, ${JSON.stringify(time)});
`);
}
};
(0, react_1.useEffect)(() => {
if ((0, utils_1.isWeb)()) {
const midi = new Tone.Sampler({
urls: {
C1: "24.mp3",
C2: "36.mp3",
C3: "48.mp3",
C4: "60.mp3",
C5: "72.mp3",
C6: "84.mp3",
C7: "96.mp3",
F1: "29.mp3",
F2: "41.mp3",
F3: "53.mp3",
F4: "65.mp3",
F5: "77.mp3",
G5: "79.mp3",
E4: "64.mp3",
A4: "69.mp3",
},
attack: 0.16,
release: 1,
volume: -8,
baseUrl: "https://assets.onlinepianist.com/player/sounds/",
}).toDestination();
setMIDI(midi);
}
return () => {
MIDI === null || MIDI === void 0 ? void 0 : MIDI.dispose();
};
}, []);
return (<MidiContext.Provider value={{ triggerAttack, triggerRelease, triggerAttackRelease }}>
{children}
<react_native_1.View style={styles.webview}>
{(react_native_1.Platform.OS === "android" || react_native_1.Platform.OS === "ios") && (<react_native_webview_1.WebView source={{ html: ToneJsWebview }} originWhitelist={["*"]} javaScriptEnabled={true} ref={webViewRef}/>)}
</react_native_1.View>
</MidiContext.Provider>);
};
exports.MidiProvider = MidiProvider;
const styles = react_native_1.StyleSheet.create({
webview: {
height: 0,
width: 0,
},
});