diff --git a/README.md b/README.md index e3dd557..b158167 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ const globe = createGlobe(canvas, { markers: [ { location: [37.7595, -122.4367], size: 0.03 }, { location: [40.7128, -74.006], size: 0.1, color: [1, 0, 0] }, // custom color + { location: [51.5074, -0.1278], size: 0.05, elevation: 0.15 }, // custom elevation ], arcs: [ { diff --git a/src/anchor.js b/src/anchor.js index 217a22b..9f0df81 100644 --- a/src/anchor.js +++ b/src/anchor.js @@ -46,7 +46,7 @@ export function createAnchorManager(wrapper) { const key = marker.id if (!key) continue - const pos = project(marker.location) + const pos = project(marker.location, marker.elevation) activeKeys[key] = 1 diff --git a/src/index.d.ts b/src/index.d.ts index dd90fb0..d170ffa 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -2,6 +2,7 @@ export interface Marker { location: [number, number] size: number color?: [number, number, number] + elevation?: number id?: string } diff --git a/src/index.js b/src/index.js index 91e4036..ee62594 100644 --- a/src/index.js +++ b/src/index.js @@ -144,6 +144,8 @@ export default (canvas, opts) => { MARKER_aMarkerSize, MARKER_aMarkerColor, MARKER_aHasColor, + MARKER_aMarkerElevation, + MARKER_aHasElevation, ]) // Arc uniforms @@ -212,8 +214,8 @@ export default (canvas, opts) => { function updateMarkers(newMarkers) { markers = newMarkers - // 8 floats per marker: x, y, z, size, r, g, b, hasColor - const markerData = new Float32Array(markers.length * 8) + // 10 floats per marker: x, y, z, size, r, g, b, hasColor, elevation, hasElevation + const markerData = new Float32Array(markers.length * 10) markers.forEach((m, i) => { markerData.set( @@ -222,8 +224,10 @@ export default (canvas, opts) => { m.size, ...(m.color || [0, 0, 0]), m.color ? 1 : 0, + m.elevation ?? 0, + m.elevation != null ? 1 : 0, ], - i * 8, + i * 10, ) }) @@ -292,10 +296,12 @@ export default (canvas, opts) => { /** * Project a location to screen coordinates + * @param {[number, number]} location + * @param {number} [elevation] - per-marker elevation override */ - function project(location) { + function project(location, elevation) { const pos3D = latLonTo3D(location) - const r = GLOBE_R + markerElevation + const r = GLOBE_R + (elevation != null ? elevation : markerElevation) const elevatedPos = [pos3D[0] * r, pos3D[1] * r, pos3D[2] * r] const rotated = applyRotation(elevatedPos) @@ -551,7 +557,7 @@ export default (canvas, opts) => { // Bind instance buffer gl.bindBuffer(gl.ARRAY_BUFFER, markerInstanceBuffer) - const markerStride = 8 * 4 // 8 floats * 4 bytes + const markerStride = 10 * 4 // 10 floats * 4 bytes setupInstancedAttribute( markerAttribs[MARKER_aMarkerPos], @@ -581,6 +587,20 @@ export default (canvas, opts) => { 28, 1, ) + setupInstancedAttribute( + markerAttribs[MARKER_aMarkerElevation], + 1, + markerStride, + 32, + 1, + ) + setupInstancedAttribute( + markerAttribs[MARKER_aHasElevation], + 1, + markerStride, + 36, + 1, + ) // Set uniforms gl.uniform1f(markerUniforms[MARKER_phi], phi) diff --git a/src/marker.glslx b/src/marker.glslx index c34f2f7..edd8f07 100644 --- a/src/marker.glslx +++ b/src/marker.glslx @@ -12,6 +12,8 @@ attribute vec3 aMarkerPos; attribute float aMarkerSize; attribute vec3 aMarkerColor; attribute float aHasColor; +attribute float aMarkerElevation; +attribute float aHasElevation; uniform float phi; uniform float theta; @@ -23,7 +25,8 @@ uniform float markerElevation; void vertex() { float cx = cos(theta), sx = sin(theta); float cy = cos(phi), sy = sin(phi); - vec3 p = aMarkerPos * (0.8 + markerElevation); + float elev = aHasElevation > 0.5 ? aMarkerElevation : markerElevation; + vec3 p = aMarkerPos * (0.8 + elev); vec3 rp = vec3( cy * p.x + sy * p.z, sy * sx * p.x + cx * p.y - cy * sx * p.z, diff --git a/website/app/components/MarkersArcs.tsx b/website/app/components/MarkersArcs.tsx index a2ced9e..a970cd4 100644 --- a/website/app/components/MarkersArcs.tsx +++ b/website/app/components/MarkersArcs.tsx @@ -9,14 +9,16 @@ const markersArcsTabs = [ name: 'Markers', code: `markers: [ // Basic marker - { location: [37.78, -122.44], size: 0.03 }, + { location: [37.78, -122.44], size: 0.03, id: 'sf' }, + // With per-marker elevation override + { location: [40.71, -74.01], size: 0.03, id: 'nyc', elevation: 0.12 }, // With custom color (RGB 0-1) { location: [51.51, -0.13], size: 0.05, color: [1, 0, 0] }, // With id for CSS anchoring { location: [35.68, 139.65], size: 0.04, id: 'tokyo' } ]`, description: - 'Place dots on the globe using `[latitude, longitude]`. Size is relative to globe radius (0.01-0.1). Colors override the global `markerColor`.', + 'Place dots on the globe using `[latitude, longitude]`. Size is relative to globe radius (0.01-0.1). Colors override the global `markerColor`. `elevation` overrides the global `markerElevation` for a single marker.', }, { key: 'arcs', diff --git a/website/app/page.tsx b/website/app/page.tsx index 2fdbd71..f21732a 100644 --- a/website/app/page.tsx +++ b/website/app/page.tsx @@ -144,7 +144,7 @@ const apiOptions = [ { name: 'markers', type: 'Marker[]', - desc: '{ location: [lat, lon], size, color?, id? }', + desc: '{ location: [lat, lon], size, color?, elevation?, id? }', }, { name: 'arcs', @@ -161,7 +161,7 @@ const apiOptions = [ { name: 'markerElevation', type: 'number', - desc: 'Marker height above surface (0 to 0.2)', + desc: 'Default marker height above surface (0 to 0.2). Overridable per marker via elevation.', }, { name: 'scale', type: 'number', desc: 'Globe scale multiplier (default 1)' }, { name: 'offset', type: '[x,y]', desc: 'Pixel offset from center [x, y]' }, @@ -1207,6 +1207,41 @@ const markerPresets = { }, ], }, + 'Different Elevations': { + markers: [ + { + id: 'pg-elev-sf', + location: [37.78, -122.44] as [number, number], + label: 'San Francisco', + elevation: 0.02, + }, + { + id: 'pg-elev-nyc', + location: [40.71, -74.01] as [number, number], + label: 'New York', + elevation: 0.06, + }, + { + id: 'pg-elev-london', + location: [51.51, -0.13] as [number, number], + label: 'London', + elevation: 0.1, + }, + { + id: 'pg-elev-tokyo', + location: [35.68, 139.65] as [number, number], + label: 'Tokyo', + elevation: 0.14, + }, + { + id: 'pg-elev-sydney', + location: [-33.87, 151.21] as [number, number], + label: 'Sydney', + elevation: 0.18, + }, + ], + arcs: [], + }, 'Data Centers': { markers: [ {