visgl / visgl/deck.gl

[Feat] IconLayer - Add support for sizing and scaling icons by height or width

Open
#9,694 0 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

feature
Dominant language
TypeScript
Stars
14.6k
Forks
2.3k
Avg merge
2d 9h
Merged PRs (30d)
42

Description

Target Use Case

Currently we can configure the size of an icon based on its height. Height is also the basis of the behaviour of the sizeMinPixels, sizeMaxPixels properties which can constrain the minimum and maximum screen height of all icons in the IconLayer where necessary.

We have use cases where we require fixed-width, variable-height icons which this doesn't currently support. We are currently working around with our own copy of IconLayer to which we've added a sizeBasis property to select which dimension to consider as the basis for the size/scaling of the icons.

For more background, here's an example where we display road signs in one layer with optional "supplementary plates" in a second. The signs are offset using anchorY so the plates can be rendered below where applicable:

Image

We use sizeMaxPixels/sizeMinPixels to ensure these signs stay sensible sizes when zoomed in/out, and using a fixed width can ensure both layers scale together proportionally:

Image

Without the capability to set which dimension of is used to set the size/scaling for the icon we end up with the layers scaling at different zoom levels:

Image

We've explored many ways of making this work, a change to IconLayer seems to be the cleanest solution, see proposal.

Does this sound too niche a requirement, or would you be open to a PR?

P.S. Thanks for all of the amazing work which has gone into this project - it is truly remarkable.

Proposal

Adding a "sizeBasis" or "sizeDimension" prop which can be set to "width" but defaults to "height" which is the current behaviour:

const signLayer = new IconLayer<Sign>({
  id: 'sign-layer',
  data: signData,
  sizeUnits: 'meters',
  getSize: 1,
  sizeMinPixels: 20,
  sizeMaxPixels: 100,
  sizeBasis: "width", // new property
  // ... other props
}

A small adjustment to the shader as follows:

// Choose correct constraint based on the 'sizeBasis' value (0.0 = width, 1.0 = height)
float iconConstraint = icon.sizeBasis == 0.0 ? iconSize.x : iconSize.y;
float instanceScale = iconConstraint == 0.0 ? 0.0 : sizePixels / iconConstraint;

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by locating the IconLayer implementation and the shader code that derives icon size from height and applies sizeMinPixels and sizeMaxPixels. Add a sizeBasis or sizeDimension option with width support while preserving height as the default, then verify that fixed-width icons and the existing height-based behavior scale correctly.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
data-visualization
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.