Thread Tools Display Modes
01-26-10, 02:51 PM   #1
Amenity
Guest
Posts: n/a
"Pulsating" effect...what's the proper method?

I have frame "frame". I want it to fade from alpha "1" to alpha "0", then back to alpha "1" and repeat until I say otherwise to make a "pulsing" effect.

I tried doing this in a manner like so, and...well...yeah, infinite loops are bad.

lua Code:
  1. while myvariable = 1 do
  2.     alpha = frame:GetAlpha()
  3.     if alpha = 1 then
  4.         UIFrameFadeOut(frame, 1, 1, 0)
  5.     elseif alpha = 0 then
  6.         UIFrameFadeIn(frame, 1, 0, 1)

Hello, Mr. Client Crash.
  Reply With Quote
01-26-10, 02:58 PM   #2
d87
A Chromatic Dragonspawn
 
d87's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2006
Posts: 163
Post

Code:
local SHINE_FADE_IN = 0.15;
local SHINE_FADE_OUT = 0.15;
local TICK_PERIOD = 0.35;

local ShineFadeOut = function(frame)
    local fadeInfo = {};
        fadeInfo.mode = "OUT";
        fadeInfo.timeToFade = SHINE_FADE_OUT;
        fadeInfo.finishedFunc = function(self) self.animating = false end;
        fadeInfo.finishedArg1 = frame;
    UIFrameFade(frame, fadeInfo);
end
local ShineFadeIn = function(frame)
    if not frame.animating then
        local fadeInfo = {};
        fadeInfo.mode = "IN";
        fadeInfo.timeToFade = SHINE_FADE_IN;
        fadeInfo.finishedFunc = function(arg1) ShineFadeOut(arg1); end;
        fadeInfo.finishedArg1 = frame;
        frame.animating = true
        UIFrameFade(frame, fadeInfo);
    end
end

f.Shine = function(self)
        ShineFadeIn(self.shinetex)
    end

f.OnUpdate = function (self, time)
        self.OnUpdateCounter = (self.OnUpdateCounter or 0) + time
        if self.OnUpdateCounter < TICK_PERIOD then return end
        self.OnUpdateCounter = 0
        
        self:Shine()
    end
  Reply With Quote
01-26-10, 03:00 PM   #3
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,892
Well did a quick search and there isn't much around on that subject so perhaps they hit a wall.

So far all I have seen is people utilising it on Enter and Leave scripts to do the different Fading functions. So how about this.

If you have an Update function that you call every so often perhaps you can put it in there to fadein if it has faded out or to fade out if it has faded in. Then keep a variable to store the last value updated. It's not perfect but might be the only way you can deal with it and even throwing the cycle in every event you watch may be a good idea too. The combination of the two functions may be enough to make it look passable at least.


Edit: Or what d87 said
__________________
  Reply With Quote
01-26-10, 03:16 PM   #4
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Pretty elegant IMO:
lua Code:
  1. frame.mult = 1
  2. frame.alpha = 1
  3. frame:SetScript("OnUpdate", function(self, elapsed)
  4.     self:SetAlpha(self.alpha)
  5.     self.alpha = self.alpha - elapsed*self.mult
  6.     if self.alpha < 0 and self.mult > 0 then
  7.         self.mult = self.mult*-1
  8.         self.alpha = 0
  9.     elseif self.alpha > 1 and frame.mult < 1 then
  10.         self.mult = self.mult*-1
  11.     end
  12. end)
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
01-26-10, 03:32 PM   #5
Xrystal
nUI Maintainer
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,892
*book marks post so I can come back and ste... erm I mean utilise the code*

Originally Posted by nightcracker View Post
Pretty elegant IMO:
lua Code:
  1. frame.mult = 1
  2. frame.alpha = 1
  3. frame:SetScript("OnUpdate", function(self, elapsed)
  4.     self:SetAlpha(self.alpha)
  5.     self.alpha = self.alpha - elapsed*self.mult
  6.     if self.alpha < 0 and self.mult > 0 then
  7.         self.mult = self.mult*-1
  8.         self.alpha = 0
  9.     elseif self.alpha > 1 and frame.mult < 1 then
  10.         self.mult = self.mult*-1
  11.     end
  12. end)
__________________
  Reply With Quote
01-26-10, 03:39 PM   #6
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
You'll want to hide the frame doing the OnUpdate when it's done, else you'll be needlessly using CPU.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
01-26-10, 03:42 PM   #7
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Originally Posted by Xrystal View Post
*book marks post so I can come back and ste... erm I mean utilise the code*
Feel free to use it(I'm pretty amazed I came up with the mult*-1 trick lol).
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
01-26-10, 03:46 PM   #8
Amenity
Guest
Posts: n/a
Originally Posted by nightcracker View Post
Feel free to use it(I'm pretty amazed I came up with the mult*-1 trick lol).
Wow guys...thank you for the quick responses! Working perfectly now.

(Also bookmarking as a reference page)
  Reply With Quote
01-26-10, 03:55 PM   #9
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Originally Posted by Amenity View Post
Wow guys...thank you for the quick responses! Working perfectly now.

(Also bookmarking as a reference page)
If this is going to be a reference, then I'll add something new, a variable to determine speed of the pulse in seconds(don't set it to 0, dividing by 0 FTW):

lua Code:
  1. local speed = 1
  2. frame.mult = 1
  3. frame.alpha = 1
  4. frame:SetScript("OnUpdate", function(self, elapsed)
  5.     elapsed = elapsed*(1/speed)
  6.     self:SetAlpha(self.alpha)
  7.     self.alpha = self.alpha - elapsed*self.mult
  8.     if self.alpha < 0 and self.mult > 0 then
  9.         self.mult = self.mult*-1
  10.         self.alpha = 0
  11.     elseif self.alpha > 1 and frame.mult < 1 then
  12.         self.mult = self.mult*-1
  13.     end
  14. end)
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
02-05-10, 12:01 PM   #10
Nemnacill
A Kobold Labourer
AddOn Author - Click to view addons
Join Date: Dec 2005
Posts: 1
I'm not sure about how it would work in lua, but any pulsating effect can be achieved with a simple sinus function.

pseudo code:
var sequence = 0;
sequence ++;
AlphaProperty = sin(sequence);

this would result in the AlphaProperty going from 0 to 1, then from 1 to 0 and so on. google 'math sin lua' for more info

Good luck
  Reply With Quote
02-05-10, 01:01 PM   #11
Hati-EK
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 20
http://www.wowwiki.com/API_UIFrameFlash

UIFrameFlash(frame, fadeInTime, fadeOutTime, flashDuration, showWhenDone, flashInHoldTime, flashOutHoldTime)

if you call it more than once(while it's active) - you'll need something that blocks this calls: (atleast for UIFrameFadeIn it makes it nearly go to infinite time - if called unnecessary times (even if you use :GetAlpha()) - you would need something like spareTime=totaltime-(GetAlpha()/totaltime))

(Note this is for UIFrameFadeIn, and not UIFrameFlash)
Code:
local fade_in = {}
local fade_out= {}

--improved UIFrameFadeIn(frame,time,startAlpha,endAlpha,~type)
function lib:UIFrameFadeIn(frame,t,startAlpha,endAlpha,typ)
	local now=GetTime()
	local fname = frame:GetName()
	if typ=='in' then
		local IsInTable,num = self:inTable(fname,fade_in)
		if not IsInTable then
			UIFrameFadeIn(frame,t,startAlpha,endAlpha)
			--tinsert(frame,{icon_name,endTime})
			tinsert(fade_in,{fname,GetTime()+t})
		else
			if now>fade_in[num][2] then
				tremove(fade_in,num)
			end
		end
	elseif typ=='out' then
		local IsInTable,num = self:inTable(fname,fade_out)
		if not IsInTable then
			UIFrameFadeIn(frame,t,startAlpha,endAlpha)
			tinsert(fade_out,{fname,GetTime()+t})
		else
			if now>fade_in[num][2] then
				tremove(fade_out,num)
			end
		end
	end
end
source: LibCooldownIcons-1.0
(Note inTable returns boolean,index of value in table(numeric))

dunno if you can 'calculate' the Pulse-time or want to fix it to some number

Last edited by Hati-EK : 02-05-10 at 08:03 PM.
  Reply With Quote
02-06-10, 12:25 AM   #12
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Originally Posted by Nemnacill View Post
I'm not sure about how it would work in lua, but any pulsating effect can be achieved with a simple sinus function.

pseudo code:
var sequence = 0;
sequence ++;
AlphaProperty = sin(sequence);

this would result in the AlphaProperty going from 0 to 1, then from 1 to 0 and so on. google 'math sin lua' for more info

Good luck
True, but that would require an onupdate function. And an onupdate function gets called at every frame. So if you run at 120 FPS your calling a sin function 120 times per second. Not that efficient as running my way(look above).
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
02-06-10, 02:59 AM   #13
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by nightcracker View Post
<snip>So if you run at 120 FPS your calling a sin function 120 times per second.<snip>
Not true.

Code:
do
	local last_update = 0
	local updater = CreateFrame("Frame", nil, UIParent)

	updater:Hide()
	updater:SetScript("OnUpdate",
			  function(self, elapsed)
				  last_update = last_update + elapsed

				  if last_update >= 0.25 then
					  RunSinFunction()
					  last_update = 0
				  end
			  end)
end
That executes the sin function every quarter of a second.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
02-06-10, 04:25 AM   #14
Hati-EK
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 20
Originally Posted by Torhal View Post
Not true.

Code:
do
	local last_update = 0
	local updater = CreateFrame("Frame", nil, UIParent)

	updater:Hide()
	updater:SetScript("OnUpdate",
			  function(self, elapsed)
				  last_update = last_update + elapsed

				  if last_update >= 0.25 then
					  RunSinFunction()
					  last_update = 0
				  end
			  end)
end
That executes the sin function every quarter of a second.
Code:
last_update = last_update -0.25
is more precise and does not skip seconds (even if this would just be some miliseconds) than reseting the whole value to 0 - (ie last_update could be 0.25182965 - so you would missing 0.00182965 - if you have this ~1000 times there's something missing

Last edited by Hati-EK : 02-06-10 at 04:27 AM.
  Reply With Quote
02-06-10, 06:43 AM   #15
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 716
Originally Posted by Hati-EK View Post
Code:
last_update = last_update -0.25
is more precise and does not skip seconds (even if this would just be some miliseconds) than reseting the whole value to 0 - (ie last_update could be 0.25182965 - so you would missing 0.00182965 - if you have this ~1000 times there's something missing
Nope, because THIS time if you run at 120 fps then the function would run a lot more then when at 10 fps.
__________________
Three things are certain,
Death, taxes and site not found,
You, victim of one.
  Reply With Quote
02-06-10, 08:30 AM   #16
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,196
Originally Posted by Hati-EK View Post
Code:
last_update = last_update -0.25
is more precise and does not skip seconds (even if this would just be some miliseconds) than reseting the whole value to 0 - (ie last_update could be 0.25182965 - so you would missing 0.00182965 - if you have this ~1000 times there's something missing
This is true, if you're looking to be precise.
__________________
Whenever someone says "pls" because it's shorter than "please", I say "no" because it's shorter than "yes".

Author of NPCScan and many other AddOns.
  Reply With Quote
02-12-10, 12:24 PM   #17
Haleth
This Space For Rent
 
Haleth's Avatar
Featured
Join Date: Sep 2008
Posts: 1,173
Sorry for thread hijack, but how can this code be applied to a single animation instead of a looping 'pulse'? I'm trying to add opening/closing animations to some addon frames, for example in the following code:

Code:
local function Stuffing_Open()
	Stuffing.frame:Show()
end


local function Stuffing_Close()
	Stuffing.frame:Hide()
end
I've tried a couple of things, but no luck.
  Reply With Quote
02-12-10, 12:55 PM   #18
Hati-EK
A Fallenroot Satyr
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 20
Originally Posted by Haleth View Post
Sorry for thread hijack, but how can this code be applied to a single animation instead of a looping 'pulse'? I'm trying to add opening/closing animations to some addon frames, for example in the following code:

Code:
local function Stuffing_Open()
	Stuffing.frame:Show()
end


local function Stuffing_Close()
	Stuffing.frame:Hide()
end
I've tried a couple of things, but no luck.
maybe you are looking for

frame:SetScript('OnShow', doSomethingOnShow)

or frame:SetScript('OnHide', doSomethingOnHide)

?
  Reply With Quote
06-25-10, 08:39 AM   #19
Smacker
A Deviate Faerie Dragon
 
Smacker's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2009
Posts: 16
Use the built-in animation code:

Code:
	local alpha = animationGroup:CreateAnimation("Alpha");
	alpha:SetOrder(order);
	alpha:SetDuration(duration);
	alpha:SetMaxFramerate(fps);
	alpha:SetChange(alphaTo);
  Reply With Quote
06-26-10, 02:07 PM   #20
Dawn
A Molten Giant
 
Dawn's Avatar
AddOn Author - Click to view addons
Join Date: May 2006
Posts: 918
Arrrr, sometimes thread necrotism is good stuff, indeed. I somehow missed this one. *bookmarks thread*
__________________
Rock: "We're sub-standard DPS. Nerf Paper, Scissors are fine."
Paper: "OMG, WTF, Scissors!"
Scissors: "Rock is OP and Paper are QQers. We need PvP buffs."

"neeh the game wont be remembered as the game who made blizz the most money, it will be remembered as the game who had the most QQ'ers that just couldnt quit the game for some reason..."

  Reply With Quote

WoWInterface » Developer Discussions » Graphics Help » "Pulsating" effect...what's the proper method?

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off