manubb / Leaflet.PixiOverlay

Bring Pixi.js power to Leaflet maps
MIT License
463 stars 85 forks source link

Incorrect position updates on DisplayObjects rendered while not in container #14

Closed icithis closed 6 years ago

icithis commented 6 years ago

I am trying to render a shape to a texture to generate multiple alpha levels on a display object. Using the pixijs.io sandbox as an example, I am able to execute this code.

document.body.appendChild(app.view);
var stage = app.stage;
var container = new PIXI.Container();
app.stage.addChild(container);

var brush = new PIXI.Graphics();
brush.beginFill(0xdddddd);
brush.drawCircle(0, 0, 300);
brush.position.set(app.screen.width / 2, app.screen.height / 2)
brush.endFill();

var brush2 = new PIXI.Graphics();
brush2.beginFill(0x888888);
brush2.drawCircle(0, 0, 200);
brush2.position.set(app.screen.width / 2, app.screen.height / 2)
brush2.endFill();

var rect = new PIXI.Graphics();
rect.beginFill(0xffaa00);
rect.drawRect(0, 0, app.screen.width, app.screen.height);
rect.endFill();

PIXI.loader.add("t1", "required/assets/bkg-grass.jpg")

PIXI.loader.load(setup);

function setup(loader, resources) {
    var background = new PIXI.Sprite(resources["t1"].texture);
    background.width = app.screen.width;
    background.height = app.screen.height;

    var renderTexture = PIXI.RenderTexture.create(app.screen.width, app.screen.height);
    var renderTextureSprite = new PIXI.Sprite(renderTexture);
    rect.mask = renderTextureSprite;
    container.addChild(background, renderTextureSprite, rect);
    app.renderer.render(brush, renderTexture, false, null, false);
    app.renderer.render(brush2, renderTexture, false, null, false);
}

However, when trying to accomplish this in Leaflet, the brush moves independently of the texture, and instead repositions itself based on the window position (move the map to the left and the circle appears and moves as well, with setView([35.935, -84.271], 16) for the map in Leaflet).

      let self = this
      let circleCenter = [35.956, -84.275]

      var loader = new PIXI.loaders.Loader()
      loader.load(function (loader, resources) {
        var pixiContainer = new PIXI.Container()
        var brush = new PIXI.Graphics()
        var rect = new PIXI.Graphics()
        var projectedBrush

        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

          if (firstDraw) {
            projectedBrush = project(circleCenter)
          }

          let always = true
          if (firstDraw || prevZoom !== zoom || always) {
            brush.clear()
            brush.beginFill(0x555555)
            brush.drawCircle(0, 0, 500)
            brush.x = 0
            brush.y = 0
            brush.endFill()

            var renderTexture = PIXI.RenderTexture.create($(window).width(), $(window).height())
            var renderTextureSprite = new PIXI.Sprite(renderTexture)
            console.log(renderTextureSprite)

            rect.beginFill(0xffaa00)
            rect.drawRect(projectedBrush.x, projectedBrush.y, $(window).width(), $(window).height())
            rect.endFill()
            rect.mask = renderTextureSprite

            container.addChild(rect)
          }
          renderer.render(brush, renderTexture, false, null, false)
          renderer.render(container)

          firstDraw = false
          prevZoom = zoom
        }, pixiContainer)
        pixiOverlay.addTo(self.map)
      })
manubb commented 6 years ago

Sorry but i do not understand what you are doing. What do you want to display on your map? Can you describe precisely your target?

icithis commented 6 years ago

Here is a fiddle of the pixi code. https://jsfiddle.net/FoomFries/bhmL2zrf/17/

I cannot get renderer.render(brush, renderTexture) to work with your leaflet container. I would like to display this fiddle on the map.

Edit: Here is a codepen of the issue. Moving the map causes the circle to move, which it shouldn't based on my understanding. https://codepen.io/foom/pen/XEVydE

icithis commented 6 years ago

It seems the order in which I was doing things was incorrect, and has nothing to do with the Leaflet.PixiOverlay wrapper. Working version with texture renders and masking - albeit a bit messy - is this codepen.

manubb commented 6 years ago

You can find a simplified version of your codepen test here and a version with similar rendering that does not use masks here.