UNPKG

react-native-piano-keyboard

Version:

A beautiful and customizable piano keyboard component for React Native

178 lines (173 loc) 6.27 kB
"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, }, });