bzzz 0.1.0 copy "bzzz: ^0.1.0" to clipboard
bzzz: ^0.1.0 copied to clipboard

A Flutter plugin for rich, cross-platform haptic feedback using CoreHaptics (iOS) and VibrationEffect (Android).

bzzz! #

pub package

Professional-grade haptic feedback for Flutter. Full control over vibration patterns on iOS (CoreHaptics) and Android (VibrationEffect), or just use the built-in presets and move on.

Quick Start #

dependencies:
  bzzz: ^0.1.0
import 'package:bzzz/bzzz.dart';

// Play a preset
await Bzzz.instance.play(HapticCollection.success);

// Stop playback (useful for long patterns)
await Bzzz.instance.cancel();

play plays the haptic and swallows errors silently — your app won't crash on devices without a vibration motor. If you want to handle errors explicitly, use playOrThrow.

HapticCollection has 22 built-in presets for common cases: clicks, success/error feedback, heartbeat, rumble, sparkle, and more. See full list below.

Platform Support #

Platform Min version Engine
iOS 13+ CoreHaptics
Android API 26+ VibrationEffect

The plugin declares android.permission.VIBRATE in its manifest automatically.

Android: How Vibration Works Under the Hood #

Android has fragmented haptics support. The library handles this by providing a tiered fallback system. You supply up to three configs in a single AndroidHapticConfig, and the library picks the best one the device can run:

Priority API What it does
1 EnvelopeConfig (API 36+) VibrationEffect.BasicEnvelopeBuilder — full control over intensity + sharpness curves over time. Closest to CoreHaptics on iOS.
2 CompositionConfig (API 30+) VibrationEffect.startComposition() — chains hardware primitives (click, thud, spin, quickRise, slowRise, quickFall, tick, lowTick) with scale and delay between them.
3 WaveformConfig (API 26+) VibrationEffect.createWaveform() — timed on/off pattern with optional amplitude control (0–255). If the device has no amplitude control, it falls back to binary on/off.

All values you pass are normalized ([0.0, 1.0] for intensities, seconds for durations). The native layer converts them to platform units (milliseconds, 0–255 amplitudes, etc.).

If none of the provided configs match the device capabilities, playback silently does nothing.

Using Presets #

HapticCollection has 22 ready-to-use patterns:

// Basic UI feedback
HapticCollection.click
HapticCollection.lightClick
HapticCollection.heavyClick
HapticCollection.selection
HapticCollection.success
HapticCollection.error
HapticCollection.snap

// Expressive
HapticCollection.heartbeat
HapticCollection.charge
HapticCollection.sparkle
HapticCollection.drumRoll
HapticCollection.rumble
HapticCollection.boing
HapticCollection.wave
HapticCollection.coinDrop
HapticCollection.waterDrip
// ...and more

Some presets accept parameters:

await Bzzz.instance.play(ClickHaptic(intensity: 0.4));

Custom Haptics #

If presets aren't enough, you have two options depending on how much control you need.

UnifiedHaptic — one config for both platforms #

Define a haptic with normalized parameters, and the library translates it for each platform:

await Bzzz.instance.play(
  UnifiedHaptic(
    intensity: 0.7,
    sharpness: 0.5,
    duration: 0.3,
    attack: 0.1,
    decay: 0.2,
  ),
);

All values are normalized to [0.0, 1.0], durations are in seconds.

CustomHaptic — full per-platform control #

When you need to squeeze out every bit of the hardware, configure each platform separately:

await Bzzz.instance.play(
  CustomHaptic(
    cupertinoConfig: CupertinoHapticConfig(
      events: [
        HapticTransient(time: 0.0, intensity: 1.0, sharpness: 0.8),
        HapticContinuous(
          time: 0.1,
          duration: 0.5,
          intensity: 0.6,
          sharpness: 0.4,
        ),
      ],
      parameterCurves: [
        ParameterCurve(
          parameterId: CurveParameterId.hapticIntensityControl,
          controlPoints: [
            ParameterCurveControlPoint(time: 0.0, value: 1.0),
            ParameterCurveControlPoint(time: 0.5, value: 0.0),
          ],
        ),
      ],
    ),
    androidConfig: AndroidHapticConfig(
      compositionConfig: CompositionConfig(
        primitives: [
          CompositionPrimitive(
            primitive: AndroidPrimitive.click,
            scale: 1.0,
            delay: 0,
          ),
        ],
      ),
    ),
  ),
);

On iOS you describe haptics as a timeline of transient/continuous events with optional parameter curves (ADSR envelopes, intensity/sharpness animations over time).

On Android the library picks the best available API automatically based on what the device supports (see Android section above). You can provide all three tiers in one config and the library will use the best match.

Checking Device Capabilities #

final info = await Bzzz.instance.getDeviceHapticsInfo();

switch (info) {
  case AndroidDeviceHapticsInfo():
    print('Vibrator: ${info.hasVibrator}');
    print('Amplitude control: ${info.hasAmplitudeControl}');
    print('Primitives: ${info.supportedPrimitives}');
  case CupertinoDeviceHapticsInfo():
    print('CoreHaptics: ${info.supportsCoreHaptics}');
}

More Examples #

The example app has a lot of patterns — from practical UI feedback (toggle switches, pull-to-refresh, message sent) to fun stuff (typewriter, raindrops, explosions) and even recognizable tunes (Imperial March, Beethoven's 5th). Good starting point if you want to design your own.

License #

MIT

4
likes
150
points
41
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

A Flutter plugin for rich, cross-platform haptic feedback using CoreHaptics (iOS) and VibrationEffect (Android).

Homepage
Repository (GitHub)
View/report issues

Topics

#haptics #vibration #haptic-feedback

License

MIT (license)

Dependencies

bzzz_android, bzzz_ios, bzzz_platform_interface, flutter

More

Packages that depend on bzzz

Packages that implement bzzz