lTyl

PIXI positioning + flickering questions

8 posts in this topic

Hey there,

I am building a Gantt chart using PIXI.JS, and have some miscellaneous questions regarding some unexpected behavior I am seeing with the outputted render.

1.) I experience flickering when applying a linear zoom (Changing the scale property with the mouse wheel). The GIF below shows the issue.

flickering.thumb.gif.ba9635208a69ce7efebfc2583314d901.gif

Here is the zoom code:

function zoom(factor) {
   var newScale = self.zoom.scale * factor;
	// Clamp the scaling
   if (newScale > self.zoom.max) { self.zoom.scale = self.zoom.max; return;}
   else if (newScale < self.zoom.min) { self.zoom.scale = self.zoom.min; return; }
   // Stops an error when you change state inbetween frame draws
   if (!self.renderer || !self.renderer.plugins){return}
   var mouse = self.renderer.plugins.interaction.eventData.data.global;
   self.zoomLayers.forEach(function(layer, idx){
      layer.scale.x *= factor;
      layer.scale.y *= factor;
      self.zoom.scale = layer.scale.x;
      layer.x -= (mouse.x - layer.x) * (factor - 1);
      layer.y -= (mouse.y - layer.y) * (factor - 1);
   });
   self.emitter.emit('zoom', {pointer: mouse, event: e, factor: factor});
}
var remaining, lastTime;
function calcZoom() {
   var time = Date.now();
   var delta = time - lastTime;
   lastTime = time;
   var step = Math.pow(remaining, delta/100);
   remaining /= step;
   zoom(step);
   if (Math.abs(remaining - 1) < change) {
      zoom(remaining);
      remaining = 1;
      zooming = false;
   } else {
      requestAnimationFrame(calcZoom);
   }
}

If it helps, my stage is set-up like this. LayerManager is simply a thin wrapper which creates a new PIXI.Container(), and tracks them by name:

this.layerManager.getLayerByName('underlay').addChild(this.lineContainer);
this.layerManager.getLayerByName('main').addChild(this.layerManager.getLayerByName('surface'));

// Add the renderer layer to stage
this.stage.addChild(this.layerManager.getLayerByName('underlay'));
this.stage.addChild(this.layerManager.getLayerByName('details'));
this.stage.addChild(this.layerManager.getLayerByName('main'));

The layer which has ‘zoom’ applied is the ‘main’ layer. The lines that are flickering are being drawn with PIXI.Graphics. The line is being added to the ‘details’ layer:

var line = new PIXI.Graphics();
this.draw = function(sx, sy, dx, dy){
   line.moveTo(sx, sy);
   line.lineTo(dx, dy);
   return line;
};

Any idea why I am seeing this flickering with these simple lines, and steps on how to mitigate the problem? Ideally, I would like the horizontal lines to remain relatively static.

 

2.) When refreshing the render (Such as when the data model changes and an event is dispatched), I clear the individual bar and then re-draw with the new data. This works fine UNLESS the view window has been zoomed or panned; in which case the new bars are drawn with an offset that correlates to the amount I have zoomed in/out on the plan.

I am calculating the X and Y like so:

var shape = new PIXI.Graphics();
var completePoint = shape.toLocal(new PIXI.Point(data.completeX, displayNode.y));
var incompletePoint = shape.toLocal(new PIXI.Point(data.incompleteX, displayNode.y));
shape.drawRect(completePoint.x, completePoint.y, width, height);
shape.drawRect(incompletePoint.x, incompletePoint.y, width, height);

displayNode is the parent DisplayObject. data.completeX/data.incompleteX is the GLOBAL X draw position. The shape is added as a child to the displayNode. The displayNode is added to the ‘surface’ layer. The gist of it is it appears toLocal is not recursively factoring in the position of all of the parents. My display node graph should look like this:

Stage -> Main (PIXI.Container) -> Surface (PIXI.Container) -> displayNode (PIXI.Graphics) -> shape (PIXI.Graphics)

before-refresh.PNG.dca42ad3e4d3c4c6f42c46711c8eb03f.PNG

^ Everything is drawing with correct positioning.

after-refresh.thumb.PNG.8eabfb98a6e3a58c341d31d96f012363.PNG

^ ‘Floor 1’ updated; expect to see it drawn similar to the former image, but with a higher width. Notice how the greenbar is drawn with a small Y offset and a very large X offset? Why is that?

 

Do any PIXI experts here have any insights they could provide to help me solve these two problems?

 

Thanks!

Share this post


Link to post
Share on other sites

I need to know exact version of your pixijs, try to update to latest.

The next thing we can try:

renderer = new PIXI.WebGLRenderer(width, height, {antialias:true});

And the next thing:

graphics = new PIXI.Graphics(true);

 

Share this post


Link to post
Share on other sites

Thanks for the reply! I am currently using version 4.5.1. Updating to 4.5.2 has no change for my two issues above.

I am doing this to initialize PIXI:

this.app = new PIXI.Application(renderOptions.width || 100, renderOptions.height || 100, renderOptions);		
this.renderer = this.app.renderer;
this.stage = this.app.stage;
this.view = this.app.view;

renderOptions has an 'antialias' property and the value is true. Using new PIXI.WebGLRenderer causes all of my interaction functionality to break, because the renderer isn't linked up to the PIXI Ticker (I'm assuming...).

var line = new PIXI.Graphics(true);

^ Has provided no improvement to the flickering I am experiencing. It has actually made the flickering worse and more prevalent.

Share this post


Link to post
Share on other sites

Does anyone else have tricks or ideas I could try to remove/reduce the amount of flickering as shown in the OP? Or any ideas on why the positions are off when re-drawing and using toLocal to calculate the relative draw position? Much appreciated~

Share this post


Link to post
Share on other sites

If you are referring to the resolution property, using a value of 1 or a value >1 still has the same unwanted flickering.

EDIT: I had a thought where maybe my use of requestAnimationFrame instead of the Application ticker is why I was experiencing the flickering on scale change. I re-wrote the zoom to use the ticker: this.ticker.add(this.renderSmoothZoom, this, PIXI.UPDATE_PRIORITY.HIGH);

After the edit, I am still experiencing the flickering. I suspect it is a relatively minor issue that I am overlooking...

Edited by lTyl

Share this post


Link to post
Share on other sites

I received an email reply asking for a fiddle. Here is one showing the flickering issue. Simply use the mouse wheel and zoom out; flickering should start happening (I'm on latest Chrome)

https://jsfiddle.net/744o680r/4/

I am drawing the graphics once and then scaling. I am using PIXI.Application and handling my zoom in a function, which is then added to PIXI.ticker with a HIGH update priority. In my application, I re-draw the graphics when one of the following is true: the widget window is resized or the browser window is resized. When a tracked data model is updated, then I re-draw only the changed graphic represented by that data model.

 

@OSUblake: Thank you for the link! It is definitely relevant to my needs and I shall peruse.

 

EDIT: Argh. @ivan.popelyshev had it right.

graphics = new PIXI.Graphics(true);

Enabling native lines made the annoying flickering go away. I could've sworn I tried his suggestion earlier...my bad <_<. Thanks for the assistance everyone!

ivan.popelyshev likes this

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.