Giter VIP home page Giter VIP logo

three-globe's Introduction

ThreeJS Globe Visualization

NPM package Build Size NPM Downloads

Largely inspired by WebGL Globe, this is a ThreeJS WebGL class to represent data visualization layers on a globe, using a spherical projection.

See also the standalone version.

Check out the examples:

Quick start

import ThreeGlobe from 'three-globe';

or using a script tag

<script src="//unpkg.com/three-globe"></script>

then

const myGlobe = new ThreeGlobe()
  .globeImageUrl(myImageUrl)
  .pointsData(myData);

const myScene = new THREE.Scene();
myScene.add(myGlobe);

API reference

Initialisation

new ThreeGlobe({ configOptions })
Config options Description Default
waitForGlobeReady: boolean Whether to wait until the globe wrapping image has been fully loaded before rendering the globe or any of the data layers. true
animateIn: boolean Whether to animate the globe initialization, by scaling and rotating the globe into its inital position. true

Globe Layer

Method Description Default
globeImageUrl([url]) Getter/setter for the URL of the image used in the material that wraps the globe. If no image is provided, the globe is represented as a black sphere. null
bumpImageUrl([url]) Getter/setter for the URL of the image used to create a bump map in the material, to represent the globe's terrain. null
showGlobe([boolean]) Getter/setter for whether to show the globe surface itself. true
showGraticules([boolean]) Getter/setter for whether to show a graticule grid demarking latitude and longitude lines at every 10 degrees. false
showAtmosphere([boolean]) Getter/setter for whether to show a bright halo surrounding the globe, representing the atmosphere. true
atmosphereColor([str]) Getter/setter for the color of the atmosphere. lightskyblue
atmosphereAltitude([str]) Getter/setter for the max altitude of the atmosphere, in terms of globe radius units. 0.15
globeMaterial([material]) Getter/setter of the ThreeJS material used to wrap the globe. Can be used for more advanced styling of the globe, like in this example. MeshPhongMaterial
onGlobeReady(fn) Callback function to invoke immediately after the globe has been initialized and visible on the scene. -

Points Layer

Method Description Default
pointsData([array]) Getter/setter for the list of points to represent in the points map layer. Each point is displayed as a cylindrical 3D object rising perpendicularly from the surface of the globe. []
pointLat([num, str or fn]) Point object accessor function, attribute or a numeric constant for the cylinder's center latitude coordinate. lat
pointLng([num, str or fn]) Point object accessor function, attribute or a numeric constant for the cylinder's center longitude coordinate. lng
pointColor([str or fn]) Point object accessor function or attribute for the cylinder color. () => '#ffffaa'
pointAltitude([num, str or fn]) Point object accessor function, attribute or a numeric constant for the cylinder's altitude in terms of globe radius units (0 = 0 altitude (flat circle), 1 = globe radius). 0.1
pointRadius([num, str or fn]) Point object accessor function, attribute or a numeric constant for the cylinder's radius, in angular degrees. 0.25
pointResolution([num]) Getter/setter for the radial geometric resolution of each cylinder, expressed in how many slice segments to divide the circumference. Higher values yield smoother cylinders. 12
pointsMerge([boolean]) Getter/setter for whether to merge all the point meshes into a single ThreeJS object, for improved rendering performance. Visually both options are equivalent, setting this option only affects the internal organization of the ThreeJS objects. false
pointsTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate point changes involving geometry modifications. A value of 0 will move the objects immediately to their final position. New objects are animated by scaling them from the ground up. Only works if pointsMerge is disabled. 1000

Arcs Layer

Method Description Default
arcsData([array]) Getter/setter for the list of links to represent in the arcs map layer. Each link is displayed as an arc line that rises from the surface of the globe, connecting the start and end coordinates. []
arcStartLat([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the line's start latitude coordinate. startLat
arcStartLng([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the line's start longitude coordinate. startLng
arcEndLat([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the line's end latitude coordinate. endLat
arcEndLng([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the line's end longitude coordinate. endLng
arcColor([str, [str, ...] or fn]) Arc object accessor function or attribute for the line's color. Also supports color gradients by passing an array of colors, or a color interpolator function. () => '#ffffaa'
arcAltitude([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the arc's maximum altitude (ocurring at the half-way distance between the two points) in terms of globe radius units (0 = 0 altitude (ground line), 1 = globe radius). If a value of null or undefined is used, the altitude is automatically set proportionally to the distance between the two points, according to the scale set in arcAltitudeAutoScale. null
arcAltitudeAutoScale([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the scale of the arc's automatic altitude, in terms of units of the great-arc distance between the two points. A value of 1 indicates the arc should be as high as its length on the ground. Only applicable if arcAltitude is not set. 0.5
arcStroke([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the line's diameter, in angular degrees. A value of null or undefined will render a ThreeJS Line whose width is constant (1px) regardless of the camera distance. Otherwise, a TubeGeometry is used. null
arcCurveResolution([num]) Getter/setter for the arc's curve resolution, expressed in how many straight line segments to divide the curve by. Higher values yield smoother curves. 64
arcCircularResolution([num]) Getter/setter for the radial geometric resolution of each line, expressed in how many slice segments to divide the tube's circumference. Only applicable when using Tube geometries (defined arcStroke). 6
arcDashLength([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the length of the dashed segments in the arc, in terms of relative length of the whole line (1 = full line length). 1
arcDashGap([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the length of the gap between dash segments, in terms of relative line length. 0
arcDashInitialGap([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the length of the initial gap before the first dash segment, in terms of relative line length. 0
arcDashAnimateTime([num, str or fn]) Arc object accessor function, attribute or a numeric constant for the time duration (in ms) to animate the motion of dash positions from the start to the end point for a full line length. A value of 0 disables the animation. 0
arcsTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate arc changes involving geometry modifications. A value of 0 will move the arcs immediately to their final position. New arcs are animated by rising them from the ground up. 1000

Polygons Layer

Method Description Default
polygonsData([array]) Getter/setter for the list of polygon shapes to represent in the polygons map layer. Each polygon is displayed as a shaped cone that extrudes from the surface of the globe. []
polygonGeoJsonGeometry([str or fn]) Polygon object accessor function or attribute for the GeoJson geometry specification of the polygon's shape. The returned value should have a minimum of two fields: type and coordinates. Only GeoJson geometries of type Polygon or MultiPolygon are supported, other types will be skipped. geometry
polygonCapColor([str or fn]) Polygon object accessor function or attribute for the color of the top surface. () => '#ffffaa'
polygonCapMaterial([material, str or fn]) Polygon object accessor function, attribute or material object for the ThreeJS material to use in the top surface. This property takes precedence over polygonCapColor, which will be ignored if both are defined. -
polygonSideColor([str or fn]) Polygon object accessor function or attribute for the color of the cone sides. () => '#ffffaa'
polygonSideMaterial([material, str or fn]) Polygon object accessor function, attribute or material object for the ThreeJS material to use in the cone sides. This property takes precedence over polygonSideColor, which will be ignored if both are defined. -
polygonStrokeColor([str or fn]) Polygon object accessor function or attribute for the color to stroke the polygon perimeter. A falsy value will disable the stroking. -
polygonAltitude([num, str or fn]) Polygon object accessor function, attribute or a numeric constant for the polygon cone's altitude in terms of globe radius units (0 = 0 altitude (flat polygon), 1 = globe radius). 0.01
polygonCapCurvatureResolution([num, str or fn]) Polygon object accessor function, attribute or a numeric constant for the resolution (in angular degrees) of the cap surface curvature. The finer the resolution, the more the polygon is fragmented into smaller faces to approximate the spheric surface, at the cost of performance. 5
polygonsTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate polygon altitude changes. A value of 0 will size the cone immediately to their final altitude. New polygons are animated by rising them from the ground up. 1000

Paths Layer

Method Description Default
pathsData([array]) Getter/setter for the list of lines to represent in the paths map layer. Each path is displayed as a line that connects all the coordinate pairs in the path array. []
pathPoints([array, str or fn]) Path object accessor function, attribute or an array for the set of points that define the path line. By default, each path point is assumed to be a 2-position array ([<lat>, <lon>]). This default behavior can be modified using the pathPointLat and pathPointLng methods. pnts => pnts
pathPointLat([num, str or fn]) Path point object accessor function, attribute or a numeric constant for the latitude coordinate. arr => arr[0]
pathPointLng([num, str or fn]) Path point object accessor function, attribute or a numeric constant for the longitude coordinate. arr => arr[1]
pathPointAlt([num, str or fn]) Path point object accessor function, attribute or a numeric constant for the point altitude, in terms of globe radius units (0 = 0 altitude (ground), 1 = globe radius). 0.001
pathResolution([num]) Getter/setter for the path's angular resolution, in lat/lng degrees. If the ground distance (excluding altitude) between two adjacent path points is larger than this value, the line segment will be interpolated in order to approximate the curvature of the sphere surface. Lower values yield more perfectly curved lines, at the cost of performance. 2
pathColor([str, [str, ...] or fn]) Path object accessor function or attribute for the line's color. Also supports color gradients by passing an array of colors, or a color interpolator function. Transparent colors are not supported in Fat Lines with set width. () => '#ffffaa'
pathStroke([num, str or fn]) Path object accessor function, attribute or a numeric constant for the line's diameter, in angular degrees. A value of null or undefined will render a ThreeJS Line whose width is constant (1px) regardless of the camera distance. Otherwise, a FatLine is used. null
pathDashLength([num, str or fn]) Path object accessor function, attribute or a numeric constant for the length of the dashed segments in the path line, in terms of relative length of the whole line (1 = full line length). 1
pathDashGap([num, str or fn]) Path object accessor function, attribute or a numeric constant for the length of the gap between dash segments, in terms of relative line length. 0
pathDashInitialGap([num, str or fn]) Path object accessor function, attribute or a numeric constant for the length of the initial gap before the first dash segment, in terms of relative line length. 0
pathDashAnimateTime([num, str or fn]) Path object accessor function, attribute or a numeric constant for the time duration (in ms) to animate the motion of dash positions from the start to the end point for a full line length. A value of 0 disables the animation. 0
pathTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate path changes. A value of 0 will move the paths immediately to their final position. New paths are animated from start to end. 1000

Heatmaps Layer

Method Description Default
heatmapsData([array]) Getter/setter for the list of heatmap datasets to represent in the heatmaps map layer. Each set of points is represented as an individual global heatmap with varying color and/or altitude, according to the point density. It uses a Gaussian KDE to perform the density estimation, based on the great-arc distance between points. []
heatmapPoints([array, str or fn]) Heatmap object accessor function, attribute or an array for the set of points that define the heatmap. By default, each point is assumed to be a 2-position array ([<lat>, <lon>]). This default behavior can be modified using the heatmapPointLat and heatmapPointLng methods. pnts => pnts
heatmapPointLat([num, str or fn]) Heatmap point object accessor function, attribute or a numeric constant for the latitude coordinate. arr => arr[0]
heatmapPointLng([num, str or fn]) Heatmap point object accessor function, attribute or a numeric constant for the longitude coordinate. arr => arr[1]
heatmapPointWeight([num, str or fn]) Heatmap point object accessor function, attribute or a numeric constant for the weight of the point. The weight of a point determines its influence on the density of the surrounding area. 1
heatmapBandwidth([num, str or fn]) Heatmap object accessor function, attribute or a numeric constant for the heatmap bandwidth, in angular degrees. The bandwidth is an internal parameter of the Gaussian kernel function and defines how localized is the influence of a point on distant locations. A narrow bandwidth leads to a more spiky representation, while a broad one has smoother curves. 4
heatmapColorFn([str or fn]) Heatmap object accessor function or attribute for the color interpolator function to represent density in the heatmap. This function should receive a number between 0 and 1 (or potentially higher if saturation > 1), and return a color string. Turbo colormap interpolator with fading opacity
heatmapColorSaturation([num, str or fn]) Heatmap object accessor function, attribute or a numeric constant for the color scale saturation. The saturation is a multiplier of the normalized density value ([0,1]) before passing it to the color interpolation function. It can be used to dampen outlier peaks in density and bring the data floor into view. 1.5
heatmapBaseAltitude([num, str or fn]) Heatmap object accessor function, attribute or a numeric constant for the heatmap base floor altitude in terms of globe radius units (0 = 0 altitude, 1 = globe radius). 0.01
heatmapTopAltitude([num, str or fn]) Heatmap object accessor function, attribute or a numeric constant for the heatmap top peak altitude in terms of globe radius units (0 = 0 altitude, 1 = globe radius). An equal value to the base altitude will yield a surface flat heatmap. If a top altitude is set, the variations in density will be used to define the altitude curves between base and top. -
heatmapsTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate heatmap changes. A value of 0 will set the heatmap colors/altitudes immediately in their final position. New heatmaps are animated by rising them from the ground up and gently fading in through the color scale. 0

Hex Bin Layer

Method Description Default
hexBinPointsData([array]) Getter/setter for the list of points to aggregate using the hex bin map layer. Each point is added to an hexagonal prism 3D object that represents all the points within a tesselated portion of the space. []
hexBinPointLat([num, str or fn]) Point object accessor function, attribute or a numeric constant for the latitude coordinate. lat
hexBinPointLng([num, str or fn]) Point object accessor function, attribute or a numeric constant for the longitude coordinate. lng
hexBinPointWeight([num, str or fn]) Point object accessor function, attribute or a numeric constant for the weight of the point. Weights for points in the same bin are summed and determine the hexagon default altitude. 1
hexBinResolution([num]) The geographic binning resolution as defined by H3. Determines the area of the hexagons that tesselate the globe's surface. Accepts values between 0 and 15. Level 0 partitions the earth in 122 (mostly) hexagonal cells. Each subsequent level sub-divides the previous in roughly 7 hexagons. 4
hexMargin([num or fn]) The radial margin of each hexagon. Margins above 0 will create gaps between adjacent hexagons and serve only a visual purpose, as the data points within the margin still contribute to the hexagon's data. The margin is specified in terms of fraction of the hexagon's surface diameter. Values below 0 or above 1 are disadvised. This property also supports using an accessor method based on the hexagon's aggregated data, following the syntax: hexMargin(({ points, sumWeight, center: { lat, lng }}) => ...). This method should return a numeric constant. 0.2
hexAltitude([num or fn]) The altitude of each hexagon, in terms of globe radius units (0 = 0 altitude (flat hexagon), 1 = globe radius). This property also supports using an accessor method based on the hexagon's aggregated data, following the syntax: hexAltitude(({ points, sumWeight, center: { lat, lng }}) => ...). This method should return a numeric constant. ({ sumWeight }) => sumWeight * 0.01
hexTopCurvatureResolution([num]) The resolution (in angular degrees) of the top surface curvature. The finer the resolution, the more the top area is fragmented into smaller faces to approximate the spheric surface, at the cost of performance. 5
hexTopColor([fn]) Accessor method for each hexagon's top color. The method should follow the signature: hexTopColor(({ points, sumWeight, center: { lat, lng }}) => ...) and return a color string. () => '#ffffaa'
hexSideColor([fn]) Accessor method for each hexagon's side color. The method should follow the signature: hexSideColor(({ points, sumWeight, center: { lat, lng }}) => ...) and return a color string. () => '#ffffaa'
hexBinMerge([boolean]) Getter/setter for whether to merge all the hexagon meshes into a single ThreeJS object, for improved rendering performance. Visually both options are equivalent, setting this option only affects the internal organization of the ThreeJS objects. false
hexTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate hexagon changes related to geometry modifications (altitude, radius). A value of 0 will move the hexagons immediately to their final position. New hexagons are animated by scaling them from the ground up. Only works if hexBinMerge is disabled. 1000

Hexed Polygons Layer

Method Description Default
hexPolygonsData([array]) Getter/setter for the list of polygon shapes to represent in the hexed polygons map layer. Each polygon is displayed as a tesselated group of hexagons that approximate the polygons shape according to the resolution specified in hexPolygonResolution. []
hexPolygonGeoJsonGeometry([str or fn]) Hexed polygon object accessor function or attribute for the GeoJson geometry specification of the polygon's shape. The returned value should have a minimum of two fields: type and coordinates. Only GeoJson geometries of type Polygon or MultiPolygon are supported, other types will be skipped. geometry
hexPolygonColor([str or fn]) Hexed polygon object accessor function or attribute for the color of each hexagon in the polygon. () => '#ffffaa'
hexPolygonAltitude([num, str or fn]) Hexed polygon object accessor function, attribute or a numeric constant for the polygon's hexagons altitude in terms of globe radius units (0 = 0 altitude, 1 = globe radius). 0.001
hexPolygonResolution([num, str or fn]) Hexed polygon object accessor function, attribute or a numeric constant for the geographic binning resolution as defined by H3. Determines the area of the hexagons that tesselate the globe's surface. Accepts values between 0 and 15. Level 0 partitions the earth in 122 (mostly) hexagonal cells. Each subsequent level sub-divides the previous in roughly 7 hexagons. 3
hexPolygonMargin([num, str or fn]) Hexed polygon object accessor function, attribute or a numeric constant for the radial margin of each hexagon. Margins above 0 will create gaps between adjacent hexagons within a polygon. The margin is specified in terms of fraction of the hexagon's surface diameter. Values below 0 or above 1 are disadvised. 0.2
hexPolygonUseDots([boolean, str or fn]) Hexed polygon object accessor function, attribute or a boolean constant for whether to represent each polygon point as a circular dot instead of an hexagon. false
hexPolygonCurvatureResolution([num, str or fn]) Hexed polygon object accessor function, attribute or a numeric constant for the resolution (in angular degrees) of each hexed polygon surface curvature. The finer the resolution, the more the polygon hexes are fragmented into smaller faces to approximate the spheric surface, at the cost of performance. 5
hexPolygonDotResolution([num, str or fn]) Hexed polygon object accessor function, attribute or a numeric constant for the resolution of each circular dot, expressed in how many slice segments to divide the circumference. Higher values yield smoother circles, at the cost of performance. This is only applicable in dot representation mode. 12
hexPolygonsTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate hexed polygons altitude and margin changes. A value of 0 will move the hexagons immediately to their final state. New hexed polygons are animated by sizing each hexagon from 0 radius. 0

Tiles Layer

Method Description Default
tilesData([array]) Getter/setter for the list of tiles to represent in the tiles map layer. Each tile is displayed as a spherical surface segment. The segments can be placed side-by-side for a tiled surface and each can be styled separately. []
tileLat([num, str or fn]) Tile object accessor function, attribute or a numeric constant for the segment's centroid latitude coordinate. lat
tileLng([num, str or fn]) Tile object accessor function, attribute or a numeric constant for the segment's centroid longitude coordinate. lng
tileAltitude([num, str or fn]) Tile object accessor function, attribute or a numeric constant for the segment's altitude in terms of globe radius units. 0.01
tileWidth([num, str or fn]) Tile object accessor function, attribute or a numeric constant for the segment's longitudinal width, in angular degrees. 1
tileHeight([num, str or fn]) Tile object accessor function, attribute or a numeric constant for the segment's latitudinal height, in angular degrees. 1
tileUseGlobeProjection([boolean, str or fn]) Tile object accessor function, attribute or a boolean constant for whether to use the globe's projection to shape the segment to its relative tiled position (true), or break free from this projection and shape the segment as if it would be laying directly on the equatorial perimeter (false). true
tileMaterial([material, str or fn]) Tile object accessor function, attribute or material object for the ThreeJS material used to style the segment's surface. () => new MeshLambertMaterial({ color: '#ffbb88' })
tileCurvatureResolution([num, str or fn]) Tile object accessor function, attribute or a numeric constant for the resolution (in angular degrees) of the surface curvature. The finer the resolution, the more the tile geometry is fragmented into smaller faces to approximate the spheric surface, at the cost of performance. 5
tilesTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate tile changes involving geometry modifications. A value of 0 will move the tiles immediately to their final position. New tiles are animated by scaling them from the centroid outwards. 1000

Rings Layer

Method Description Default
ringsData([array]) Getter/setter for the list of self-propagating ripple rings to represent in the rings map layer. Each data point is displayed as an animated set of concentric circles that propagate outwards from (or inwards to) a central point through the spherical surface. []
ringLat([num, str or fn]) Ring object accessor function, attribute or a numeric constant for each circle's center latitude coordinate. lat
ringLng([num, str or fn]) Ring object accessor function, attribute or a numeric constant for each circle's center longitude coordinate. lng
ringAltitude([num, str or fn]) Ring object accessor function, attribute or a numeric constant for the circle's altitude in terms of globe radius units. 0.0015
ringColor([str, [str, ...] or fn]) Ring object accessor function or attribute for the stroke color of each ring. Also supports radial color gradients by passing an array of colors, or a color interpolator function. () => '#ffffaa'
ringResolution([num]) Getter/setter for the geometric resolution of each circle, expressed in how many slice segments to divide the circumference. Higher values yield smoother circles. 64
ringMaxRadius([num, str or fn]) Ring object accessor function, attribute or a numeric constant for the maximum outer radius of the circles, at which the rings stop propagating and are removed. Defined in angular degrees. 2
ringPropagationSpeed([num, str or fn]) Ring object accessor function, attribute or a numeric constant for the propagation velocity of the rings, defined in degrees/second. Setting a negative value will invert the direction and cause the rings to propagate inwards from the maxRadius. 1
ringRepeatPeriod([num, str or fn]) Ring object accessor function, attribute or a numeric constant for the interval of time (in ms) to wait between consecutive auto-generated concentric circles. A value less or equal than 0 will disable the repetition and emit a single ring. 700

Labels Layer

Method Description Default
labelsData([array]) Getter/setter for the list of label objects to represent in the labels map layer. []
labelLat([num, str or fn]) Label object accessor function, attribute or a numeric constant for the latitude coordinate. lat
labelLng([num, str or fn]) Label object accessor function, attribute or a numeric constant for the longitude coordinate. lng
labelText([str or fn]) Label object accessor function or attribute for the label text. text
labelColor([str or fn]) Label object accessor function or attribute for the label color. () => 'lightgrey'
labelAltitude([num, str or fn]) Label object accessor function, attribute or a numeric constant for the label altitude in terms of globe radius units. 0
labelSize([num, str or fn]) Label object accessor function, attribute or a numeric constant for the label text height, in angular degrees. 0.5
labelTypeFace([typeface ]) Getter/setter for the text font typeface JSON object. Supports any typeface font generated by Facetype.js. helvetiker regular
labelRotation([num, str or fn]) Label object accessor function, attribute or a numeric constant for the label rotation in degrees. The rotation is performed clockwise along the axis of its latitude parallel plane. 0
labelResolution([num]) Getter/setter for the text geometric resolution of each label, expressed in how many segments to use in the text curves. Higher values yield smoother labels. 3
labelIncludeDot([boolean, str or fn]) Label object accessor function, attribute or a boolean constant for whether to include a dot marker next to the text indicating the exact lat, lng coordinates of the label. If enabled the text will be rendered offset from the dot. true
labelDotRadius([num, str or fn]) Label object accessor function, attribute or a numeric constant for the radius of the dot marker, in angular degrees. 0.1
labelDotOrientation([str or fn]) Label object accessor function or attribute for the orientation of the label if the dot marker is present. Possible values are right, top and bottom. () => 'bottom'
labelsTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate label changes involving position modifications (lat, lng, altitude, rotation). A value of 0 will move the labels immediately to their final position. New labels are animated by scaling their size. 1000

HTML Elements Layer

Method Description Default
htmlElementsData([array]) Getter/setter for the list of objects to represent in the HTML elements map layer. Each HTML element is rendered using ThreeJS CSS2DRenderer. []
htmlLat([num, str or fn]) HTML element accessor function, attribute or a numeric constant for the latitude coordinate of the element's central position. lat
htmlLng([num, str or fn]) HTML element accessor function, attribute or a numeric constant for the longitude coordinate of the element's central position. lng
htmlAltitude([num, str or fn]) HTML element accessor function, attribute or a numeric constant for the altitude coordinate of the element's position, in terms of globe radius units. 0
htmlElement([str or fn]) Accessor function or attribute to retrieve the DOM element to use. Should return an instance of HTMLElement. null
htmlTransitionDuration([num]) Getter/setter for duration (ms) of the transition to animate HTML elements position changes. A value of 0 will move the elements immediately to their final position. 1000

3D Objects Layer

Method Description Default
objectsData([array]) Getter/setter for the list of custom 3D objects to represent in the objects layer. Each object is rendered according to the objectThreeObject method. []
objectLat([num, str or fn]) Object accessor function, attribute or a numeric constant for the latitude coordinate of the object's position. lat
objectLng([num, str or fn]) Object accessor function, attribute or a numeric constant for the longitude coordinate of the object's position. lng
objectAltitude([num, str or fn]) Object accessor function, attribute or a numeric constant for the altitude coordinate of the object's position, in terms of globe radius units. 0.01
objectRotation([{[x], [y], [z]}, str or fn]) Object accessor function, attribute or a {x, y, z} object for the object's rotation (in degrees). Each dimension is optional, allowing for rotation only in some axes. Rotation is applied in the order X->Y->Z. -
objectFacesSurface([boolean, str or fn]) Object accessor function, attribute or a boolean constant for whether the object should be rotated to face (away from) the globe surface (true), or be left in its original universe orientation (false). true
objectThreeObject([Object3d, str or fn]) Object accessor function or attribute for defining a custom 3d object to render as part of the objects map layer. Should return an instance of ThreeJS Object3d. A yellow sphere

Custom Layer

Method Description Default
customLayerData([array]) Getter/setter for the list of items to represent in the custom map layer. Each item is rendered according to the customThreeObject method. []
customThreeObject([Object3d, str or fn]) Object accessor function or attribute for generating a custom 3d object to render as part of the custom map layer. Should return an instance of ThreeJS Object3d. null
customThreeObjectUpdate([str or fn]) Object accessor function or attribute for updating an existing custom 3d object with new data. This can be used for performance improvement on data updates as the objects don't need to be removed and recreated at each update. The callback method's signature includes the object to be update and its new data: customThreeObjectUpdate((obj, objData) => { ... }). null

Utility

Method Description
getGlobeRadius() Returns the cartesian distance of a globe radius in absolute spatial units.
getCoords(lat, lng [,altitude]) Utility method to translate spherical coordinates. Given a pair of latitude/longitude coordinates and optionally altitude (in terms of globe radius units), returns the equivalent {x, y, z} cartesian spatial coordinates.
toGeoCoords({ x, y, z }) Utility method to translate cartesian coordinates to the geographic domain. Given a set of 3D cartesian coordinates {x, y, z}, returns the equivalent {lat, lng, altitude} spherical coordinates. Altitude is defined in terms of globe radius units.

Render Options

Method Description Default
rendererSize(Vector2) It's recommended to inject the current renderer size to ensure the object proportions remain constant. This is specially necessary when using path FatLines. Fallback to the full browser window size (THREE.Vector2(window.innerWidth, window.innerHeight))
pauseAnimation() Pauses the animation on all globe layers.
resumeAnimation() Resumes the animation on all globe layers.

Giving Back

paypal If this project has helped you and you'd like to contribute back, you can always buy me a ☕!

three-globe's People

Contributors

dependabot[bot] avatar marvin-kolja avatar rgreen32 avatar samnrubin avatar samshal avatar vasturiano avatar vikgmdev avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

three-globe's Issues

updating labels size according to zoom

hey :) i want to show the size of the dot of the labels dynamically, according to zoom, so that they be big enough to be visible when the hole globe is in view, but small enough after zooming to fit in the screen (lets say 100 times closer then the default settings)
what would be the way to do that?
thanks a lot

Custom Layer Performance

Hi! First of all, thanks for a great project. Some really cool visualizations are possible right out of the gate which is awesome! I just have a question about performance in the custom layer. I noticed that when I increased the number of objects to 10-15k, the FPS started to drop pretty fast. I don't know a whole lot about Three, but in my limited experience I was able to improve the performance by about 10fps by changing up the customThreeObject a bit. So here's what it is in the example:

.customThreeObject(d => new THREE.Mesh(
    new THREE.SphereBufferGeometry(d.radius),
    new THREE.MeshLambertMaterial({ color: d.color })
))

I created a group of sphere geometries ahead of time, created a name property in the data object based off the index, and then grabbed the object by name in the customThreeObject accessor:

const N = 15000;

...

const geometry = new THREE.SphereBufferGeometry(0.5, 16, 16);
const group = new THREE.Group();
const material = new THREE.MeshLambertMaterial();
const protoSphere = new THREE.Mesh(geometry, material);

for (let i = 0; i < N; i++) {
    const sphere = protoSphere.clone();
    sphere.position.x = data[i].lng;
    sphere.position.y = data[i].lat;
    sphere.position.z = data[i].alt;
    sphere.name = `object${i}`;
    group.add(sphere);
}

...

.customThreeObject((d) => group.getObjectByName(d.name))

Like I said earlier this improves performance by about 10fps, and gets me to a point where, at least on my machine, my app is pretty responsive. However I was wondering if there was an even better way to improve performance when visualizing large datasets. I tried working with an InstancedMesh, but like I said, I just don't know enough about Three to really have much success with that yet.

Thanks again for all your hard work, and any insight you have on this issue would be great!

Bug: Unable to create links from API reference

Describe the bug
When trying to create rings from the API reference for the rings layer the methods are not suggested and can not be used:
https://github.com/vasturiano/three-globe/blob/master/example/ripples/index.html

All other references work perfectly!

To Reproduce

  1. Duplicate the code: https://github.com/vasturiano/three-globe/blob/master/example/ripples/index.html
  2. Try to adjust the Globe references / add layers

Desktop (please complete the following information):

  • Browser chrome

Looking forward to some help!

Support video texture

Is your feature request related to a problem? Please describe.
My project requires very complex dynamic effects on the globe surface, it's hard to code in three.js, but we cloud make a 2:1 globe video to simulate all effects.
Three.js has a video texture demo, so is there possible to render video texture on the globe?

Describe the solution you'd like
Like the demo, we cloud customize a video texture in globeMaterial()

In addition, like #9, support image/video content on the globe with particular location would be a nice feature

Polygon Layer cannot cover globe surface with small altitude value, holes in big regions

Describe the bug
The polygon geometries cannot cover the globe surface if set with a small altitude value.

set 0 altitude, make polygon layer close to the surface, it only shows borders for most of countries
Screen Shot 2020-07-15 at 20 18 06

with bigger altitude value, more regions show, but still leaves holes in big countries, like China, Russia
Screen Shot 2020-07-15 at 20 18 48

It seems that the ConicPolygonBufferGeometry with border coords is not fully fit the curve of a globe.

Expected behavior
It should cover all surface event with 0 altitude.

support rendering loading icon until globe is ready

Is your feature request related to a problem? Please describe.
It'd be a better user experience if a customizable loading icon could be rendered until the globe is ready and rendered like:

https://jsfiddle.net/vfug1adn/19/

Describe the solution you'd like
A fine minimal solution would be to allow users to provide a callback that is run at the start of initGlobe. In my case the callback would be used to remove the loading icon from the screen now that the globe is ready

Describe alternatives you've considered
I guess the "threejs" way of doing this might also be to use the LoadingManager somehow

Additional context

Is there a way to make the globe transparent?

Describe the bug
Not a bug but it's not technically a feature request:

Is there a way to make the globe transparent, similar to stripe/github's globe? Or at worst, ability to change it to a nicer solid colour rather than just black? Can't see any parameters anywhere that allows you to control globe colour/transparency.

Thank you! <3

JSFIDDLE
https://jsfiddle.net/wv1eqab5/2/

Screenshot 2022-01-31 at 14 59 30 (2)

Examples of HexBin and HexedPolygon does not output data (layer) onto globe surface

Describe the bug
I am unable to see any data projected on globe surface with HexBin and HexedPolygon examples.
I can only see globe with a texture.

For HexBin example console prints this output:

Uncaught TypeError: e is undefined
    update https://unpkg.com/three-globe:20
    o https://unpkg.com/three-globe:2
    l https://unpkg.com/three-globe:2
three-globe:20:7278
    update https://unpkg.com/three-globe:20
    o https://unpkg.com/three-globe:2
    l https://unpkg.com/three-globe:2

For HexedPolygon example console prints this output:

 Uncaught TypeError: e is undefined
    x https://unpkg.com/three-globe:20
    updateObj https://unpkg.com/three-globe:20
    en https://unpkg.com/three-globe:5
    en https://unpkg.com/three-globe:5
    en https://unpkg.com/three-globe:5
    tn https://unpkg.com/three-globe:5
    update https://unpkg.com/three-globe:20
    o https://unpkg.com/three-globe:2
    l https://unpkg.com/three-globe:2

To Reproduce

  1. Open https://vasturiano.github.io/three-globe/example/hexbin/
  2. Open https://vasturiano.github.io/three-globe/example/hexed-polygons/

Expected behavior
I expect to see data mapped onto surface.

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser: Firefox
  • Version 88.0.1 (x64)

three-fatline dependency problem

When I try to build my static site in prod it fails with this error:

5:08:10 PM: failed Building production JavaScript and CSS bundles - 40.636s
5:08:10 PM: error Generating JavaScript bundles failed
5:08:10 PM: Can't resolve 'three-fatLine' in '/opt/build/repo/node_modules/three-globe/dist'
5:08:10 PM: error Generating JavaScript bundles failed
5:08:10 PM: /opt/build/repo/node_modules/gatsby/dist/utils/babel-loader.js??ref--4-0!/opt/build/repo/src/components/globe.js 2c1f6f1bb8d0d5c79d3cffa76a8ca2cf
5:08:10 PM: Unexpected token (1769:35)
5:08:10 PM: |         var stroke = strokeAccessor(path);
5:08:10 PM: |         var useFatLine = stroke !== null && stroke !== undefined;
5:08:10 PM: |         var obj = useFatLine ? new !(function webpackMissingModule() { var e = new Error("Cannot find module 'three-fatLine'"); e.code = 'MODULE_NOT_FOUND'; throw e; }())(new !(function webpackMissingModule() { var e = new Error("Cannot find module 'three-fatLine'"); e.code = 'MODULE_NOT_FOUND'; throw e; }())(), new !(function webpackMissingModule() { var e = new Error("Cannot find module 'three-fatLine'"); e.code = 'MODULE_NOT_FOUND'; throw e; }())()) : new THREE$7.Line(new THREE$7.BufferGeometry(), sharedShaderMaterial.clone() // Separate material instance per object to have dedicated uniforms (but shared shaders)
5:08:10 PM: |         );
5:08:10 PM: |         obj.__globeObjType = 'path'; // Add object type

I think I narrowed the problem to 8742ca4 because I confirmed that when I use three-globe v2.3.4 I see this problem but when I use three-globe v2.1.2 the build passes.

Also interestingly I can build the static site locally but it fails to build in Netlify when it's being deployed in prod. I'm not exactly sure what's causing the error but could this repo do without the three-fatline dep? If so, since three-globe v2.1.2 works fine, I think removing the need for the three-fatline dep would be a simple way to resolve this for me.

Possible to determine the width / height of the globe?

Hi, apologies if this is the incorrect place to ask, but I'm trying to determine the width / height of the globe when appearing within the canvas. The camera has unique z / y values set, so I'd need to take that into account.

The reason I'm trying to achieve this is because I would like to overlay a native DOM element (a circle) directly over the Three.js globe, with the same position, width and height.

Is this possible, and does anybody have any ideas about how I might approach this?

issue with latest version 136 three.js

Describe the bug
Uncaught TypeError: Class constructor BufferGeometry cannot be invoked without 'new'
at new gt (three-globe.js:2)
at stateInit (three-globe.js:2)
at new (three-globe.js:2)
at N (three-globe.js:2)
at three-globe.js:20
at Object.execCb (require.js:1696)
at Module.check (require.js:883)
at Module. (require.js:1139)
at require.js:134
at require.js:1189

After updating three.js to version 136 I am getting this BufferGeometry issue, I think you are probably aware of this, so I was wondering if this will be updated in the future?

To Reproduce
Steps to reproduce the behavior:

  1. open three-globe using three.js version 136

Expected behavior
n/a

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Multipolygon holes not rendered correctly

Is there any way to render GeoJSON multipolygons which contain holes using the polygons layer? I just can't make this work - a very simple example is 2 triangles nested into each other (one of them is poportionally smaller):

const polygonData = {
  "type": "FeatureCollection",
  "features": [
    {
      "properties": {},
      "type": "Feature",
      "geometry": {
        "type": "MultiPolygon",
        "coordinates": [
          [
            [
              [-40, -15],
              [-30, -5],
              [-40, -5],
              [-40, -15]
            ],
            [
              [-39, -12],
              [-32, -6],
              [-39, -6],
              [-39, -12]
            ]
          ]
        ]
      }
    }
  ]
}

...

globeInstance.polygonsData(polygonData.features)

Expected result:
image
(taken from https://geojson.io/, you can also try https://geojson.tools/ - the result is identical)

Actual results:
imageimage

  • OS: Windows 10
  • Browser: Electron 13.1.7 (Chromium)
  • Library version: 2.18.8

Make GLOBE_RADIUS configurable

Is your feature request related to a problem? Please describe.
I need to change the Earth Radius because I need very precise coordinates for the object around the earth. I do not need it to be 1:1, but with radius 100, the scale is too big and it is making the 3d simulation look inaccurate.

Describe the solution you'd like
Add a GLOBE_RADIUS option to ThreeGlobe.

.htmlElementsData() and .htmlElement() causes an uncaught type error - missing definition?

Using .htmlElementsData() and .htmlElement() causes a "Uncaught TypeError: ...is not a function"

Going to the definition in "three-globe.d.ts", nothing resembling those functions exists there. As per the docs, there are hexes, polygons, custom layers etc. but no html elements.

Steps to reproduce the behavior:

  1. initialize an instance of ThreeGlobe() and try using the .htmlElementsData() or .htmlElement()

Path animation with FlatLine

I see your comment on path animation with flatline:

obj.__dashAnimateStep = 0; // can't animate dashes on fat lines (no initial gap)

Can we do something to support dashes in flatline? or use different geometry?
e.g. A group of arcs with stroke(TubeGeometry) connected with each other would do a same result as A path, so can we use TubeGeometry in path layer with stroke?

How to animate color change?

I want to be able to animate color change over time. My use case is polyhexes, but in general - how can you change the color/props of the graph without (the force method) running new data through your model? the new data approach seems to re-create the geometry - and for the record it is also flawed; for instance I filtered countries to European continents, then changed the data to Asian ones, and the only way I could get that to work was to re-create the entire globe.

you have a great visualizer, but its a shame that rendering data over time is not a native predicted feature of this component.

The correct way to import with react / next JS

Hello,
I'm so sorry to open this, however I have spent the past 8 hours trying to get it done with next JS with no luck.

I have the following great example fully working in an HTML file

Screen Shot 2021-04-04 at 3 28 01 PM
and here is the code for the html file:

<head>
  <title>2</title>
  <script src="//unpkg.com/three"></script>
  <script src="//unpkg.com/three/examples/js/controls/TrackballControls.js"></script>
  <script src="//unpkg.com/three-globe"></script>
  <!--<script src="../../dist/three-globe.js"></script>-->
</head>

<body>
  <div id="globeViz"></div>

  <script>
    const Globe = new ThreeGlobe().globeImageUrl("g7.png");
    //.bumpImageUrl("//unpkg.com/three-globe/example/img/earth-topology.png");

    // custom globe material
    const globeMaterial = Globe.globeMaterial();
    globeMaterial.bumpScale = 10;
    new THREE.TextureLoader().load(
      "//unpkg.com/three-globe/example/img/earth-water.png",
      (texture) => {
        globeMaterial.specularMap = texture;
        globeMaterial.specular = new THREE.Color("lightgreen");
        globeMaterial.shininess = 25;
      }
    );

    // Setup renderer
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.getElementById("globeViz").appendChild(renderer.domElement);

    // Setup scene
    const scene = new THREE.Scene();
    scene.add(Globe);
    scene.add(new THREE.AmbientLight(0xbbbbbb));
    scene.add(new THREE.DirectionalLight(0xffffff, 0.2));

    // Setup camera
    const camera = new THREE.PerspectiveCamera();
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    camera.position.z = 500;

    // Add camera controls
    const tbControls = new THREE.TrackballControls(camera, renderer.domElement);
    tbControls.minDistance = 101;
    tbControls.rotateSpeed = 5;
    tbControls.zoomSpeed = 0.8;

    // Kick-off renderer
    function animate() {
      // IIFE
      // Frame cycle
      tbControls.update();
      Globe.rotation.y += 0.005;
      renderer.render(scene, camera);
      requestAnimationFrame(animate);
    }
    animate();
  </script>
</body>

Now i need to move this to next JS, and I want to use three-globe not react-globe.gl as this one gives me the needed control to do customization.

Here is the code for my next JS component.

import { useEffect } from 'react';
import dynamic from 'next/dynamic';
const ThreeGlobe = dynamic(() => import('three-globe').then(mod => mod.ThreeGlobe), { ssr: false })

export default function GlobeComponent() {

    useEffect(async () => {
        const myGlobe = new ThreeGlobe();

    }, []);


    return (
        <div>  </div>
    )
};

and it gives this error whatever i try to do
Screen Shot 2021-04-04 at 3 31 21 PM

I think it might be something with how kapsule-class.js is implemented but i can't wrap my head around it.

Thank you so much.

Attempting to integrate this library in a React Native App using Expo

Hello and thank you for such a great library!

I am attempting to use this library within a react native app using expo with some success but one issue. I am able to generate the globe, render it, add data points, etc. but the globe image itself, I cannot get it to render, I can only get a black globe. I tried forking the project and altering the code to achieve the image rendering however, I have been unsuccessful. Is this an incompatibility with Expo? (I am sort of assuming this may be the case) In order to get the globe to render at all, I had to utilize expo-three. Would I need to rewrite this library to use expo-three? Would you happen to have any ideas on how I could overcome this? Any help or guidance is greatly appreciated.

my current GLView snippet (Note in order to get this to work I had to use the renderer from expo-three):

<GLView
          style={{ flex: 1 }}
          onContextCreate={async (gl) => {
            const { drawingBufferWidth: width, drawingBufferHeight: height } = gl;

            // Gen random data
            const N = 300;
            const gData = [...Array(N).keys()].map(() => ({
              lat: (Math.random() - 0.5) * 180,
              lng: (Math.random() - 0.5) * 360,
              size: Math.random() / 3,
              color: ['red', 'white', 'blue', 'green'][Math.round(Math.random() * 3)]
            }));

            gData.forEach(d => d.size = Math.random());
            
            const Globe = new ThreeGlobe()
              .globeImageUrl('../../assets/images/globe/earth-night.png')
              .pointsData(gData)
              .pointColor('color')
              .showAtmosphere(true);

            // Scale Globe larger 
            Globe.scale.multiplyScalar(1.6);

            // Set up renderer
            const renderer = new Renderer({ gl, alpha: true });
            renderer.setSize(width, height);

            // Set up the scene
            const scene = new THREE.Scene();
            scene.add(Globe);
            scene.add(new THREE.AmbientLight(0xbbbbbb));
            scene.add(new THREE.DirectionalLight(0xffffff, 0.6));

            // Set up the camera
            const camera = new THREE.PerspectiveCamera();
            camera.aspect = gl.drawingBufferWidth / gl.drawingBufferHeight;
            camera.updateProjectionMatrix();
            camera.position.z = 500;

            Globe.update
            const render = () => {
              requestAnimationFrame(render);
              renderer.render(scene, camera);
              gl.endFrameEXP();
            };
            render();
          }}
        />
</View>

Thanks again!

Possible to rotate along X axis without needing to interact?

I was curious if there was possibly a way to naturally have the globe rotate on the x axis without interfering with the user when they try and interact with the sphere.

I have tried rotating the object but it does not do anything sadly.

Non working rotate code:

import { useEffect, useRef } from 'react'
import * as THREE from 'three'
import { TrackballControls } from 'three/examples/jsm/controls/TrackballControls'
import ThreeGlobe from 'three-globe'

function Mindmap() {
  const canvasRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    const Globe = new ThreeGlobe({
      animateIn: true,
    })
      .globeImageUrl('//unpkg.com/three-globe/example/img/earth-blue-marble.jpg')

    Globe.atmosphereColor('#ffffff')
    .atmosphereAltitude(0.1)

    const globeMaterial = Globe.globeMaterial() as THREE.MeshPhongMaterial;
    globeMaterial.shininess = 0;

    // Setup renderer
    const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
    renderer.setSize(window.innerHeight, window.innerHeight);
    canvasRef.current?.appendChild(renderer.domElement);

    // Setup scene
    const scene = new THREE.Scene();
    scene.add(Globe);
    scene.add(new THREE.AmbientLight(0xbbbbbb));
    renderer.setClearColor( 0xffffff, 0 )

    // Setup camera
    const camera = new THREE.PerspectiveCamera();
    camera.aspect = 1;
    camera.position.z = 500;
    camera.updateProjectionMatrix();

    // Add camera controls
    const tbControls = new TrackballControls(camera, renderer.domElement);
    tbControls.rotateSpeed = 1;
    tbControls.noZoom = true
    tbControls.noPan = true
    tbControls.object.position.z = 260


    function addLight(color: number, intensity = 1, ...pos: [number, number, number]): void {
      const light = new THREE.DirectionalLight(color, intensity)
      light.position.set(...pos)
      scene.add(light)
    }
    addLight(0x3055A5, 2, -20, 20, 20)
    addLight(0x7830A5, 2, 20, -20, -20)

    const clamp = (num: number, min: number, max: number) => Math.min(Math.max(num, min), max)

    let animate = function () {
      requestAnimationFrame(animate);
      tbControls.update()
      tbControls.object.rotation.x += 0.001
      renderer.render(scene, camera)
    };
    animate()

    return () => {
      animate = () => {}
      canvasRef.current?.removeChild(renderer.domElement)
    }
  }, [])

  return (
    <div className="Mindmap">
      <div className='canvas-context' ref={canvasRef} />
    </div>
  )
}

export default Mindmap

I was also attempting to clamp rotation to not pass a certain point on the y axis but I am unsure of what to target to handle rotation.

JSPM Interop Issue

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://jspm.org/sandbox#H4sIAAAAAAAAA51YbVPbOBD+fPwKXe5DnDtsJwQ4jiZM0kApPWA6BNq56fSDYiuJgi35JJkQbu6/30q2gvNSpVdm2sSrR8++SevddH6OeaQWGUFTlSZnex37QXB8todQJyUKo2iKhSSqW8vV2D+pmQVFVULO7giOFBoqLBQRnbAQLvcxnJJu7YmSecaFqqGIM0UY8MxprKbdmDzRiPjmYR9RRhXFiS8jnJBuC7R0wsKMzojHC8P6s+/DB0Ifhh9v0CVhRGDFBbpKNT+6wZlZvYipQg9316fglMrkaRhOLDSYySwNKA9/eTi4nf51+fbx/CK7vR8c3Q0GRx+uB9mH689XfDGc/nkff7p9OUk+DtnDvDm7WTTvb971+yK+/STTfh/0+L4xSUaCZgrpGHZr1BiS4szE6B9jTSmUtdNSACI1FYT4k4SPCIhrSzPx0j6WpacVVO8gODgMjsKYShVW5EHK4zwhsK1muP/dL3TKiGdkReUWHZVlAPRULsbhiPOEYOZnnDLlU/0lWUw4c5jp3tg7Do6CZmE4kSFlMXnW5u6va56SJCNC7lRU4r6bl7InLChmaifzEvld3HNC2EyG5lMvutjXsL3WSXAcHJbZNMJoJtc04CgiUnLhj13Br6B6raAdHBSkFXHliFTY47aPhcALB7WF9NpBKzgOpYi2RgJgEU+4cDMZiGFquphikuCc7TLLoiBPTfDYwTfmIsWuzC8xu22bEO4mAgCwNIPWDhb/iQvOON3JZoFw+3ewwp0jAm4cVq6CsgrcbaspxW4+A+kd7sqDoukOIo0wFjlzoFHfldQKEKzbkVklqH418XzHIX7FwV1zeowV9me6EroIlyBgO7DF/VX6jYtLRjxnkTOaJcTQtrYbWNwg5b62S1DvyCRmGxPBIspdbhYA/QIL2iZghWCNZiygV4CsRY/EZVIVZnLQLqL2TsvvjXiNeNr2ncXZrMPB+92WzpHgc0lEaBbWyEwAiqroj1xFahVYrcyrK9tzbC4p022ES0OJMcWh/c2j+IgzmTtvcYkAI1sQhsLKUrbdvExw/XZxvfH0QxhxQYx1TX8E7SB0MCHjcKjoSC6jXHL58BnnkaKcrSkTfJRLBeskphFULZfaDWxZ4rbFxTRRu5qvHuw+BA/CUU6TuGi8tsek6MmgOtDIdj66gkMbLFznxLUNEnIExldavu04l0FjrBLKdjeZJQ78PbJXamXBpQPsmMn/4+76Bn3y7MHbjnCoD8kzTrME2rSZTMNyA4XHe/KsLu1+ZwlYTfX38rkNSTiOoUsN38H74tp8/2EbtlO51QsCR17oXYPh8OD8rnz8YRscfG5DckUTGb7Nx2MibPQetOyHTXEyVo2hbGG6zgOXniUIDuEh1OilYDlSwVC1Z//X/zphMfLpCa+cSdHFEN2YE4qGU5rKUzuRQnmWSN/XMU0SBO0IKg6yRGX9k2hO1ZTnCtHKDpln5sHDsIs8RwQGzMFUgK/o5I/fGmujJ5YLFiGo/91vvoKlX+j1pTavWljWlrTXKBJczw50Qlm3hhlni5Tnsna27vnK6FuwmLkXWWfudRYv9ZyKxmA9qlcm1/qbvb2ffgpDPcYjgVkM67r3Mfuh0EmFblEXtZvNNxXR5BwgIP4SBEFfv0O920bwSBbSa3wNIHae10DdM+TZuRb63FPk3WA1DQodsO4jqHIN9CtqnTTteUnY5Nu49vESJ+kLOUWruBC17bI5OafoSx3eQPV9VJ9PqSL6yyjJzecE/Gf1r18KBujS4jWloK3xtThvjQaE6NX1Io5dxMi8ElivUaoOTFSvUjwhDyLx6mGYs+xxEkQ8rf5gYO9SSNOJ7sTU1I+xeAxm2aS+pBrlafYjTIrDWeeTRZCxCpv5RUDqxHkmfasL/URRlcfEq+vYru0a6Hh6dRPWug2HJOoeunu4NGW2bbINewC37AJHUy/WS3GgWSFqK1FuvCl3mBBuGvim/C0FHTabTasWjuqQqDxDthZWcmNFNj3v7y4ugs9kdHltK6VXklpkAF4MwTRvDs0JnweUMSI+F7+EVUXvCZ1MVbk55lGeEpgMJkRdJER/fbu4ir26Scgn+lJvBDjLQMVgCv2Kt1QGXpf4DW9kRBipuGKeV/wYaom13ywHOI49E7sN6eu2fjqioPBa2+81n0fmr+HYcE4FMR0gTuymsfnbh4t43NiwPIKWX1TrRSFYsf0jlNhMsz6RgVm1fhTYAJtV2LKRhnAzCys78wyqFfko+KwwGg6YoM9r9BmX1PS0L6DiSJcy60I/jq29eqQUPJEVT9RoUApXvLkXOHocwUvBrnoFxT7anmlN+EoVpJSdQ83HMBoCbavZ2kAIrsCpYUZIrA3eWH/hPLWrzeDk1Z0/YfTy+Xi8ejm8MYyh2n+EGYVJHE4R+kfDr67eXZRXEJ7M8IaiRZSQUlhRWcTZW17ZpafFF8+cpP0ylhXU3zmRqm/UggFGhVdaYe93o2B9fa11wuKX5k5Y/Az+H5ipKlgeFwAA
  2. See error

Expected behavior
three-globe should be supported on JSPM

Additional context

JSPM tries to use the module version of three-globe, which in turn imports frame-ticker like this:

import FrameTicker from 'frame-ticker';

JSPM follows the Node.js CJS / ESM interop pattern (https://nodejs.org/dist/latest-v18.x/docs/api/esm.html#commonjs-namespaces), which therefore treats the default export of a CommonJS module as the CommonJS module itself.

This matches FrameTickers own documentation as to the CommonJS representation of FrameTicker requiring an explicit .default access - https://www.npmjs.com/package/frame-ticker#usage.

The correct pattern to use by Node.js interop while also supporting Webpack interop would be:

import _FrameTicker from 'frame-ticker';
const FrameTicker = _FrameTicker.default || FrameTicker;

This two line change should be enough to get comprehensive JSPM support.

Some polygons from geojson data have holes in caps...

First off, i just wanted to say awesome work on this project! Thank you so much for all your hard work on this!

Problem:
Most of the polygons are drawn fine, but there are a few that seem to have areas missing on the caps, although the data seems to be there because the edges are visible, as well as the sides. I am using the same geojson data at you are, and when previewing those files in various viewers, the holes are not there. This makes me think this must have something to do with how the geojson country coords are being drawn/parsed (to me it almost looks like the points are being drawn out of order sometimes...) I have attached a few screenshots from your choropleth example

Im thinking the issue may lie in: https://github.com/vasturiano/three-conic-polygon-geometry

Can you shed some light on why this may be happening?

  • OS: OSX
  • Browser Chrome
  • Version 88.0.4324.192

Screen Shot 2021-03-02 at 4 23 15 PM
Screen Shot 2021-03-02 at 4 23 02 PM
Screen Shot 2021-03-02 at 4 22 31 PM

Points Customization

Hey!

I've been playing around with the "Three-Globe" for a while now and I must say great work and clear documentation!
Now I'm searching for a way to create and customize points and lines like the screenshot attached. Is this already possible with the custom layer? If so, how can I create custom 2D HTML elements on the globe?

image

[Feature request] Curved text label

The label layer uses flat text geometry, it works fine, but I try to prevent long text goes far away from the surface:

Screen Shot 2020-07-16 at 05 29 48

it will be a great feature if text labels could curved nicely around the surface, especially for long text labels:
Screen Shot 2020-07-16 at 05 29 13

Option for setting custom material for points

Is your feature request related to a problem? Please describe.
Points don't look as shiny as I want them to be.

Describe the solution you'd like
Please add pointsMaterial option (e.g. I want mine to be made out of metal).

Describe alternatives you've considered
Using rgba color values for points to make them look like glass, but that's just nowhere as good as metal.

Additional context
Currently there's globeMaterial, polygonCapMaterial, polygonSideMaterial, tileMaterial, but no pointsMaterial in globe.gl, which wraps this plugin. Adding pointsMaterial, possibly later followed by arcMaterial, pathMaterial, hexMaterial, hexPolygonMaterial, and perhaps labelMaterial, would cover all possible styling needs.

Integrating with react-three-fiber

Hi, very cool project!

I am trying to learn more about how to use this library with react-three-fiber

I was able to successfully add the globe to the ThreeJS scene using a useEffect hook:

import React, { useEffect } from "react";
import { useThree } from "react-three-fiber";
import ThreeGlobe from "three-globe";

const MyGlobe = new ThreeGlobe()
  .globeImageUrl("//unpkg.com/three-globe/example/img/earth-blue-marble.jpg")
  .bumpImageUrl("//unpkg.com/three-globe/example/img/earth-topology.png");

const Globe = (props) => {
  const { scene } = useThree();
  // This reference will give us direct access to the mesh

  useEffect(() => {
    scene.add(myGlobe);
  }, []);

  return null;
};

export default Globe;

However ideally I would be able to render the MyGlobe as a component instead so it can be controlled using react-three-fiber utilities such as useFrame as shown in their example:

import ReactDOM from 'react-dom'
import React, { useRef, useState } from 'react'
import { Canvas, useFrame } from 'react-three-fiber'

function Box(props) {
  // This reference will give us direct access to the mesh
  const mesh = useRef()

  // Set up state for the hovered and active state
  const [hovered, setHover] = useState(false)
  const [active, setActive] = useState(false)

  // Rotate mesh every frame, this is outside of React without overhead
  useFrame(() => {
    mesh.current.rotation.x = mesh.current.rotation.y += 0.01
  })

  return (
    <mesh
      {...props}
      ref={mesh}
      scale={active ? [1.5, 1.5, 1.5] : [1, 1, 1]}
      onClick={(event) => setActive(!active)}
      onPointerOver={(event) => setHover(true)}
      onPointerOut={(event) => setHover(false)}>
      <boxBufferGeometry args={[1, 1, 1]} />
      <meshStandardMaterial color={hovered ? 'hotpink' : 'orange'} />
    </mesh>
  )
}

ReactDOM.render(
  <Canvas>
    <ambientLight />
    <pointLight position={[10, 10, 10]} />
    <Box position={[-1.2, 0, 0]} />
    <Box position={[1.2, 0, 0]} />
  </Canvas>,
  document.getElementById('root')
)

Do you have any tips? Thanks for your help!

[Feature request] Clickable Labels

I've scanned trough the documentation, but cannot find anything about adding click functionality to a label?

Maybe a solution to create a callback on the rendered labels/dots and create a raycaster functions on it?

Examples broken - u.computeFaceNormals is not a function

Describe the bug
Some of the examples aren't rendering, probably because of the following console error: u.computeFaceNormals. I think this has been deprecated but not sure about the specific version of Three JS.

To Reproduce
Steps to reproduce the behavior:

  1. Go to https://vasturiano.github.io/three-globe/example/hexed-polygons/
  2. Inspect the page using browser dev tools
  3. See error: Uncaught TypeError: u.computeFaceNormals is not a function

Expected behavior
I expected the example page to load the hexed polygon data visualisation.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: OSX
  • Browser [chrome, firefox]
  • Version [latest]

Additional context
Add any other context about the problem here.

Missing __threeObj in polygon callbacks

Describe the bug
For all other layers, we can access d.__threeObj in property callbacks, but missing in polygon layer

Expected behavior
Can access __threeObj in polygon property callbacks

Example doesn't work(hexed-polygons)

Describe the bug
I tried run example and got this message:
Uncaught TypeError: Cannot read property 'BufferGeometryUtils' of undefined
at x (three-globe:20)
at updateObj (three-globe:20)
at three-globe:5
at Array.forEach ()
at three-globe:5
at zt (three-globe:5)
at Vt (three-globe:5)
at Function.update (three-globe:20)
at three-globe:2
at l (three-globe:2)

To Reproduce
Steps to reproduce the behavior:

  1. Go to 'https://vasturiano.github.io/three-globe/example/hexed-polygons/'
  2. See error

Screenshots
image

Desktop (please complete the following information):

  • OS: Windows 7
  • Browser Chrome
  • Version [e.g. 22]

Additional context
I tried use hexed polygons for my project but it doesn't work. I want to use three-globe instead globe.gl because idk how to work with scene in globe.gl and add other objects

Compile error when add three-globe in angular 11

Describe the bug
I want to use three-globe to show a globe in angular 11.
But after install three-globe with "npm install three-globe" and write code in component like "
@component({
selector: 'app-globe',
templateUrl: './globe.component.html',
styleUrls: ['./globe.component.css']
})
export class GlobeComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
    this.makeGlobe()
  }

  makeGlobe() {
    var myGlobe = new ThreeGlobe();

    var myScene = new THREE.Scene();
    myScene.add(myGlobe);

  }

}

" after that I execute "ng serve", then several errors occur
"
Error: node_modules/three-globe/dist/three-globe.d.ts:105:37 - error TS2709: Cannot use namespace 'Material' as a type.

105 polygonCapMaterial(): ObjAccessor;
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:106:52 - error TS2709: Cannot use namespace 'Material' as a type.

106 polygonCapMaterial(materialAccessor: ObjAccessor): ChainableInstance;
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:109:38 - error TS2709: Cannot use namespace 'Material' as a type.

109 polygonSideMaterial(): ObjAccessor;
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:110:53 - error TS2709: Cannot use namespace 'Material' as a type.

110 polygonSideMaterial(materialAccessor: ObjAccessor): ChainableInstance;
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:207m:31 - error TS2709: Cannot use namespace 'Material' as a type.

207 tileMaterial(): ObjAccessor;
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:208:46 - error TS2709: Cannot use namespace 'Material' as a type.

208 tileMaterial(materialAccessor: ObjAccessor): ChainableInstance;
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:247:24 - error TS2709: Cannot use namespace 'Object3D' as a type.

247 customThreeObject(): Object3D | string | ((d: object, globeRadius: number) => Object3D);
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:247:81 - error TS2709: Cannot use namespace 'Object3D' as a type.

247 customThreeObject(): Object3D | string | ((d: object, globeRadius: number) => Object3D);
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:248:39 - error TS2709: Cannot use namespace 'Object3D' as a type.

248 customThreeObject(object3DAccessor: Object3D | string | ((d: object, globeRadius: number) => Object3D)): ChainableInstance;
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:248:96 - error TS2709: Cannot use namespace 'Object3D' as a type.

248 customThreeObject(object3DAccessor: Object3D | string | ((d: object, globeRadius: number) => Object3D)): ChainableInstance;
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:249:46 - error TS2709: Cannot use namespace 'Object3D' as a type.

249 customThreeObjectUpdate(): string | ((obj: Object3D, objData: object, globeRadius: number) => void);
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:250:61 - error TS2709: Cannot use namespace 'Object3D' as a type.

250 customThreeObjectUpdate(object3dAccessor: string | ((obj: Object3D, objData: object, globeRadius: number) => void)): ChainableInstance;
~~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:257:19 - error TS2709: Cannot use namespace 'Vector2' as a type.

257 rendererSize(): Vector2;
~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:258:22 - error TS2709: Cannot use namespace 'Vector2' as a type.

258 rendererSize(size: Vector2): ChainableInstance;
~~~~~~~

Error: node_modules/three-globe/dist/three-globe.d.ts:40:20 - error TS2709: Cannot use namespace 'Material' as a type.

40 globeMaterial(): Material;
~~~~~~~~
"

[Bug?]Wrong shortest line between two standard GPS coords in path

Describe the bug
If using standard GPS coords[-90/90, 180/180], for those lines pass through 180/-180
e.g. between [116, 30] and [-175, 30],

1610552897925
the shortest way should pass 180/-180, but it goes with the big arc

Expected behavior
It should use shortest line between two GPS coords

So we need to optimise the algorithm to find the shortest way in path layer

Installing globe.gl with npm results in non-working parcel due to tween.js version

Describe the bug

Importing Globe GL like so:

import Globe from 'globe.gl';

Results in the below error when running parcel.

Uncaught TypeError: Cannot read properties of undefined (reading 'update')
    at onFrame (three-globe.module.js:3289:13)
    at Function.init (three-globe.module.js:3290:6)
    at initStatic (kapsule.module.js:139:14)
    at comp (kapsule.module.js:133:7)
    at new FromKapsule (three-globe.module.js:3315:61)
    at linkKapsule (globe.gl.module.js:152:16)
    at 3DUmY.three (globe.gl.module.js:194:17)
    at newRequire (index.4d6bcbeb.js:71:24)
    at localRequire (index.4d6bcbeb.js:84:35)
    at 6bJph.three (GlobeVisualization.js:5:1)

The tween object appears to be undefined. The latest tween version is 18.6.4, forcing a downgrade to 18.6.0 resolves the import issue

npm install @tweenjs/[email protected]

To Reproduce
Steps to reproduce the behavior:

  1. Create a node package
  2. Install globe.gl and parcel
  3. Create a file (index.js) that imports globe.gl
  4. run parcel index.js
  5. In the console the error shown above appears

Expected behavior
The import should complete instead of entering an infinite error loop

Desktop (please complete the following information):

  • OS: Ubuntu 22.04.1 LTS
  • Browser Chrome
  • Version 104.0.5112.101 (Official Build) (64-bit)

Paths layer has buggy behavior when using FatLines

Describe the bug
It seems that FatLines have some buggy behavior compared to the regular 1px lines when used on the paths layer. I first noticed this in my own project which uses the globe.gl component. In that project I call pathsData with new data every 5 seconds, and I noticed that after a few intervals, FatLines stop appearing intermittently. It works fine with regular 1px lines (not applying any stroke). It also seems to work fine if I set pathsTransitionDuration to 0, strangely.

Below I've provided a minimal repro using the paths example.

To Reproduce
Steps to reproduce the behavior:

  1. See this JSFiddle (which is just the paths example with .pathStroke(5) added to force it to use FatLines): https://jsfiddle.net/rbqt9L87/
  2. Note that the lines do not animate as they regularly do (except intermittently while the altitude transition is occurring, strangely). The lines also seem to flicker in and out of existence during this.

Expected behavior
I expected the lines to behave similarly to the regular 1px lines that are used without the added .pathStroke(5) call.

Desktop (please complete the following information):

  • OS: Windows 10
  • Browser: Firefox
  • Version: 72.0.1

Smartphone (please complete the following information):

  • Device: iPhone 11
  • OS: iOS 13.3
  • Browser: Safari

Thanks for your work on this awesome library!

Suggestion - Method(s) to get ThreeJS object references

It would be really helpful if there were getters on the constructed globe instance to get ThreeJS object references
that were rendered by this lib.

It would enable higher customization; as you could get a certain set of objects rendered by this lib
and pass it to something like three's raycaster to query intersecting objects.

Example Usage:

// Create Data Point
const gData = [
  {
      lat: 1100,
      lng: 10,
      color: 'red',
      size: 0.1,
  }
]
const colorInterpolator = (t: number) => `rgba(255,0,0,${1-t})`

// Setup camera
const camera = new THREE.PerspectiveCamera();

// Construct Globe & Pass Data Points
const Globe = new ThreeGlobe({
  animateIn: true,
})
  .globeImageUrl(ed)
  .pointsData(gData)
  .pointAltitude('size')
  .pointColor('color')

// Create Raycaster
const raycaster = new THREE.Raycaster()

// Check If Hovering Over A Data Point
function checkHover(vec2) {
  raycaster.setFromCamera(vec2, camera)

  // Globe.points() would be an accessor to all point mesh refs currently rendered
  return raycaster.intersectObjects(Globe.points(), true)
}

const intersections = checkHover(...)

Ability to add another image on globe

Is your feature request related to a problem? Please describe.
The problem I am facing is that i need to render another PNG over the globe generated.

Describe the solution you'd like
I have a PNG image with a transparent background that looks like below. This is generated with information describing the corners of this image.

Corner Coordinates:
Upper Left  (-130.0000000,  55.0000000) (130d 0' 0.00"W, 55d 0' 0.00"N)
Lower Left  (-130.0000000,  20.0000010) (130d 0' 0.00"W, 20d 0' 0.00"N)
Upper Right ( -60.0000020,  55.0000000) ( 60d 0' 0.01"W, 55d 0' 0.00"N)
Lower Right ( -60.0000020,  20.0000010) ( 60d 0' 0.01"W, 20d 0' 0.00"N)
Center      ( -95.0000010,  37.5000005) ( 95d 0' 0.00"W, 37d30' 0.00"N)

image

It will be really nice to overlay given images on the globe at the specified region.

Additional context
Cesium does something similar that add imagery overlays on the globe. Which results like
image

Ref: https://sandcastle.cesium.com/gallery/Imagery%20Layers%20Manipulation.html

Make arc blending mode configurable

Is your feature request related to a problem? Please describe.
When using light textures, the arcs are super bright and hard to see. This is due to using AdditiveBlending for the Arcs Layer. It would be great to be able to configure this to make the arcs properly visible.
Screenshot of the light arcs

Describe the solution you'd like
Add an arcsBlendingMode option to ThreeGlobe

Describe alternatives you've considered
There are no suitable alternatives, because changing the color of the arcs does not affect the blending mode.

How to use hover listening event

Describe the bug
Hello I would like to know if it's possible to make change to canvas while hovering labelText for example ?
Is it related to THREEJS or three-globe ?

I would like to reproduce same Github Homepage hover label
https://github.com/

Thanks for your help

[ERR_REQUIRE_ESM]: require() of d3-geo is not supported. Instead change the require of index.js in `/three-geojson-geometry/dist/three-geojson-geometry.common.js` to a dynamic import() which is available in all CommonJS modules.

Having issue with importing.

error - Error [ERR_REQUIRE_ESM]: require() of ES Module /d3-geo/src/index.js from /three-geojson-geometry/dist/three-geojson-geometry.common.js not supported.
Instead change the require of index.js in /three-geojson-geometry/dist/three-geojson-geometry.common.js to a dynamic import() which is available in all CommonJS modules.

using version 2.24.4

Do three-globe support tree-shaking for webpack?

I am using your awesome library in my project, but then I found that the bunder size is a little bit large, I am not sure thee-globe can support tree-shaking or not?

import ThreeGlobe from "three-globe";

image

How to Change Helvetiker Font

Hi,

I can't run characters like ç,ğ,ö in the labeltext area. ? appears on the screen as a sign. Is there any way to fix this issue?

Memory leak when updating Globe.tilesData()

To Reproduce
Update the Globe.tilesData() in a setInterval(). After some time it will crash the browser because of the lack of memory.

I've created a simple repo to showcase the issue:
https://stackblitz.com/edit/web-platform-85n1dt

It does nothing special, just extends the default demo of the tiles layer with the folowing code:

setInterval(() => {
  Globe.tilesData(
    tilesData.slice(0, Math.floor(Math.random() * tilesData.length))
  );
}, 1000);

If you open up the developer tools, in the memory tab, you will see that the memory usage will keep growing until it crashed the browser.
Screenshot 2022-02-28 at 13 51 17 1

Expected behavior
It should not crash the browser because of the lack of memory.

Desktop:

  • OS: macOS Monterey
  • Browser chrome Version 98.0.4758.102 (Official Build) (x86_64)

The issue is caused by creating a THREE.SphereBufferGeometry object in an animation callback function.

obj.geometry = new THREE.SphereBufferGeometry(
GLOBE_RADIUS * (1 + alt),
Math.ceil(width / (curvatureResolution || -1)),
Math.ceil(height / (curvatureResolution || -1)),
deg2Rad(90 - width / 2) + (useGlobeProjection ? rotLng : 0),
deg2Rad(width),
deg2Rad(90 - height / 2) + (useGlobeProjection ? rotLat : 0),
deg2Rad(height)
);
if (!useGlobeProjection) {
// rotate obj instead. order matters, rotate longitudinally first.
obj.setRotationFromEuler(new THREE.Euler(rotLat, rotLng, 0, 'YXZ'));
}
};

If you comment out the lines 81-89 the memory usage is constant, but the animation stops working (duh).

Ideally the object would be created once, outside of the animation callback, and then only updated in the animation callback.
But I'm too big of a Threejs noob to help out here.

I did manage to make it work in my app, by making the following workaround:

  1. call the applyPosition() function outside of the animation, just once.
  2. animate the creating of the tile by tweening the scale of the sphere.

The diff generated by patch-package looks like this:

diff --git a/node_modules/three-globe/dist/three-globe.module.js b/node_modules/three-globe/dist/three-globe.module.js
index ff966a1..252b829 100644
--- a/node_modules/three-globe/dist/three-globe.module.js
+++ b/node_modules/three-globe/dist/three-globe.module.js
@@ -2437,6 +2437,11 @@ var TilesLayerKapsule = Kapsule({
           height: 0
         });
 
+        var animate = (td) => {
+          obj.scale.x = td.scale;
+          obj.scale.y = td.scale;
+        }
+
         if (Object.keys(targetD).some(function (k) {
           return currentTargetD[k] !== targetD[k];
         })) {
@@ -2445,7 +2450,8 @@ var TilesLayerKapsule = Kapsule({
             applyPosition(targetD);
           } else {
             // animate
-            new TWEEN.Tween(currentTargetD).to(targetD, state.tilesTransitionDuration).easing(TWEEN.Easing.Quadratic.InOut).onUpdate(applyPosition).start();
+            applyPosition(targetD);
+            new TWEEN.Tween({ scale: 0 }).to({ scale: 1 }, state.tilesTransitionDuration).easing(TWEEN.Easing.Quadratic.InOut).onUpdate(animate).start();
           }
         }
       }

Continuously push new arc data

Preface: First off, huge fan of all your work, thanks so much for all the effort you've put in and making these open source. I'll also caveat that I'm a threeJS noob so feel free to school me or tell me to go read the docs more 😄

Feature request / question: I'm wondering if it's possible within three-globe to continually update the arcs data in this example. I want to build something similar to the Github globe (go to github.com when you are not logged in to see it in action), where I have a real time feed of data (coming from a websocket or something) that I want to visualize on the globe.

CleanShot 2021-12-03 at 15 35 00@2x

From the example you have, I tried updating the arcs data in the animation loop but as you could guess this didn't work (no arcs ever even completed their path since it would get instantly reset each time animate was called).

    (function animate() { // IIFE
      // define newArcsData
     Globe.arcsData(newArcsData)
    
      tbControls.update();
      renderer.render(scene, camera);
      requestAnimationFrame(animate);
    })();

Please let me know if this is possible with three-globe, or if I'll need to do it directly in three-js. Thanks in advance!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.