Skip to content

v0.2.2

Latest

Choose a tag to compare

@RanveerSingh1997 RanveerSingh1997 released this 02 Jul 18:13
· 27 commits to main since this release
bcc1cb8

Bug fixes

  • Drag-to-scroll interferenceCanvasScrollEvent could fire immediately
    after releasing a drag when the hand briefly adopted a pointing-like shape
    during the transition. Fixed by adding a scrollConfirmFrames gate (default
    2, ~67 ms at 30 fps) that requires N consecutive pointing frames before
    scroll activates, consistent with the existing pinchConfirmFrames guard for
    drag. Set scrollConfirmFrames: 1 to restore the old single-frame-baseline
    behaviour.

New

  • handLandmarkConnections — exported constant listing the 21 skeleton
    bone pairs for the MediaPipe hand topology. Iterate over it to draw a
    skeleton overlay without hand-coding the connections yourself.

  • CanvasGestureEvent.confidence (double, default 1.0) — ML
    confidence of the gesture classification. Always 1.0 on web (rule-based
    heuristic); populated from the backend's score on native when using a
    model-based LandmarkProvider such as hand_detection.

  • HandDetectionFrame.gestureConfidence / secondHandGestureConfidence
    (double, default 1.0) — per-gesture confidence fields for native backends
    to expose ML scores that flow through to CanvasGestureEvent.confidence.

  • GestureInputSource confidence thresholds (web) — three new constructor
    params minHandDetectionConfidence, minHandPresenceConfidence, and
    minTrackingConfidence (each default 0.5, matching MediaPipe defaults).
    Tune these to trade sensitivity against false positives without modifying the
    JS worker.

  • HandDetectionFrame.worldLandmarks / secondWorldLandmarks
    optional world-space landmark lists (metric scale, hand-centre origin) for
    native backends to expose orientation-invariant landmark data. On web,
    populated from MediaPipe's worldLandmarks result automatically.

  • GestureDebugInfo.worldLandmarks / secondWorldLandmarks — world
    landmarks forwarded through the debug snapshot so overlays and classifiers
    can consume them.

  • HandDetectionFrame.boundingBox / secondHandBoundingBox (Rect?)
    — axis-aligned bounding box of each detected hand in normalised image
    coordinates. Native backends set this from their ML model's output. On web,
    computed automatically as the min/max envelope of the 21 image-space
    landmarks.

  • GestureDebugInfo.boundingBox / secondHandBoundingBox (Rect?)
    — bounding box forwarded through the debug snapshot for overlay rendering.

  • StylusInputSource — input source for Apple Pencil, Samsung S-Pen, and
    any PointerDeviceKind.stylus / PointerDeviceKind.invertedStylus device.
    Maps pen contact to element-drag canvas events (Down/Move/Up, tap, double-tap,
    hover, cancel). Filters out mouse/touch/trackpad events so it can be combined
    with MouseInputSource or TouchInputSource without duplicates. Exposes an
    eraserModeStream that emits true / false on eraser-vs-tip mode changes.

  • CanvasDownEvent.pressure / CanvasMoveEvent.pressure (double,
    default 1.0) — hardware pen pressure (0.0–1.0) carried by stylus down and
    move events. Backwards-compatible: non-stylus sources emit 1.0; existing
    construction and pattern-matching compiles unchanged.

  • defaultPointerSource() — factory function that returns the best-fit
    CanvasInputSource for the current platform: TouchInputSource on Android /
    iOS, MouseInputSource everywhere else (including web). Uses kIsWeb and
    defaultTargetPlatform from package:flutter/foundation.dart, so it is safe
    to call on web without conditional imports. GestureInputSource is not
    included — it requires platform-specific configuration that cannot be inferred
    automatically.

  • TouchInputSource — mobile-native input source for Android and iOS.
    Single-finger drag → CanvasScrollEvent (direct-manipulation pan); two-finger
    pinch/spread → CanvasScaleEvent; fling → CanvasScrollEvent with non-zero
    velocity field for consumer momentum animations. Tap detection uses raw
    Listener events rather than GestureDetector so taps are never dropped by
    ScaleGestureRecognizer's kPanSlop movement threshold.

  • CanvasScrollEvent.velocity (Offset, default Offset.zero) — fling
    velocity field added to CanvasScrollEvent. Non-zero only on fling events
    emitted by TouchInputSource. Backwards-compatible: existing code that
    constructs or pattern-matches CanvasScrollEvent compiles unchanged.

Documentation

  • README — Documented three previously undocumented public API surfaces:
    CanvasInputController muting (muteWhenActive/activeStream),
    GestureInputSource.statusStream lifecycle states, and
    GestureInputSource.setFilterParams().
  • README — Added self-hosting section documenting mediaPipeBaseUrl and
    modelAssetUrl constructor parameters (Flutter Web only); corrected the
    "no self-hosted model" limitation which was inaccurate — self-hosting has
    been wired since 0.1.0.
  • KNOWN_LIMITATIONS — Corrected "No rotation gesture" bullet: rotation IS
    emitted by GestureInputSource via CanvasScaleEvent.rotation; only
    MouseInputSource omits it (Flutter's ScaleGestureRecognizer limitation).
  • CONTRIBUTING — Fixed wrong directory paths (lib/src/filters/
    lib/src/filter/, removed non-existent lib/src/calibration/); added
    development prerequisites table.
  • SECURITY — Replaced GitHub default template with accurate policy for a
    0.2.x package (correct version table, advisory link, SLA, scope table).
  • CLAUDE.md — Added architecture guide for AI-assisted development,
    covering the js_interop boundary invariant, quality gates, testing philosophy,
    and breaking-change rules.

Fixes

  • pubspec.yaml version bumped from 0.2.0 to 0.2.1 (was incorrectly
    behind CHANGELOG.md); added homepage and issue_tracker fields.
  • GestureInputSource (native)dispose() now wraps _frameSub?.cancel()
    in unawaited(), consistent with the three StreamController.close() calls
    below it.

Example

  • 3D Room — Camera now starts inside the room (dist 900 → 250) for an
    immersive interior view instead of a dollhouse perspective from outside.
  • 3D Room — Furniture can now be rotated on its Y-axis: horizontal scroll
    while a piece is selected rotates it in-place; two-finger twist
    (CanvasScaleEvent.rotation) also rotates the selected piece instead of the
    camera.