传单上的 PixiOverlay,无法添加另一张图片,因为它已经有一个条目

PixiOverlay on leaflet, cant add another image because it is already had an entry

我在传单上使用 Pixi 和 PixiOverlay。我有以下 jsfiddle 用于虚拟模拟。 objective:单击“添加图片 2”后,它会在地图上随机添加一张仓鼠图片。

它(几乎)有效。

问题:

错误信息:"BaseTexture added to the cache with an id [hamster] that already had an entry"

我想不出我们应该把加载器放在哪里以及如何在代码组织方面正确地集成它:(我只需要使用它一次吗?)如果我要添加其他层怎么办?所以我认为我的挑战就在这里:

this.loader.load((loader, resources) => {...}

小技巧:如何缩小仓鼠的体积:-)

我的JS代码(也在jsfiddle上)

class Simulation
{
    constructor()
    {
          // center of the map
    var center = [1.8650,  51.2094];

    // Create the map
    this.map = L.map('map').setView(center, 2);

    // Set up the OSM layer
    L.tileLayer(
      'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 18
      }).addTo(this.map);
    
    this.imagesLayer = new L.layerGroup(); 
    this.imagesLayer.addTo(this.map);
    
    
}

_getRandomCoord()
{
        var randLat = Math.floor(Math.random() * 90);
        randLat *=  Math.round(Math.random()) ? 1 : -1;

    var randLon = Math.floor(Math.random() * 180);
    randLon *=  Math.round(Math.random()) ? 1 : -1;
    
    return [randLat,randLon]
}

addImage2()
{
                
    this.loader = new PIXI.Loader()
    this.loader.add('hamster', 'https://cdn-icons-png.flaticon.com/512/196/196817.png')
    this.loader.load((loader, resources) => {
    
        let markerTexture = resources.hamster.texture
        let markerLatLng = this._getRandomCoord()
        let marker = new PIXI.Sprite(markerTexture)
        marker.anchor.set(0.5, 1)

        let pixiContainer = new PIXI.Container()
        pixiContainer.addChild(marker)

        let firstDraw = true
        let prevZoom

        let pixiOverlay = L.pixiOverlay(utils => {
          let zoom = utils.getMap().getZoom()
          let container = utils.getContainer()
          let renderer = utils.getRenderer()
          let project = utils.latLngToLayerPoint
          let scale = utils.getScale()

          if (firstDraw) {
            let markerCoords = project(markerLatLng)
            marker.x = markerCoords.x
            marker.y = markerCoords.y
          }

          if (firstDraw || prevZoom !== zoom) {
            marker.scale.set(1 / scale)
          }

          firstDraw = true
          prevZoom = zoom
          renderer.render(container)
        }, pixiContainer)

        this.imagesLayer.addLayer(pixiOverlay);
  })
}   

addTriangle()
{
            console.log("Trinalge")   
    var polygonLatLngs = [
        [51.509, -0.08],
        [51.503, -0.06],
        [51.51, -15.047],
        [21.509, -0.08]
    ];
    var projectedPolygon;
    var triangle = new PIXI.Graphics();

    var pixiContainer = new PIXI.Container();
    pixiContainer.addChild(triangle);

    var firstDraw = true;
    var prevZoom;

    var pixiOverlay = L.pixiOverlay(function(utils) {
        var zoom = utils.getMap().getZoom();
        var container = utils.getContainer();
        var renderer = utils.getRenderer();
        var project = utils.latLngToLayerPoint;
        var scale = utils.getScale();

        if (firstDraw) {
            projectedPolygon = polygonLatLngs.map(function(coords) {return project(coords);});
        }
        if (firstDraw || prevZoom !== zoom) {
            triangle.clear();
            triangle.lineStyle(3 / scale, 0x3388ff, 1);
            triangle.beginFill(0x3388ff, 0.2);
            projectedPolygon.forEach(function(coords, index) {
                if (index == 0) triangle.moveTo(coords.x, coords.y);
                else triangle.lineTo(coords.x, coords.y);
            });
            triangle.endFill();
        }
        firstDraw = false;
        prevZoom = zoom;
        renderer.render(container);
    }.bind(this), pixiContainer);
    
            this.imagesLayer.addLayer(pixiOverlay)
}
    
removeLayer()
{
            this.imagesLayer.clearLayers();
}   
}

var simulation = new Simulation();

TLDR:更新了 jsfiddle:

https://jsfiddle.net/gbsdfm97/

更多信息如下:

第一个问题:加载资源(贴图)

控制台出现错误,因为您在每次点击时都加载了仓鼠图像:

    addImage2()
    {
                    
        this.loader = new PIXI.Loader()
        this.loader.add('hamster', 'https://cdn-icons-png.flaticon.com/512/196/196817.png')
        this.loader.load((loader, resources) => {
        ...

更好的方法是在开始时加载一次图像(资源),然后重新使用内存中加载的内容:

    constructor()
    {
...
        
        this.markerTexture = null;
        this._loadPixiResources();
    }
    
...
    
    _loadPixiResources()
    {
        this.loader = new PIXI.Loader()
        this.loader.add('hamster', 'https://cdn-icons-png.flaticon.com/512/196/196817.png')
        this.loader.load((loader, resources) => {
            this.markerTexture = resources.hamster.texture;
      })
    }

...
    
    addImage2()
    {
        ...
        let marker = new PIXI.Sprite(this.markerTexture);

第二个问题:仓鼠的大小:)

比例设置如下:

marker.scale.set(1 / scale)

哪个太大 - 所以将其更改为:

// affects size of hamsters:
this.scaleFactor = 0.05;
...
marker.scale.set(this.scaleFactor / scale);

仓鼠的比例(不是三角形!)现在会在缩放更改时更新 - 所以当用户使用鼠标滚轮等时。

问题三:pixiOverlay层数过多

之前每次点击 Add Image 2Add Triangle 按钮都会添加新的 pixiContainer 和新的 pixiOverlay,它们被添加为新层:this.imagesLayer.addLayer(pixiOverlay);

新版本简化了一点:开头只创建了一个pixiContainer和一个pixiOverlay

    constructor()
    {
        ...
        
        // Create one Pixi container for pixiOverlay in which we will keep hamsters and triangles:
        this.pixiContainer = new PIXI.Container();
        
        let prevZoom;
        
        // Create one pixiOverlay:
        this.pixiOverlay = L.pixiOverlay((utils, data) => {
          ...
        }, this.pixiContainer)

        this.imagesLayer.addLayer(this.pixiOverlay);
    }
  • this.pixiOverlay作为一层添加
  • 然后在程序的其余部分我们重复使用 this.pixiOverlay
  • 我们也重用 this.pixiContainer 因为它是从 utils 返回的 - 参见:
let container = utils.getContainer()  // <-- this is our "this.pixiContainer"
...
container.addChild(marker)
renderer.render(container)

奖金:三角形

现在您可以添加许多三角形 - 每次点击一个。

注意:三角形不会改变比例 - 这是与仓鼠的区别。