Jump to content

Need help on Pixi demo spinner


Azern
 Share

Recommended Posts

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)image.thumb.png.ab5c93232ee0b62b46094c3a7e26df9c.png



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 by Azern
changes for better word
Link to comment
Share on other sites

  • Azern changed the title to Need help on Pixi demo spinner

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 by Exca
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by Azern
Link to comment
Share on other sites

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 by Exca
Link to comment
Share on other sites

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.

Link to comment
Share on other sites

  • 2 years later...

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...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...