Skip to content

[Feature] Resources: <mask> and non-rectangular (path) clips #216

Open

Description

@toomingos

Version: @tanstack/charts 1.1.0 (57774e1). Split from the comments on #128 and #191 so the ask stays open when those issues close.

Two resource types have no scene representation: a <mask> (first reported on 0.16.0, still absent in 1.1.0) and a clip that is not a rectangle.

Mask (from #128's comment)

An SVG <mask> with maskUnits="userSpaceOnUse" used as an edge fade on a live (rolling) line chart. It fades the line, its fill and the tip marker together, so a stroke gradient with opacity stops in gradients cannot replace it. We render it beside the chart svg and reference it by id, the same seam as patterns. packages/charts-core/src has no mask handling.

Path clip (from #191's comment)

Example: a highlight pulse that must be clipped to a non-rectangular silhouette (an isometric bar's front face, side face and lid). A rectangular clip lights the neighbouring faces.

Ask

Allow clip to be a rect or a path ({ path: string, fillRule?: 'nonzero' | 'evenodd' }), rendered as the <clipPath> child in SVG and a Path2D clip on canvas, with the path's bounds used for hit testing. For masks, a declared masks resource next to gradients (scoped by idPrefix), or the same generic resource slot that PR #166 adds for <pattern>.

Read from source, not run.

Related: #128 / PR #166 (<pattern> resources), #191 (gradients).

Activity

  1. tannerlinsley commented on Oct 16, 2026

    @tannerlinsley
    Member

    Thanks @toomingos, both gaps are still present on 9d806998.

    I checked two details that matter for the implementation:

    • A path's bounds can narrow the focus search, but they cannot be the final hit test. In Chromium, Firefox and WebKit, triangle and hole fixtures have fully transparent pixels that are still inside those bounds. Both fill rules and translated groups need to be carried through interaction geometry, not just SVG and Canvas painting.
    • A group mask is different from changing each child's opacity. With a half-opacity mask, two overlapping opaque shapes stay at alpha 128 in the overlap. Applying half-opacity separately gives alpha 191 or 192 there. The native Canvas isolation control matches the group mask, but that is only a feasibility check, not an implemented Charts renderer. Alpha and luminance masks also differ: the black half-opacity mask leaves alpha 128 in alpha mode and alpha 0 in luminance mode.

    The existing Native adapter also only emits rectangular clips. So this needs a shared coordinate/fill-rule contract, renderer coverage, and an explicit mask mode and interaction policy. I have not added a raw markup resource slot or changed the public API. Keeping this open, with path clips and masks tracked as separate implementation pieces.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions