一、效果展示

二、代码
import * as L from "leaflet";
import * as d3 from "d3";
import * as topojson from "topojson";
import { wordJson } from "./world";
L.Control.GlobeMiniMap = L.Control.extend({
options: {
position: "bottomleft",
width: 82,
height: 82,
land: "#bbb",
water: "rgba(0, 0, 0, 0.3)",
marker: "#CC0000",
topojsonSrc: wordJson,
},
initialize: function (options) {
L.Util.setOptions(this, options);
},
onAdd: function (map) {
this._mainMap = map;
this._container = L.DomUtil.create("div", "leaflet-control-minimap");
this._container.style.width = this.options.width + "px";
this._container.style.height = this.options.height + "px";
L.DomEvent.disableClickPropagation(this._container);
L.DomEvent.on(this._container, "mousewheel", L.DomEvent.stopPropagation);
this._userToggledDisplay = false;
this._minimized = false;
this._mainMap.on("moveend", this._onMainMapMoved, this);
return this._container;
},
addTo: function (map) {
L.Control.prototype.addTo.call(this, map);
this.initCanvas();
return this;
},
initCanvas: function () {
d3.select(".leaflet-control-minimap")
.append("svg")
.attr("width", 82)
.attr("height", 82)
.attr("style", "position: absolute; left: 0; top: 0;")
.append("path")
.attr(
"d",
"m 768,896 q 0,106 -75,181 -75,75 -181,75 -106,0 -181,-75 -75,-75 -75,-181 0,-106 75,-181 75,-75 181,-75 106,0 181,75 75,75 75,181 z m 256,0 q 0,-109 -33,-179 L 627,-57 q -16,-33 -47.5,-52 -31.5,-19 -67.5,-19 -36,0 -67.5,19 Q 413,-90 398,-57 L 33,717 Q 0,787 0,896 q 0,212 150,362 150,150 362,150 212,0 362,-150 150,-150 150,-362 z"
)
.attr("transform", "scale(.01,-.01),translate(3600,-3900)")
.attr("style", "fill:" + this.options.marker);
this.projection = d3.geo
.orthographic()
.scale(40)
.translate([41, 41])
.rotate([0, 0])
.clipAngle(90);
var canvas = d3
.select(".leaflet-control-minimap")
.append("canvas")
.attr("width", 400)
.attr("height", 400);
this.c = canvas.node().getContext("2d");
this.path = d3.geo.path().projection(this.projection).context(this.c);
var that = this;
d3.json(this.options.topojsonSrc, function () {
const world = wordJson;
that.globe = { type: "Sphere" };
that.land = topojson.feature(world, world.objects.land);
});
this.transitionMap(this._mainMap.getCenter());
},
transitionMap: function (p) {
var that = this;
var c = that.c;
var path = that.path;
d3.transition()
.duration(1250)
.each("start", function () {})
.tween("rotate", function () {
var r = d3.interpolate(that.projection.rotate(), [-p.lng, -p.lat]);
return function (t) {
that.projection.rotate(r(t));
c.clearRect(0, 0, that.options.width, that.options.height);
c.fillStyle = that.options.water;
c.beginPath();
path(that.globe);
c.fill();
c.fillStyle = that.options.land;
c.beginPath();
path(that.land);
c.fill();
};
});
},
onRemove: function (map) {
this._mainMap.off("moveend", this._onMainMapMoved, this);
this._mainMap.off("move", this._onMainMapMoving, this);
},
_onMainMapMoved: function (e) {
if (!this._miniMapMoving) {
this._mainMapMoving = true;
this.transitionMap(this._mainMap.getCenter());
} else {
this._miniMapMoving = false;
}
},
});
L.control.globeminimap = function (layer, options) {
return new L.Control.GlobeMiniMap(layer, options);
};
L.Map.mergeOptions({
miniMapControl: false,
});
export default L;
import L from "./leaflet-globeminimap";
const map = L.map(ID, {
zoomControl: false,
maxBounds: bounds,
center: [34, 108],
maxZoom: 21,
minZoom: 4,
zoom: 4,
});
new L.Control.GlobeMiniMap({
land: "#94cf6a",
water: "#3972f7",
marker: "#e44131",
}).addTo(map);