javascriptd3.jsthree.jsmap-projectionsd3.geo

syncing d3.js with THREE.js earth


I am trying to combine WebGL earth with d3.geo.satellite projection.

I have managed to to overlay the 2 projections on top of each other and sync rotation, but I am having trouble to sync zooming. When I sync them to match size, WebGL projection gets deformed, but the d3.geo.satellite remains the same. I have tried different combination of projection.scale, projection.distance without much success.

Here is JS fiddle (it take a little while to load the resources). You can drag it to rotate (works well). But if you zoom in (use mousewheel) you can see the problem.

https://jsfiddle.net/nxtwrld/7x7dLj4n/2/

The important code is at the bottom of the script - the scale function.

function scale(){
    var scale = d3.event.scale;
    var ratio = scale/scale0;

    // scale projection
    projection.scale(scale);

    // scale Three.js earth
    earth.scale.x = earth.scale.y = earth.scale.z = ratio;
}

Solution

  • I do not using WebGL earth either , checking on your jsfiddle is not working anymore, and my assumption of your problem that you want to integrated D3.js with Threejs as a solution for 3d globe.

    May I suggest you to try earthjs as your solution. Under the hood it use D3.js v4 & Threejs revision 8x both are the latest, and it can combine between Svg, canvas & threejs(WebGL).

        const g = earthjs({padding:60})
        .register(earthjs.plugins.mousePlugin())
        .register(earthjs.plugins.threejsPlugin())
        .register(earthjs.plugins.autorotatePlugin())
        .register(earthjs.plugins.dropShadowSvg(),'dropshadow')
        .register(earthjs.plugins.worldSvg('../d/world-110m.json'))
        .register(earthjs.plugins.globeThreejs('../globe/world.jpg'))
        g._.options.showLakes = false;
        g.ready(function(){
            g.create();
        })
    

    above snippet code you can run it from here.