Azern Posted May 24, 2021 Share Posted May 24, 2021 (edited) Hello, I need some help of the demo displayed on this page.https://pixijs.io/examples/#/demos-advanced/spinners.js (Latest development version, maybe it's 6.0.2 at the moment) They called it spinner, and I want to make something like the third spinner since I want to make a sort of a button that will complete upon a certain duration. But I can't understand what the codes written are for. I don't need the explanation of all other, just for the third spinner. Edited May 24, 2021 by Azern changes for better word Quote Link to comment Share on other sites More sharing options...
Exca Posted May 25, 2021 Share Posted May 25, 2021 (edited) Hi, I'm the one who made that example. The basic functionaly for each spinner is in their generation function and they return a function that updates that spinner. Here's a more detailed descriptin without any overhead related to other spinners. // Crete the app const app = new PIXI.Application({ backgroundColor: 0x1099bb }); document.body.appendChild(app.view); // Create a container for the stage. const container = new PIXI.Container(); app.stage.addChild(container); // Create the sprite that gets masked out. const base = PIXI.Sprite.from('examples/assets/bg_scene_rotate.jpg'); // Resize the sprite to a fixed one. This step could be skipped and you could just use it as is. const size = 100; base.width = size; base.height = size; // Create a mask and set it to center of the base sprite. const mask = new PIXI.Graphics(); mask.position.set(size / 2, size / 2); base.mask = mask; // Add the sprite & mask to container. container.addChild(base); container.addChild(mask); let phase = 0; // Function to redraw the mask. function update(delta){ // Update phase. Phase in this example is from 0 to Pi*2 (full circle). phase += delta / 60; // If phase is over Pi*2, go back to 0 to restart animation. phase %= (Math.PI * 2); // Offset the starting angle to point up instead of right. const angleStart = 0 - Math.PI / 2; // Angle to calculate with is the phase + starting angle. const angle = phase + angleStart; // Half of the size as radius. const radius = size/2; // Calculate a position on the circle at the starting angle. const x1 = Math.cos(angleStart) * radius; const y1 = Math.sin(angleStart) * radius; // Clear old graphics mask.clear(); // Set linestyle to 2, this is only for debug purposes, could be omitted. mask.lineStyle(2, 0xff0000, 1); // Start filling the mask. mask.beginFill(0xff0000, 1); // Start rendering from center. mask.moveTo(0, 0); // First draw line to starting angle. mask.lineTo(x1, y1); // Then draw an arc from starting angle to current angle. mask.arc(0, 0, radius, angleStart, angle, false); // Finally go back to center to complete the polygon. mask.lineTo(0, 0); // End filling. mask.endFill(); } // Listen to ticker updates. app.ticker.add( (delta) => { update(delta); }); Hopefully this helps. Edited May 25, 2021 by Exca ivan.popelyshev and Azern 2 Quote Link to comment Share on other sites More sharing options...
Azern Posted May 26, 2021 Author Share Posted May 26, 2021 17 hours ago, Exca said: Hi, I'm the one who made that example. The basic functionaly for each spinner is in their generation function and they return a function that updates that spinner. Here's a more detailed descriptin without any overhead related to other spinners. // Crete the app const app = new PIXI.Application({ backgroundColor: 0x1099bb }); document.body.appendChild(app.view); // Create a container for the stage. const container = new PIXI.Container(); app.stage.addChild(container); // Create the sprite that gets masked out. const base = PIXI.Sprite.from('examples/assets/bg_scene_rotate.jpg'); // Resize the sprite to a fixed one. This step could be skipped and you could just use it as is. const size = 100; base.width = size; base.height = size; // Create a mask and set it to center of the base sprite. const mask = new PIXI.Graphics(); mask.position.set(size / 2, size / 2); base.mask = mask; // Add the sprite & mask to container. container.addChild(base); container.addChild(mask); let phase = 0; // Function to redraw the mask. function update(delta){ // Update phase. Phase in this example is from 0 to Pi*2 (full circle). phase += delta / 60; // If phase is over Pi*2, go back to 0 to restart animation. phase %= (Math.PI * 2); // Offset the starting angle to point up instead of right. const angleStart = 0 - Math.PI / 2; // Angle to calculate with is the phase + starting angle. const angle = phase + angleStart; // Half of the size as radius. const radius = size/2; // Calculate a position on the circle at the starting angle. const x1 = Math.cos(angleStart) * radius; const y1 = Math.sin(angleStart) * radius; // Clear old graphics mask.clear(); // Set linestyle to 2, this is only for debug purposes, could be omitted. mask.lineStyle(2, 0xff0000, 1); // Start filling the mask. mask.beginFill(0xff0000, 1); // Start rendering from center. mask.moveTo(0, 0); // First draw line to starting angle. mask.lineTo(x1, y1); // Then draw an arc from starting angle to current angle. mask.arc(0, 0, radius, angleStart, angle, false); // Finally go back to center to complete the polygon. mask.lineTo(0, 0); // End filling. mask.endFill(); } // Listen to ticker updates. app.ticker.add( (delta) => { update(delta); }); Hopefully this helps. Thanks you so much for explaining and shorten them all. I still don't know what "delta" supposed to do since it appears on many tutorials but I never use that string. Anyway, what I can tell is, each update the mask is drawn back and forth from the center to the radius end following the arc. Once again, thank you so much for shortening that demo page. It is easier to read now. Quote Link to comment Share on other sites More sharing options...
Exca Posted May 26, 2021 Share Posted May 26, 2021 Delta is the numeric normalized value on how much time has passed since the last frame. Let's say your target FPS is 60 and rendering a frame takes 50ms then your delta would be 50/16.66 = 3.001. To keep everything going as fast as the intended timing then that value is used in calculations and everything updates at the same speed even if frames rendered is 3 times less. You could also just ignore delta and update with a fixed amount, then on slow computer then the animations etc. would just take longer if no delta calculations was done. There's a lot of solutions on how to handle timing differences in gameplay/rendering, but the delta calculations are the simplest. Azern 1 Quote Link to comment Share on other sites More sharing options...
Azern Posted May 26, 2021 Author Share Posted May 26, 2021 4 hours ago, Exca said: Delta is the numeric normalized value on how much time has passed since the last frame. Let's say your target FPS is 60 and rendering a frame takes 50ms then your delta would be 50/16.66 = 3.001. To keep everything going as fast as the intended timing then that value is used in calculations and everything updates at the same speed even if frames rendered is 3 times less. You could also just ignore delta and update with a fixed amount, then on slow computer then the animations etc. would just take longer if no delta calculations was done. There's a lot of solutions on how to handle timing differences in gameplay/rendering, but the delta calculations are the simplest. So you can just type in "delta" without declaring it as any number before? Like this? // Listen to ticker updates. app.ticker.add( (delta) => { update(delta); }); Sorry if this question sound stupid. I'm just so used to using random string as parameters and declared it with some value before. Quote Link to comment Share on other sites More sharing options...
Exca Posted May 26, 2021 Share Posted May 26, 2021 That row uses arrow-syntax to declare a function. You could also write: app.ticker.add( function(delta){ update(delta); }); So the delta is a variable that has been declared in the functions parameter listing. And the parameter that apps ticker passes to the given function is a number. You could also do something like this which might make it clearer: function renderLoop( delta ){ update(delta); // Do something else you want to do per frame. } app.ticker.add( renderLoop ); You just need to be a bit carefull when doing class/object based programming with the functions scope. Arrow functions are always bound (this in callback function refers to same as this outside of it) to the scope they are initialiazed in. Regular functions on the other hand have their scope determined by how they are called. Quote Link to comment Share on other sites More sharing options...
Azern Posted May 26, 2021 Author Share Posted May 26, 2021 (edited) function renderLoop( delta ){ update(delta); // Do something else you want to do per frame. } app.ticker.add( renderLoop ); Okay, that's easier to read. the app.ticker will update the renderLoop, which have update(delta) inside. But what's the difference between putting the "delta" as a parameter in that function vs not putting any parameter at all? because I had this running as my loop // ticker.speed = 2 // ticker.deltaMS = 1 ticker.add(function () { renderer.render(mainview) looptest() }) ticker.start() and it always run at 60fps. that commented part is when I try to run the update to 120fps but nothing changed, so I just comment it instead of deleting it. It still update to 60fps. - Is it because my monitor that capped to 60fps so it's only updating to 60fps? - Is adding the "delta" will make the changes? Edited May 26, 2021 by Azern Quote Link to comment Share on other sites More sharing options...
Exca Posted May 26, 2021 Share Posted May 26, 2021 (edited) The delta part there tells how much your rendering differs from the target. I don't currently remember how the default pixi ticker works in relation to that (I use a custom ticker). When your computer has enough processing power to handle solid 60 fps (default target in pixi and also the time browser does requestAnimationFrame on a 60 hz monitor) then having delta or just skipping it makes no difference. But if you were running the program on a very slow computer that could render only at 30 fps then the renderloop would be called only 30 times in second compared to previous 60 times. So all your updates would advance only 30 times instead of the 60. For example if you had a sprite that was spinning with rotation+=1 in every update. Then on pc running with 30 frames per second it would move 30 radians during a second where as the other fullspeed rendering would rotate 60 radians. And if you had a 144hz monitor where the requestAnimationFrame might be called 144 times a second then that would be much faster. The delta value in the trigger measures how much time has passed since your last render and calculates a normalized delta value (normalzied into target fps) based on that. So with 30fps the delta would be 2 and your rotation update would be rotation+=1*delta -> 60 radians in a second. Then with 144hz rendering it would 60/144=0.41666 and thus the rotation would be called 144 times with rotation+=1*0.41666 -> 60 radians in a second. Basically the delta tells you how much your previous frame was off from the target fps. The target fps in pixi v6 is set into settings.TARGET_FPMS (how many frames should be rendered in milliseconds, so 60/1000 is the default). The target fps does not affect how many times your program gets the render call, as that is determined by the browser and is something that cannot be changed by the developer. Though there are frame skip methods to emulate lower fps rendering. [Edit] Here's an article that goes into a bit more detail with images about frames deltatime https://gamedevunboxed.com/understanding-delta-time/ Edited May 26, 2021 by Exca Azern 1 Quote Link to comment Share on other sites More sharing options...
Azern Posted May 26, 2021 Author Share Posted May 26, 2021 so adding the delta just to make sure that the animation is framerate independent. making the animation stick to time instead of number of frames. and the problem about 60fps is just browser things, nothing wrong with my code Thank you so much for answering all of my question these far. Quote Link to comment Share on other sites More sharing options...
Gagandeep Singh Posted July 20, 2023 Share Posted July 20, 2023 Hi, can anyone confirm what changes I need to do to the above code so that it complete the full cycle in 5 seconds and also for 15 seconds. Thanks in the advance. 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.