Gui.animate slowly going out of sync!

Hi!
I’m animating the X and Y positions of several gui nodes (labels) using gui.animate. They are slowly going out of sync (it’s a looped anim)


Screenshot 2022-11-25 at 19.29.35

	local number = 8
local xdis = 200
local ydis = 30
local spread = 0.1
local time = 4

local table = {
	10,9,8,8,5,
	10,10,10
}
for i = 1,number do
	local node = gui.get_node("text"..i)

	gui.set_position(node, vmath.vector3(-xdis, ydis, 0))
	local accum = 0
	for n = 1, i do
		accum = accum + (table[n]/100)
	end
	gui.set_color(node, vmath.vector4(0,0,0,0))
	gui.animate(node, "color.w", 1, gui.EASING_INOUTQUAD, time, accum+(time/4), nil, gui.PLAYBACK_LOOP_PINGPONG)
	gui.animate(node, "position.x", xdis, gui.EASING_INOUTSINE, time, accum, nil, gui.PLAYBACK_LOOP_PINGPONG)
	gui.animate(node, "position.y", -ydis, gui.EASING_INOUTSINE, time, accum+(time/4), nil, gui.PLAYBACK_LOOP_PINGPONG)
end
timer.delay(0.2, true, function(self) 
	for i = 1,number do
		local node = gui.get_node("text"..i)
		local pos = gui.get_position(node)
		if pos.y > 0 then
			gui.set_layer(node, "behind")
		else
			gui.set_layer(node, "infront")
		end
	end
end)

Any help? Would I get any benefit from using a timer and repeating gui.animate instead of using the Pingpong loop?

thanks.

fixed this by writing my own animation in update. Is this very inefficient? Is there anyway I can make it more efficient? Is there a fixed update so it only happens e.g. 30 times a second?

function update(self, dt)
self.count = self.count+0.02
for i = 1,9 do
	local node = gui.get_node("text"..i)
	local xpos = math.sin((self.count+(self.offsets[i]/8)))*self.xdis
	local ypos =  math.cos((self.count+(self.offsets[i]/8)))*-self.ydis
	gui.set_position(node, vmath.vector3(xpos, ypos, 0))
	if ypos < 0 then
		gui.set_layer(node, "infront")
	else
		gui.set_layer(node, "behind")
	end
end

end

finished product!

2 Likes

Good to see that you solved it, but it would be interesting to dig in and try to figure out why the animation went out of sync…

You animate them differently?
I don’t think that your two code snippets are equivalent.
In your first code snippets, it delays the Y component an extra time/4 which is 1 second.

In your second example, you have no such extra delay.

In the second example, i use math.sin on the xpos and math.cos on the ypos, so that when x.pos is at 0% (or 100%), y.pos is at 50%.

In the first example, I have to start the ypos animation after the xpos animation is at exactly one quarter of the way through its ping pong loop, but the maths is the same.

It’s possible that the y animation also suffers from a less noticeable sync problem, but you can see here that it’s the xpos that is noticeable suffering (each letter is a label of its own)

2 Likes