Reply
 
Thread Tools Display Modes
Old 01-26-10, 01: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
Old 01-26-10, 01:58 PM   #2
d87
A Warpwood Thunder Caller
AddOn Author - Click to view addons
Join Date: Jan 2006
Posts: 98
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
d87 is offline   Reply With Quote
Old 01-26-10, 02:00 PM   #3
Xrystal
nUI User and Supporter
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,025
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
__________________
Xrystal is offline   Reply With Quote
Old 01-26-10, 02:16 PM   #4
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 714
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.
nightcracker is offline   Reply With Quote
Old 01-26-10, 02:32 PM   #5
Xrystal
nUI User and Supporter
 
Xrystal's Avatar
Premium Member
AddOn Author - Click to view addons
Join Date: Feb 2006
Posts: 5,025
*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)
__________________
Xrystal is offline   Reply With Quote
Old 01-26-10, 02:39 PM   #6
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,023
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 Revelation, Spamalyzer, TravelAgent, Volumizer, and many other AddOns.
Torhal is offline   Reply With Quote
Old 01-26-10, 02:42 PM   #7
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 714
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.
nightcracker is offline   Reply With Quote
Old 01-26-10, 02: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
Old 01-26-10, 02:55 PM   #9
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 714
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.
nightcracker is offline   Reply With Quote
Old 02-05-10, 11:01 AM   #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
Nemnacill is offline   Reply With Quote
Old 02-05-10, 12: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 07:03 PM.
Hati-EK is offline   Reply With Quote
Old 02-05-10, 11:25 PM   #12
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 714
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.
nightcracker is offline   Reply With Quote
Old 02-06-10, 01:59 AM   #13
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,023
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 Revelation, Spamalyzer, TravelAgent, Volumizer, and many other AddOns.
Torhal is offline   Reply With Quote
Old 02-06-10, 03: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 03:27 AM.
Hati-EK is offline   Reply With Quote
Old 02-06-10, 05:43 AM   #15
nightcracker
A Molten Giant
 
nightcracker's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2009
Posts: 714
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.
nightcracker is offline   Reply With Quote
Old 02-06-10, 07:30 AM   #16
Torhal
A Pyroguard Emberseer
 
Torhal's Avatar
AddOn Author - Click to view addons
Join Date: Aug 2008
Posts: 1,023
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 Revelation, Spamalyzer, TravelAgent, Volumizer, and many other AddOns.
Torhal is offline   Reply With Quote
Old 02-12-10, 11:24 AM   #17
Haleth
This Space For Rent
 
Haleth's Avatar
WoWInterface Super Mod
Featured
Join Date: Sep 2008
Posts: 1,154
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.
Haleth is offline   Reply With Quote
Old 02-12-10, 11:55 AM   #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)

?
Hati-EK is offline   Reply With Quote
Old 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);
Smacker is offline   Reply With Quote
Old 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: 903
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..."

Dawn is offline   Reply With Quote
Reply

Go BackWoWInterface » 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