d3.js. Spinning globe with bars

前端 未结 3 1588

I am trying to create spinning globe with bars like in this example. You can see my example here. And everything goes fine until bars go over horizon. I have no idea how to cut

3条回答
  •  伪装坚强ぢ
    2021-02-04 18:07

    A simpler method that works with canvas would be to:

    1. Draw all the bars without clipping
    2. Draw the map
    3. Draw only the foreground bars (i.e., use clipping)

    This clipping does not have to be down manually but can leverage the path.centroid method which respects the clipping set on the projections by clipAngle. Pseudo code might look like:

    let projection = d3.geoOrthographic()
                   .clipAngle(90)
                   ...
    let barProjection = d3.geoOrthographic()
                   .clipAngle(90)
                   ...
    
    let path = d3.geoPath()
             .projection(projection)
             .context(canvasCtx)
    let barPath = d3.geoPath()
             .projection(barProjection)
    
    let renderBar = function(isBgLayer = false) {
        let barLengthAsScale = ...
        barProjection.scale(barLengthAsScale)
        let barStart, barEnd
        if (isBgLayer) {
            barStart = projection([ lon, lat ])
            barEnd = barProjection([ lon, lat ])
        } else {
            let geoJs = { type: 'Point', coordinates: [ lon, lat ] }
            barStart = path.centroid(geoJs)
            barEnd = barPath.centroid(geoJs)
        }
        // draw line from start to end using canvasCtx
    };
    
    let renderMap = function(topology) {
        // normal map drawing to canvas
    };
    
    // then to render a frame
    renderBar(true)
    renderMap(topoJsonTopology)
    renderBar()
    

    Some bars will be drawn twice, but with I've found that canvas is fast enough to keep up with the drawing and keep animations smooth with at least 200+ bars.

    For an example, check out this code on GitHub and the live page.

提交回复
热议问题