New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

regl-worldview

Package Overview
Dependencies
Maintainers
10
Versions
81
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

regl-worldview - npm Package Compare versions

Comparing version 0.5.0 to 0.6.0

src/stories/.DS_Store

2

package.json
{
"name": "regl-worldview",
"version": "0.5.0",
"version": "0.6.0",
"description": "A reusable component for rendering 2D and 3D views using regl",

@@ -5,0 +5,0 @@ "license": "Apache-2.0",

@@ -81,2 +81,10 @@ // @flow

},
isPerspective(context, props) {
return this.cameraState.perspective;
},
fovy(context, props) {
return this.cameraState.fovy;
},
},

@@ -83,0 +91,0 @@

@@ -5,7 +5,7 @@ // @flow

import memoizeOne from "memoize-one";
import React, { useState, useContext } from "react";
import React, { useState } from "react";
import type { Color } from "../types";
import { defaultBlend, defaultDepth } from "../utils/commandUtils";
import WorldviewReactContext from "../WorldviewReactContext";
import { defaultBlend, defaultDepth, toColor } from "../utils/commandUtils";
import { createInstancedGetChildrenForHitmap } from "../utils/getChildrenForHitmapDefaults";
import Command, { type CommonCommandProps } from "./Command";

@@ -29,3 +29,2 @@ import { isColorDark, type TextMarker } from "./Text";

// ============================
// - Add hitmap support.
// - Allow customization of font style, maybe highlight ranges.

@@ -138,2 +137,6 @@ // - Consider a solid rectangular background instead of an outline. This is challenging because the

uniform float scaleInvariantSize;
uniform float viewportHeight;
uniform float viewportWidth;
uniform bool isPerspective;
uniform float cameraFovY;

@@ -187,14 +190,40 @@ // per-vertex attributes

void main () {
// Scale invariance only works for billboards
bool scaleInvariantEnabled = scaleInvariant && billboard == 1.0;
vec2 srcSize = vec2(srcWidth, fontSize);
vec3 markerSpacePos = scale * vec3((destOffset + position * srcSize + alignmentOffset) / fontSize, 0);
gl_Position = computeVertexPosition(markerSpacePos);
vec3 markerSpacePos = vec3((destOffset + position * srcSize + alignmentOffset) / fontSize, 0);
if (scaleInvariant && billboard == 1.0) {
// Scale invariance only works for billboards
float w = gl_Position.w;
w *= scaleInvariantSize;
markerSpacePos *= w;
gl_Position = computeVertexPosition(markerSpacePos);
if (!scaleInvariantEnabled) {
// Apply marker scale only when scale invariance is disabled
markerSpacePos *= scale;
} else {
// If scale invariance is enabled, the text will be rendered at a constant
// scale regardless of the zoom level.
// The given scaleInvariantSize is in pixels. We need to scale it based on
// the current canvas resolution to get the proper dimensions later in NDC
float scaleInvariantFactor = scaleInvariantSize / viewportHeight;
if (isPerspective) {
// When using a perspective projection, the effect is achieved by using
// the w-component for scaling, which is obtained by first projecting
// the marker position into clip space.
gl_Position = computeVertexPosition(markerSpacePos);
scaleInvariantFactor *= gl_Position.w;
// We also need to take into account the camera's half vertical FOV
scaleInvariantFactor *= cameraFovY;
} else {
// Compute inverse aspect ratio
float invAspect = viewportHeight / viewportWidth;
// When using orthographic projection, the scaling factor is obtain from
// the camera projection itself.
// We also need applied the inverse aspect ratio
scaleInvariantFactor *= 2.0 * invAspect / length(projection[0].xyz);
}
// Apply scale invariant factor
markerSpacePos *= scaleInvariantFactor;
}
// Compute final vertex position
gl_Position = computeVertexPosition(markerSpacePos);
vTexCoord = (srcOffset + texCoord * srcSize) / atlasSize;

@@ -218,2 +247,3 @@ vEnableBackground = enableBackground;

uniform float scaleInvariantSize;
uniform bool isHitmap;

@@ -236,12 +266,17 @@ varying vec2 vTexCoord;

if (scaleInvariant && vBillboard == 1.0 && scaleInvariantSize < 0.03) {
// If scale invariant is enabled and scaleInvariantSize is "too small", do not interpolate
// the raw distance value since at such small scale, the SDF approach causes some
if (scaleInvariant && vBillboard == 1.0 && scaleInvariantSize <= 20.0) {
// If scale invariant is enabled and scaleInvariantSize is "too small", do not interpolate
// the raw distance value since at such small scale, the SDF approach causes some
// visual artifacts.
// The value used for checking if scaleInvariantSize is "too small" is arbitrary and
// was defined after some experimentation.
// The value used for checking if scaleInvariantSize is "too small" is arbitrary and
// was defined after some experimentation.
edgeStep = dist;
}
if (vEnableHighlight > 0.5) {
if (isHitmap) {
// When rendering for the hitmap buffer, we draw flat polygons using the foreground color
// instead of the actual glyphs. This way we increase the selection range and provide a
// better user experience.
gl_FragColor = vForegroundColor;
} else if (vEnableHighlight > 0.5) {
gl_FragColor = mix(vHighlightColor, vec4(0, 0, 0, 1), edgeStep);

@@ -269,38 +304,45 @@ } else if (vEnableBackground > 0.5) {

const atlasTexture = regl.texture();
const drawText = regl({
depth: defaultDepth,
blend: defaultBlend,
primitive: "triangle strip",
vert,
frag,
uniforms: {
atlas: atlasTexture,
atlasSize: () => [atlasTexture.width, atlasTexture.height],
fontSize: command.resolution,
cutoff: CUTOFF,
scaleInvariant: command.scaleInvariant,
scaleInvariantSize: command.scaleInvariantSize,
},
instances: regl.prop("instances"),
count: 4,
attributes: {
position: [[0, 0], [0, -1], [1, 0], [1, -1]],
texCoord: [[0, 0], [0, 1], [1, 0], [1, 1]], // flipped
srcOffset: (ctx, props) => ({ buffer: props.srcOffsets, divisor: 1 }),
destOffset: (ctx, props) => ({ buffer: props.destOffsets, divisor: 1 }),
srcWidth: (ctx, props) => ({ buffer: props.srcWidths, divisor: 1 }),
scale: (ctx, props) => ({ buffer: props.scale, divisor: 1 }),
alignmentOffset: (ctx, props) => ({ buffer: props.alignmentOffset, divisor: 1 }),
billboard: (ctx, props) => ({ buffer: props.billboard, divisor: 1 }),
foregroundColor: (ctx, props) => ({ buffer: props.foregroundColor, divisor: 1 }),
backgroundColor: (ctx, props) => ({ buffer: props.backgroundColor, divisor: 1 }),
highlightColor: (ctx, props) => ({ buffer: props.highlightColor, divisor: 1 }),
enableBackground: (ctx, props) => ({ buffer: props.enableBackground, divisor: 1 }),
enableHighlight: (ctx, props) => ({ buffer: props.enableHighlight, divisor: 1 }),
posePosition: (ctx, props) => ({ buffer: props.posePosition, divisor: 1 }),
poseOrientation: (ctx, props) => ({ buffer: props.poseOrientation, divisor: 1 }),
},
});
const makeDrawText = (isHitmap: boolean) => {
return regl({
depth: defaultDepth,
blend: defaultBlend,
primitive: "triangle strip",
vert,
frag,
uniforms: {
atlas: atlasTexture,
atlasSize: () => [atlasTexture.width, atlasTexture.height],
fontSize: command.resolution,
cutoff: CUTOFF,
scaleInvariant: command.scaleInvariant,
scaleInvariantSize: command.scaleInvariantSize,
isHitmap: !!isHitmap,
viewportHeight: regl.context("viewportHeight"),
viewportWidth: regl.context("viewportWidth"),
isPerspective: regl.context("isPerspective"),
cameraFovY: regl.context("fovy"),
},
instances: regl.prop("instances"),
count: 4,
attributes: {
position: [[0, 0], [0, -1], [1, 0], [1, -1]],
texCoord: [[0, 0], [0, 1], [1, 0], [1, 1]], // flipped
srcOffset: (ctx, props) => ({ buffer: props.srcOffsets, divisor: 1 }),
destOffset: (ctx, props) => ({ buffer: props.destOffsets, divisor: 1 }),
srcWidth: (ctx, props) => ({ buffer: props.srcWidths, divisor: 1 }),
scale: (ctx, props) => ({ buffer: props.scale, divisor: 1 }),
alignmentOffset: (ctx, props) => ({ buffer: props.alignmentOffset, divisor: 1 }),
billboard: (ctx, props) => ({ buffer: props.billboard, divisor: 1 }),
foregroundColor: (ctx, props) => ({ buffer: props.foregroundColor, divisor: 1 }),
backgroundColor: (ctx, props) => ({ buffer: props.backgroundColor, divisor: 1 }),
highlightColor: (ctx, props) => ({ buffer: props.highlightColor, divisor: 1 }),
enableBackground: (ctx, props) => ({ buffer: props.enableBackground, divisor: 1 }),
enableHighlight: (ctx, props) => ({ buffer: props.enableHighlight, divisor: 1 }),
posePosition: (ctx, props) => ({ buffer: props.posePosition, divisor: 1 }),
poseOrientation: (ctx, props) => ({ buffer: props.poseOrientation, divisor: 1 }),
},
});
};
return (props: $ReadOnlyArray<TextMarkerProps>) => {
return (props: $ReadOnlyArray<TextMarkerProps>, isHitmap: boolean) => {
let estimatedInstances = 0;

@@ -364,6 +406,12 @@ const prevNumChars = charSet.size;

const fgColor = marker.colors?.[0] || marker.color || BG_COLOR_LIGHT;
// If we need to render text for hitmap framebuffer, we only render the polygons using
// the foreground color (which needs to be converted to RGBA since it's a vec4).
// See comment on fragment shader above
const fgColor = toColor(
isHitmap ? marker.color || [0, 0, 0, 1] : marker.colors?.[0] || marker.color || BG_COLOR_LIGHT
);
const outline = marker.colors?.[1] != null || command.autoBackgroundColor;
const bgColor =
marker.colors?.[1] || (command.autoBackgroundColor && isColorDark(fgColor) ? BG_COLOR_LIGHT : BG_COLOR_DARK);
const bgColor = toColor(
marker.colors?.[1] || (command.autoBackgroundColor && isColorDark(fgColor) ? BG_COLOR_LIGHT : BG_COLOR_DARK)
);
const hlColor = marker?.highlightColor || { r: 1, b: 0, g: 1, a: 1 };

@@ -385,3 +433,6 @@

srcOffsets[2 * index + 0] = info.x + BUFFER;
srcOffsets[2 * index + 1] = info.y + BUFFER;
// In order to make sure there's enough room for glyphs' descenders (i.e. 'g'),
// we need to apply an extra offset based on the font resolution.
// The value used to compute the offset is a result of experimentation.
srcOffsets[2 * index + 1] = info.y + BUFFER + 0.05 * command.resolution;
srcWidths[index] = info.width;

@@ -441,3 +492,3 @@

drawText({
makeDrawText(isHitmap)({
instances: totalInstances,

@@ -469,5 +520,2 @@

export default function GLText(props: Props) {
const context = useContext(WorldviewReactContext);
const { dimension } = context;
const [command] = useState(() => makeTextCommand(props.alphabet));

@@ -477,14 +525,8 @@ // HACK: Worldview doesn't provide an easy way to pass a command-level prop into the regl commands,

command.autoBackgroundColor = props.autoBackgroundColor;
command.resolution = Math.max(MIN_RESOLUTION, props.resolution || DEFAULT_RESOLUTION);
command.scaleInvariant = props.scaleInvariantFontSize != null;
// Compute the actual size for the text object in NDC coordinates (from -1 to 1)
// In order to make sure the text is always shown at the same size regardless of
// the canvas dimensions (as Text does), we need to scale it based on both the desired
// font size and the current worldview resolution. Otherwise, the text will be
// displayed at different sizes depending on the worlview canvas dimension.
command.scaleInvariantSize = (props.scaleInvariantFontSize ?? 0) / dimension.height;
command.scaleInvariantSize = props.scaleInvariantFontSize ?? 0;
const getChildrenForHitmap = createInstancedGetChildrenForHitmap(1);
return <Command reglCommand={command} {...props} />;
return <Command getChildrenForHitmap={getChildrenForHitmap} reglCommand={command} {...props} />;
}

@@ -11,4 +11,4 @@ // @flow

import type { Point, CameraCommand, Dimensions, Color, Pose, Scale } from "../types";
import { getCSSColor } from "../utils/commandUtils";
import type { Point, CameraCommand, Dimensions, Color, Pose, Scale, Vec4 } from "../types";
import { getCSSColor, toColor } from "../utils/commandUtils";
import { type WorldviewContextType } from "../WorldviewContext";

@@ -27,4 +27,4 @@ import WorldviewReactContext from "../WorldviewReactContext";

scale: Scale,
color?: Color,
colors?: Color[],
color?: Color | Vec4,
colors?: (Color | Vec4)[],
text: string,

@@ -95,5 +95,6 @@ };

const hasBgColor = colors.length >= 2;
const textColor = hasBgColor ? colors[0] : color;
const textColor = toColor(hasBgColor ? colors[0] : color || [0, 0, 0, 1]);
if (textColor) {
const backgroundColor = toColor(colors[1]);
if (!isColorEqual(this._prevTextColor, textColor)) {

@@ -118,6 +119,6 @@ this._prevTextColor = textColor;

this._inner.style.background = hexBgColor;
} else if (hasBgColor && this._prevBgColor && !isColorEqual(colors[1], this._prevBgColor)) {
} else if (hasBgColor && this._prevBgColor && !isColorEqual(backgroundColor, this._prevBgColor)) {
// update background color with colors[1] data
this._prevBgColor = colors[1];
this._inner.style.background = getCSSColor(colors[1]);
this._prevBgColor = backgroundColor;
this._inner.style.background = getCSSColor(backgroundColor);
}

@@ -124,0 +125,0 @@ }

@@ -14,2 +14,3 @@ // @flow

import Container from "./Container";
import { rng } from "./util";

@@ -22,9 +23,21 @@ import { GLText } from "..";

background = true,
}: {
randomScale = false,
}: {|
text: string,
billboard?: ?boolean,
background?: ?boolean,
}) {
randomScale?: ?boolean,
|}) {
const radius = 10;
const count = 10;
const scale = (i: number) => {
if (!randomScale) {
return { x: 1, y: 1, z: 1 };
}
return {
x: 0.5 + 2.0 * rng(),
y: 0.5 + 2.0 * rng(),
z: 0.5 + 2.0 * rng(),
};
};
return new Array(count).fill().map((_, i) => {

@@ -39,3 +52,3 @@ const angle = (2 * Math.PI * i) / count;

},
scale: { x: 1, y: 1, z: 1 },
scale: scale(i),
color,

@@ -95,2 +108,26 @@ colors: background && i % 4 === 0 ? [color, { r: 1, g: 1, b: 0, a: 1 }] : undefined,

})
.add("glyph ascent and descent", () => {
const markers = textMarkers({ text: "BDFGHJKLPQTY\nbdfghjklpqty", billboard: true });
const target = markers[9].pose.position;
return (
<Container
cameraState={{
target: [target.x, target.y + 2, target.z],
perspective: true,
distance: 8,
}}>
<GLText>{markers}</GLText>
<Axes />
</Container>
);
})
.add("random marker scale", () => {
const markers = textMarkers({ text: "Hello\nWorldview", billboard: true, randomScale: true });
return (
<Container cameraState={{ perspective: true, distance: 25 }}>
<GLText resolution={40}>{markers}</GLText>
<Axes />
</Container>
);
})
.add("scaleInvariant", () => {

@@ -117,3 +154,3 @@ const markers = textMarkers({ text: "Hello\nWorldview", billboard: true });

return (
<Container cameraState={{ perspective: true, distance: 25 }}>
<Container cameraState={{ perspective: true, distance: 25 }} backgroundColor={[0.2, 0.2, 0.4, 1]}>
<GLText scaleInvariantFontSize={40}>{markers}</GLText>

@@ -124,2 +161,11 @@ <Axes />

})
.add("scaleInvariant - perspective: false", () => {
const markers = textMarkers({ text: "Hello\nWorldview", billboard: true });
return (
<Container cameraState={{ perspective: false, distance: 25 }} backgroundColor={[0.4, 0.2, 0.2, 1]}>
<GLText scaleInvariantFontSize={40}>{markers}</GLText>
<Axes />
</Container>
);
})
.add("scaleInvariant resize", () => {

@@ -147,2 +193,11 @@ function Example() {

})
.add("scaleInvariant - ignore scale", () => {
const markers = textMarkers({ text: "Hello\nWorldview", billboard: true, randomScale: true });
return (
<Container cameraState={{ perspective: true, distance: 25 }}>
<GLText scaleInvariantFontSize={30}>{markers}</GLText>
<Axes />
</Container>
);
})
.add("with alphabet", () => {

@@ -149,0 +204,0 @@ const markers = textMarkers({ text: "Hello\nWorldview", billboard: true });

@@ -57,2 +57,4 @@ // @flow

export const toColor = (val: Color | Vec4): Color => (Array.isArray(val) ? vec4ToRGBA(val) : val);
export function getCSSColor(color: Color = DEFAULT_TEXT_COLOR) {

@@ -59,0 +61,0 @@ const { r, g, b, a } = color;

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc