UNPKG

react-native-hapticlabs

Version:

A package to play back haptics developed using Hapticlabs Studio

500 lines (465 loc) 18 kB
"use strict"; import { Platform } from 'react-native'; import NativeHapticlabs from "./NativeHapticlabs.js"; /** * This command will play an HLA file from the specified `path`, including corresponding audio files. * * *Note*: This command is only supported on Android. * @param path The path to the HLA file. This can be a path relative to the assets directory or a fully qualified path. * @returns A promise that resolves when the HLA file has been played. */ export async function playHLA(path) { if (Platform.OS === 'android') { return await NativeHapticlabs.playHLA(path); } else { console.error('HLA playback is only supported on Android'); } } /** * This command will play an OGG file from the specified `path`, including encoded haptic feedback. * If the device's haptic support level is less than 3, the device will play the audio file without haptic feedback. * To automatically select adequate haptic feedback for the device, use `playAndroidHaptics` instead. * * *Note*: This command is only supported on Android. * @param path The path to the OGG file. This can be a path relative to the assets directory or a fully qualified path. * @returns A promise that resolves when the OGG file has been played. */ export async function playOGG(path) { if (Platform.OS === 'android') { return await NativeHapticlabs.playOGG(path); } else { console.error('OGG playback is only supported on Android'); } } /** * This command will play a HAC file from the specified `path`, including corresponding audio files. * * The HAC file itself contains multiple haptic patterns for different haptic support levels. * The device will automatically select and play the optimal haptic pattern based on its haptic support level. * * *Note*: This command is only supported on Android. * @param path The path to the HAC file. This can be a path relative to the assets directory or a fully qualified path. * @returns A promise that resolves when the HAC file has been played. */ export async function playHAC(path) { if (Platform.OS === 'android') { return NativeHapticlabs.playHAC(path); } else { console.error('HAC playback is only supported on Android'); } } /** * This command will play a haptic pattern from the specified `directoryOrHACPath`. * * The type of input will be automatically detected: * * If a HAC file is specified, the function behaves like `playHAC`. * * If a directory is specified, the function will select and play the appropriate haptic pattern based on the device's haptic support level. * Depending on the device's haptic support level, different haptic feedback will be played. * For instance, if the device's haptic support level is 3, the device will play the haptic pattern * specified in the `lvl3` subdirectory. If the device's haptic support level is 0, no haptic feedback will be played. * Make sure that the directory follows the following structure: * ``` * directoryPath * ├── lvl1 * │ └── main.hla * ├── lvl2 * │ └── main.hla * └── lvl3 * └── main.ogg * ``` * *Note*: This command is only supported on Android. * @param directoryOrHACPath The path to the haptic pattern directory or HAC file. This can be a path relative to the assets directory or a fully qualified path. * @returns A promise that resolves when the haptic pattern has been played. */ export async function playAndroidHaptics(directoryOrHACPath) { if (Platform.OS === 'android') { return await NativeHapticlabs.playAndroidHaptics(directoryOrHACPath); } else { console.error('Android haptics are only supported on Android'); } } /** * This command will preload the OGG file from the specified `path`. * * This is useful for reducing latency when playing haptic patterns. Currently, * OGG filse will only be preloaded and cached if their uncompressed size is * less than 1 MB * (see [Android's SoundPool documentation](https://developer.android.com/reference/android/media/SoundPool)). * * @param path The path to the haptic pattern directory to unload. The same * you would pass to `playOGG`. */ export function preloadOGG(path) { if (Platform.OS === 'android') { NativeHapticlabs.preloadOGG(path); } else { console.error('OGG haptics are only supported on Android'); } } /** * This command will preload haptic patterns from the specified `directoryOrHACPath`. * * This is useful for reducing latency when playing haptic patterns. Currently, * only OGG files will be preloaded and cached, and only so if their * uncompressed size is less than 1 MB * (see [Android's SoundPool documentation](https://developer.android.com/reference/android/media/SoundPool)). * * @param directoryOrHACPath The path to the haptic pattern directory or HAC file. See the * `playAndroidHaptics` documentation for further details. */ export function preloadAndroidHaptics(directoryOrHACPath) { if (Platform.OS === 'android') { NativeHapticlabs.preloadAndroidHaptics(directoryOrHACPath); } else { console.error('Android haptics are only supported on Android'); } } /** * This command will unload the OGG file from the specified `path`. * * This is useful for freeing up memory when the haptic patterns are no longer * needed, and to clear the cache and enforce a reload if the file has changed. * * @param path The path to the haptic pattern directory to unload. The same * you would pass to `playOGG`. */ export function unloadOGG(path) { if (Platform.OS === 'android') { NativeHapticlabs.unloadOGG(path); } else { console.error('Android haptics are only supported on Android'); } } /** * This command will unload the haptic patterns loaded from the specified * `directoryOrHACPath`. * * This is useful for freeing up memory when the haptic patterns are no longer * needed, and to clear the cache and enforce a reload if the files have * changed. * * @param directoryOrHACPath The path to the haptic pattern directory or HAC file. See the * `playAndroidHaptics` documentation for further details */ export function unloadAndroidHaptics(directoryOrHACPath) { if (Platform.OS === 'android') { NativeHapticlabs.unloadAndroidHaptics(directoryOrHACPath); } else { console.error('Android haptics are only supported on Android'); } } /** * This command will unload all haptic patterns that have been preloaded or * played. * * Equivalent to calling `unloadAndroidHaptics()` for all directories and OGG * files that have been preloaded or played. */ export function unloadAllAndroidHaptics() { if (Platform.OS === 'android') { NativeHapticlabs.unloadAllAndroidHaptics(); } else { console.error('Android haptics are only supported on Android'); } } const constants = Platform.OS === 'android' ? NativeHapticlabs.getAndroidConstants?.() ?? NativeHapticlabs.getConstants?.() ?? {} : { hapticSupportLevel: 4, areOnOffHapticsSupported: true, areAmplitudeControlHapticsSupported: true, areAudioCoupledHapticsSupported: true, areEnvelopeHapticsSupported: true, resonanceFrequency: null, qFactor: null, minFrequency: null, maxFrequency: null, maxAcceleration: null, frequencyResponseKeys: null, frequencyResponseValues: null, envelopeControlPointMinDurationMillis: null, envelopeControlPointMaxDurationMillis: null, envelopeMaxDurationMillis: null, envelopeMaxControlPointCount: null }; /** * The device's haptic support level. * This value is a number between 0 and 4, where: * - 0: The device does not support haptics. * - 1: The device supports on / off haptic feedback. * - 2: The device supports amplitude control haptic feedback. * - 3: The device supports fully customizable audio-coupled haptic feedback. * - 4: The device supports parametric envelope-controlled haptic feedback. * * *Note*: This value is only supported on Android. */ export const androidHapticSupportLevel = constants.hapticSupportLevel ?? 0; /** * Whether the device supports on/off haptic feedback. * * On/Off haptic feedback is the most basic form of haptic feedback with timing * being the only controllable parameter. * * *Note**: This value is only supported on Android. */ export const areOnOffHapticsSupported = constants.areOnOffHapticsSupported ?? false; /** * Whether the device supports amplitude control haptic feedback. * * Amplitude control haptic feedback allows for more nuanced haptic feedback * by controlling the amplitude of the haptic signal over time. * * **Note**: This value is only supported on Android. */ export const areAmplitudeControlHapticsSupported = constants.areAmplitudeControlHapticsSupported ?? false; /** * Whether the device supports audio coupled haptic feedback. * * Audio coupled haptic feedback allows for full control over the haptic * feedback, while at the same time offering playback synchronized with audio. * * **Note**: This value is only supported on Android. */ export const areAudioCoupledHapticsSupported = constants.areAudioCoupledHapticsSupported ?? false; /** * Whether the device supports envelope-controlled haptic feedback. * * Similar to amplitude control haptic feedback, envelope-controlled haptic * feedback allows for controlling both the amplitude and the frequency of the * haptic signal over time. * * **Note**: This value is only supported on Android. */ export const areEnvelopeHapticsSupported = constants.areEnvelopeHapticsSupported ?? false; /** * The device's haptic actuator's resonance frequency. * * This is the frequency at which the haptic actuator is driven for e.g. HLA * level 2 files. At this frequency, the actuator will resonate and produce * the strongest and most energy-efficient haptic feedback. * * **Note**: This value is only supported on Android. */ export const resonanceFrequency = constants.resonanceFrequency ?? null; /** * The device's haptic actuator's q factor. * * See https://en.wikipedia.org/wiki/Q_factor for more information. * * **Note**: This value is only supported on Android. */ export const qFactor = constants.qFactor ?? null; /** * The device's haptic actuator's self-reported minimum frequency. * * **Note**: This value is only supported on Android. * * **Note**: With audio-coupled haptics (OGG files), there are no frequency * limits. */ export const minFrequency = constants.minFrequency ?? null; /** * The device's haptic actuator's self-reported maximum frequency. * * **Note**: This value is only supported on Android. * * **Note**: With audio-coupled haptics (OGG files), there are no frequency * limits. */ export const maxFrequency = constants.maxFrequency ?? null; /** * The device's haptic actuator's self-reported maximum acceleration (in Gs). * * **Note**: This value is only supported on Android. */ export const maxAcceleration = constants.maxAcceleration ?? null; // Deserialize the frequency response data from the native module const frequencyResponseKeys = constants.frequencyResponseKeys; const frequencyResponseValues = constants.frequencyResponseValues; /** * The device's haptic actuator's self-reported frequency response. * * This is a map from frequency (in Hz) to acceleration (in Gs) at that * frequency. * * **Note**: This value is only supported on Android. */ let frequencyResponse = null; if (frequencyResponseKeys != null && frequencyResponseValues != null) { if (frequencyResponseKeys.length === frequencyResponseValues.length) { // Valid frequency response data frequencyResponse = new Map(); for (let i = 0; i < frequencyResponseKeys.length; i++) { const frequency = frequencyResponseKeys[i]; const acceleration = frequencyResponseValues[i]; if (frequency != null && acceleration != null && !isNaN(frequency) && !isNaN(acceleration)) { frequencyResponse.set(frequency, acceleration); } } } } export { frequencyResponse }; /** * The minimum duration (in milliseconds) for an envelope control point. * * **Note**: This value is only supported on Android. */ export const envelopeControlPointMinDurationMillis = constants.envelopeControlPointMinDurationMillis ?? null; /** * The maximum duration (in milliseconds) for an envelope control point. * * **Note**: This value is only supported on Android. */ export const envelopeControlPointMaxDurationMillis = constants.envelopeControlPointMaxDurationMillis ?? null; /** * The maximum duration (in milliseconds) for an envelope effect. * * **Note**: This value is only supported on Android. */ export const envelopeMaxDurationMillis = constants.envelopeMaxDurationMillis ?? null; /** * The maximum number of control points for an envelope effect. * * **Note**: This value is only supported on Android. */ export const envelopeMaxControlPointCount = constants.envelopeMaxControlPointCount ?? null; /** * This command will play an AHAP file from the specified `path`, including corresponding AHAP files and audio files. * * *Note*: This command is only supported on iOS. * @param path The path to the AHAP file. * @returns A promise that resolves when the AHAP file has been played. */ export async function playAHAP(path) { if (Platform.OS === 'ios') { return await NativeHapticlabs.playAHAP(path); } else { console.error('AHAP is only supported on iOS'); } } /** * This command will play the haptic pattern specified by the `iosPath` on iOS and the `androidPath` on Android. * @param iosPath The path to the AHAP file. * @param androidPath The path to the Android haptic pattern directory. This can be a path relative to the assets directory or a fully qualified path. * @returns A promise that resolves when the haptic pattern has finished playing. */ export async function playHaptics({ iosPath, androidPath }) { if (Platform.OS === 'ios') { return NativeHapticlabs.playAHAP(iosPath); } else if (Platform.OS === 'android') { return NativeHapticlabs.playAndroidHaptics(androidPath); } else { console.error('Haptics are only supported on iOS and Android'); } } /** * Predefined haptic signals available on Android. */ export let AndroidPredefinedHaptics = /*#__PURE__*/function (AndroidPredefinedHaptics) { AndroidPredefinedHaptics["CLICK"] = "Click"; AndroidPredefinedHaptics["DOUBLE_CLICK"] = "Double Click"; AndroidPredefinedHaptics["HEAVY_CLICK"] = "Heavy Click"; AndroidPredefinedHaptics["TICK"] = "Tick"; return AndroidPredefinedHaptics; }({}); /** * Predefined haptic signals available on iOS. */ export let IOSPredefinedHaptics = /*#__PURE__*/function (IOSPredefinedHaptics) { IOSPredefinedHaptics["LIGHT"] = "light"; IOSPredefinedHaptics["MEDIUM"] = "medium"; IOSPredefinedHaptics["HEAVY"] = "heavy"; IOSPredefinedHaptics["RIGID"] = "rigid"; IOSPredefinedHaptics["SOFT"] = "soft"; IOSPredefinedHaptics["SUCCESS"] = "success"; IOSPredefinedHaptics["WARNING"] = "warning"; IOSPredefinedHaptics["ERROR"] = "error"; IOSPredefinedHaptics["SELECTION"] = "selection"; return IOSPredefinedHaptics; }({}); /** * This command will play a predefined (built-in) haptic signal. * * For each platform, up to one predefined haptic signal can be specified. * If none is specified for the current platform, no haptic feedback will be played. * * @param android The predefined haptic signal to play on Android. * @param ios The predefined haptic signal to play on iOS. */ export function playPredefinedHaptics(signal) { if (Platform.OS === 'android' && signal.android !== undefined) { NativeHapticlabs.playPredefinedHaptics(signal.android); } else if (Platform.OS === 'ios' && signal.ios !== undefined) { NativeHapticlabs.playPredefinedHaptics(signal.ios); } } /** * This command will mute or unmute haptic feedback from Hapticlabs. * * **Note**: This command is only supported on iOS. * * **Note**: This command will not affect predefined haptic signals played via `playPredefinedHaptics`. * * @param mute Whether to mute (true) or unmute (false) haptic feedback. */ export function setHapticsMute(mute) { if (Platform.OS === 'ios') { NativeHapticlabs.setHapticsMute(mute); } else { console.error('Haptics mute state is only supported on iOS'); } } /** * This command will return whether haptic feedback from Hapticlabs is muted. * * **Note**: This command is only supported on iOS. * * **Note**: This command will not reflect the mute state of predefined haptic signals played via `playPredefinedHaptics`. * * @returns A promise that resolves to whether haptic feedback is muted. */ export async function isHapticsMuted() { if (Platform.OS === 'ios') { return await NativeHapticlabs.isHapticsMuted(); } else { console.error('Haptics mute state is only supported on iOS'); return false; } } /** * This command will mute or unmute audio playback from Hapticlabs. * * **Note**: This command is only supported on iOS. * * **Note**: This command exclusively affects audio playback associated with haptic patterns played via `playAHAP` or `playHaptics`. * * @param mute Whether to mute (true) or unmute (false) audio playback. */ export function setAudioMute(mute) { if (Platform.OS === 'ios') { NativeHapticlabs.setAudioMute(mute); } else { console.error('Audio mute state is only supported on iOS'); } } /** * This command will return whether audio playback from Hapticlabs is muted. * * **Note**: This command is only supported on iOS. * * **Note**: This command exclusively reflects the mute state of audio playback associated with haptic patterns played via `playAHAP` or `playHaptics`. * * @returns A promise that resolves to whether audio playback is muted. */ export async function isAudioMuted() { if (Platform.OS === 'ios') { return await NativeHapticlabs.isAudioMuted(); } else { console.error('Audio mute state is only supported on iOS'); return false; } } //# sourceMappingURL=index.js.map