Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Border radius on TextLayer background #9004

Open
mariush2 opened this issue Jul 4, 2024 · 2 comments · May be fixed by #9447
Open

Border radius on TextLayer background #9004

mariush2 opened this issue Jul 4, 2024 · 2 comments · May be fixed by #9447
Labels

Comments

@mariush2
Copy link

mariush2 commented Jul 4, 2024

Target Use Case

Hi,
I'm trying to get the background on tooltips of an EditableGeoJson layer to have rounded corners but can't seem to find a way without having to create a sub classed layer.

Would it be possible to add a new prop to the TextLayer that enabled users to set border-radius in a similar way to css?

The look I am after is this:
image

Proposal

getBorderRadius:

getBorderRadius: 5 // A number is just the same for all corners,
getBorderRadius: [5,2,5,2] // An array of numbers would work in the same way as other CSS shorthands.
@CANEVETGASPARD
Copy link

CANEVETGASPARD commented Feb 17, 2025

Hello, If you want to add it quickly to your project you can create an extension like that:

import { LayerExtension } from "@deck.gl/core";

const fs = `\
#version 300 es
#define SHADER_NAME text-background-layer-fragment-shader

precision highp float;

uniform bool stroked;

in vec4 vFillColor;
in vec4 vLineColor;
in float vLineWidth;
in vec2 uv;
in vec2 dimensions;

out vec4 fragColor;

float round_rect(vec2 p, vec2 size, vec4 radii) {
    // from https://www.shadertoy.com/view/4llXD7
    radii.xy = (p.x>0.0)?radii.xy : radii.zw;
    radii.x  = (p.y>0.0)?radii.x  : radii.y;
    vec2 q = abs(p)-size+radii.x;
    return min(max(q.x,q.y),0.0) + length(max(q,0.0)) - radii.x;
}

void main(void) {
  geometry.uv = uv;

  // Convert UV to center-based coordinates [-0.5, 0.5]
  vec2 pixelPosition = (uv - 0.5) * dimensions;

  float maxBorderRadius = min(dimensions.x, dimensions.y) * 0.5;
  vec4 borderRadius = vec4(min(YOUR_BORDER_VALUE, maxBorderRadius)); // TO_UPDATE
  float dist = round_rect(pixelPosition, dimensions * 0.5, borderRadius);

  // Border Calculation
  if (stroked) {
    float distToEdge = -dist;
    float isBorder = smoothstep(vLineWidth - 1.0, vLineWidth + 1.0, distToEdge);
    fragColor = mix(vLineColor, vFillColor, isBorder);
  } else {
    fragColor = vFillColor;
  }

  // Smooth transition for the main shape
  float shapeAlpha = smoothstep(1.0, -1.0, dist);
  fragColor.a *= shapeAlpha;

  DECKGL_FILTER_COLOR(fragColor, geometry);
}
`;

export default class BorderRadiusExtension extends LayerExtension {
  static extensionName = "BorderRadiusExtension";

  getShaders() {
    return {
      fs,
    };
  }
}

and add this parameter to your TextLayer

extensions: [new BorderRadiusExtension()]

@CANEVETGASPARD
Copy link

CANEVETGASPARD commented Feb 17, 2025

Actually it also depends on the version of deckgl you are using. Which version are you using @mariush2 ?
In the meantime, I will also try to do a PR for this feature.

@CANEVETGASPARD CANEVETGASPARD linked a pull request Feb 18, 2025 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants