capacitor-haptics-advanced
v0.1.0
Published
Advanced haptics for Capacitor using CHHapticEngine (iOS) and VibrationEffect.Composition (Android)
Maintainers
Readme
capacitor-haptics-advanced
Advanced haptics for Capacitor using CHHapticEngine on iOS and VibrationEffect.Composition on Android.
Goes far beyond @capacitor/haptics — exposes the full platform haptic APIs including custom waveforms, parameter curves, envelope effects, looping players, and AHAP pattern playback.
Install
npm install capacitor-haptics-advanced
npx cap syncAndroid permissions
Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.VIBRATE" />Platform support
| Feature | iOS | Android | Web | |---------|-----|---------|-----| | Transient / continuous | ✅ CHHapticEngine | ✅ VibrationEffect | ✅ navigator.vibrate | | Predefined effects (CLICK, TICK …) | ✅ UIFeedbackGenerator | ✅ createPredefined (API 29+) | ✅ | | AHAP pattern playback | ✅ | — (no-op) | — | | Parameter curves (real-time) | ✅ CHHapticParameterCurve | — (no-op) | — | | Primitive composition | ✅ approximation | ✅ API 30+ | ✅ | | Custom waveform | ✅ | ✅ API 26+ | ✅ | | Envelope effects | ✅ parameter curves | ✅ API 34+ BasicEnvelopeBuilder | ✅ | | Waveform envelope (freq+amp) | ✅ sharpness approximation | ✅ API 34+ WaveformEnvelopeBuilder | ✅ | | Looping player | ✅ CHHapticAdvancedPatternPlayer | ✅ repeating waveform | ✅ |
Usage
import { HapticsAdvanced } from 'capacitor-haptics-advanced'
// Check capabilities first
const caps = await HapticsAdvanced.getCapabilities()
console.log(caps.platform, caps.supportsAdvancedHaptics)
// Simple tap
await HapticsAdvanced.playTransient({ intensity: 0.8, sharpness: 0.5 })
// Sustained buzz for 0.5 s
await HapticsAdvanced.playContinuous({ intensity: 1.0, duration: 0.5 })
// Device-tuned effect (best quality on both platforms)
await HapticsAdvanced.playPredefined({ effect: 'CLICK' })
// Sequence of primitives (Android API 30+ / iOS approximation)
await HapticsAdvanced.composePrimitives({
primitives: [
{ type: 'CLICK', amplitude: 1.0 },
{ type: 'TICK', amplitude: 0.5, delay: 100 },
{ type: 'QUICK_FALL', amplitude: 0.8, delay: 50 },
],
})
// Custom timing waveform
await HapticsAdvanced.playWaveform({
timings: [50, 30, 50, 30, 100],
amplitudes: [0.4, 0, 0.8, 0, 1.0],
})
// Looping player with real-time intensity control (iOS)
const { playerId } = await HapticsAdvanced.startContinuousLoop({ intensity: 0.6, sharpness: 0.5 })
await HapticsAdvanced.updateContinuousLoop({ playerId, intensity: 1.0, sharpness: 0.8 })
await HapticsAdvanced.stopContinuousLoop({ playerId })
// AHAP pattern (iOS only)
const pattern = JSON.stringify({
Version: 1,
Pattern: [
{ Event: { Time: 0, Type: 'HapticTransient', EventParameters: [
{ ParameterID: 'HapticIntensity', ParameterValue: 1.0 },
{ ParameterID: 'HapticSharpness', ParameterValue: 0.8 },
]}},
],
})
await HapticsAdvanced.playAHAPPattern({ pattern })
// Envelope (Android API 34+ / iOS via parameter curves)
await HapticsAdvanced.playEnvelope({
controlPoints: [
{ intensity: 0.0, sharpness: 0.5, durationMs: 20 },
{ intensity: 1.0, sharpness: 0.7, durationMs: 100 },
{ intensity: 0.5, sharpness: 0.5, durationMs: 200 },
{ intensity: 0.0, sharpness: 0.3, durationMs: 100 },
],
})
// Stop everything
await HapticsAdvanced.cancel()API
getCapabilities() → HapticCapabilities
Returns platform haptic capabilities. Always call this before using advanced features.
interface HapticCapabilities {
supportsAdvancedHaptics: boolean // CHHapticEngine / hasAmplitudeControl
supportsPrimitiveComposition: boolean // Android API 30+
supportsAHAP: boolean // iOS only
supportsAmplitudeControl: boolean
supportsFrequencyControl: boolean // Android API 34+
supportsEnvelopeEffects: boolean // iOS always / Android API 34+
resonantFrequency: number // Android API 34+: Hz (0 = unknown)
platform: 'ios' | 'android' | 'web'
platformVersion: number
}playTransient(options)
Single sharp haptic burst.
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| intensity | number | 1.0 | 0.0–1.0 |
| sharpness | number | 0.5 | 0.0 (soft) – 1.0 (crisp). iOS only. |
| attackTime | number | 0 | Ramp-up duration in seconds. iOS only. |
| decayTime | number | 0 | Ramp-down duration. iOS only. |
| releaseTime | number | 0 | Tail-off after event. iOS only. |
playContinuous(options)
Sustained vibration.
Same options as playTransient plus:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| duration | number | — | Duration in seconds (iOS) or milliseconds (Android). |
playPredefined(options)
Device-optimised named effect. Best quality on both platforms.
effect: 'CLICK' | 'DOUBLE_CLICK' | 'HEAVY_CLICK' | 'TICK'
playAHAPPattern(options) (iOS only)
Play a raw AHAP pattern from a JSON string.
playWithParameterCurve(options) (iOS only)
Play a haptic sequence with real-time parameter automation via CHHapticParameterCurve.
composePrimitives(options)
Sequence of haptic primitives with optional delays.
Primitive types: CLICK | THUD | SPIN | QUICK_RISE | SLOW_RISE | QUICK_FALL | TICK | LOW_TICK
playWaveform(options)
Raw timing + amplitude waveform.
| Option | Type | Description |
|--------|------|-------------|
| timings | number[] | Step durations in ms |
| amplitudes | number[] | Amplitude per step (0.0–1.0) |
| repeat | boolean | Loop the waveform |
playEnvelope(options)
Smooth amplitude + sharpness envelope. Android API 34+ uses BasicEnvelopeBuilder; iOS uses parameter curves.
playWaveformEnvelope(options)
Amplitude + frequency sweep. Android API 34+ uses WaveformEnvelopeBuilder; iOS approximates via sharpness curves.
Looping
startContinuousLoop({ intensity, sharpness }) → { playerId }
updateContinuousLoop({ playerId, intensity, sharpness })
stopContinuousLoop({ playerId })cancel()
Cancel all ongoing haptics and stop looping players.
