AnStef

Stalling mouse move events with lower frame rate

Recommended Posts

Hi everybody,

I am working on a browser interface to control audio hardware. The page itself should have the lowest possible impact on the computer's performance, so we manually lowered the render framerate by setting app.ticker.maxFPS and app.ticker.minFPS.

Within the app, we draw graphics using Graphics's bezierCurveTo and such, so we can't use readily shaped graphics like rects. We want those graphics to change their color and the mouse to change its shape when hovering them. But seemingly, whenever the mouse is moved too quickly over the graphic's area, the mouse events come too quickliy for the shape to be rendered completely, this only happens if maxFPS and minFPS are set manually. However, the mouse pointer constantly flickers changing its shape from the arrow to the hand and back while it moves across the graphic's area. Whenever the mouse movement is stopped, the rendering will take place accordingly and the expected behaviour happens: The graphic changes its color. Note, that this only happens while the mouse moves.

I tried setting app.renderer.plugins.interaction.interactionFrequency to avoid the mouse events being fired too often, but it only makes the behaviour growing less predictable.

Is there any way to actually slow down the mouse event frequency? Why does this only happen if I draw shapes using connected lines? Can you think of any way to solve this issue?

Thanks and best wishes,

AnStef

Feel free to test for yourself:

import * as PIXI from 'pixi.js';

const app = new PIXI.Application({
    width: 100,
    height: 100,
});

document.body.appendChild(app.view);

app.ticker.maxFPS = 15;
app.ticker.minFPS = 10;

const graphics = new PIXI.Graphics();
graphics.interactive = true;
graphics.buttonMode = true;

const renderGraphics = (color) => {
    graphics.clear();
    graphics.lineTo(0, 0);
    graphics.lineStyle(1, color);
    graphics.beginFill(color);

    // draw a square using connected lines as minimal example
    graphics.lineTo(100, 0);
    graphics.lineTo(100, 100);
    graphics.lineTo(0, 100);
    graphics.lineTo(0, 0);
};

renderGraphics(0xcccccc);

graphics.on('pointerover', () => renderGraphics(0));

graphics.on('pointerout', () => renderGraphics(0xcccccc));

app.stage.addChild(graphics)

 

Share this post


Link to post
Share on other sites

Last graphicsData shape (square) is not actually added before rendering. Just for this cause, Graphics has "finishPoly()" calls everywhere it matters, like in "render()".  Yes, its a bit strange - we have to close the path when we want to render it, thus in next frame any lineTo() actually starts new one. Apparantly, its missing from "containsPoint" method.

Adding "endFill()" after you created the shape solves the problem.

Alternatively, we can add "finishPoly()" call in containsPoint(), you can even make a PR in pixijs github repo.

Edited by ivan.popelyshev

Share this post


Link to post
Share on other sites

I understand that in general sense its bad idea to change state of graphics based on those calls like getBounds() or render(), and mature frameworks like Flash actually work fine with those cases. But they are closed-source and has many checks because users have all the ideas to break it and ask "wtf guys why didnt you code in case we forgot to close our shape".

Even @eXponeta encountered this problem some time ago in AwayJS - old flash app was calling getBounds() and lineTo() in succession, something like "graphics.lineTo(0, graphics.width)", of course it broke AwayJS , while it worked fine in old Adobe Flash runtime.

Edited by ivan.popelyshev

Share this post


Link to post
Share on other sites

Thanks for your reply!

endFill() works perfectly fine for me, and it makes sense to tell Pixi when to check for the actual shape. I wonder why I didn't think about it even since I've used it before.

However, I don't perfectly understand why you suggested using finishPoly() in containsPoint(). In case somebody would forget to endFill()?

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.