AnStef Posted November 19, 2020 Share Posted November 19, 2020 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) Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted November 19, 2020 Share Posted November 19, 2020 (edited) 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 November 19, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted November 19, 2020 Share Posted November 19, 2020 (edited) 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 November 19, 2020 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted November 19, 2020 Share Posted November 19, 2020 I recommend to open issue at pixijs github anyway. Quote Link to comment Share on other sites More sharing options...
AnStef Posted November 19, 2020 Author Share Posted November 19, 2020 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()? Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.