Thread Tools Display Modes
09-25-18, 05:04 AM   #1
Terenna
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 105
Optimizing a fade out

Good morning all,

I have written a small snippet of code to show certain aspects of the minimap children, by controlling their alpha, when I mouseover the minimap. Further, when the mouse leaves the minimap, it starts a fadeout process that occurs relatively smoothly, 20 incremental decreases of alpha by 0.05 over 1 second. I couldn't think of a better way to code this, and everything works as intended. I am writing this to determine how to do it better.

Thank you, I'm guessing this is way over engineered and am eager to learn more about how to do this more efficiently.

Lua Code:
  1. local fadeouttimer = 1
  2. local subtractor = fadeouttimer/20
  3. local fader
  4. local function tMinimapFadeOut()
  5.     if Minimap:IsMouseOver() then --mouse reentered during fadeout, cancel the ticker, reset the timer, and set alphas back to 1
  6.         fader:Cancel()
  7.         fadeouttimer = 1
  8.         GameTimeFrame:SetAlpha(1)
  9.         TimeManagerClockButton:SetAlpha(1)
  10.         MiniMapTracking:SetAlpha(1)
  11.         MiniMapChallengeMode:SetAlpha(1)
  12.         MiniMapInstanceDifficulty:SetAlpha(1)
  13.         GuildInstanceDifficulty:SetAlpha(1)
  14.     end
  15.    
  16.     fadeouttimer = fadeouttimer - subtractor
  17.     GameTimeFrame:SetAlpha(fadeouttimer or 0) -- or 0 for when the game inevitably determines that 0 is actually a tiny negative number
  18.     TimeManagerClockButton:SetAlpha(fadeouttimer or 0)
  19.     MiniMapTracking:SetAlpha(fadeouttimer or 0)
  20.     MiniMapChallengeMode:SetAlpha(fadeouttimer or 0)
  21.     MiniMapInstanceDifficulty:SetAlpha(fadeouttimer or 0)
  22.     GuildInstanceDifficulty:SetAlpha(fadeouttimer or 0)
  23.    
  24.     if fadeouttimer <= 0 then --reset the fadeouttimer for next time
  25.         fader:Cancel() --failsafe to stop any previous fades that are ongoing when the mouse leaves (in case the mouse enters and then exits and then reenters)
  26.         fadeouttimer = 1
  27.     end
  28. end
  29.  
  30. local lasttime = 0
  31. Minimap:SetScript('OnLeave', function()
  32.     if Minimap:IsMouseOver() then return end --failsafe to ensure we don't hide with mouse still on minimap
  33.     if time() == lasttime then return end --another failsafe
  34.     lasttime = time()
  35.     fader = C_Timer.NewTicker(0.05, tMinimapFadeOut, 20) --run 20 times over 1 second (20*0.05 = 1)
  36. end)
  Reply With Quote
09-25-18, 05:41 AM   #2
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Normally I use the animation api for fadein/out animations.
https://github.com/zorker/rothui/blo...efader.lua#L55

Though for the minimap I do not do that. I just use an onleave delay timer of 1 second to hide all minimap icons.
https://github.com/zorker/rothui/blo.../core.lua#L156
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote
09-25-18, 07:34 AM   #3
Terenna
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 105
Hey zork,

Thanks for your reply. I based this on your code; however, I wanted to fade out rather than just immediately set the alpha to 0.

I'll take a look at running animations. Thanks!
  Reply With Quote
09-25-18, 08:24 AM   #4
Terenna
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 105
I was able to dry code the following:

Lua Code:
  1. local fadeouttable = {}
  2. table.insert(fadeouttable, GameTimeFrame)
  3. table.insert(fadeouttable, TimeManagerClockButton)
  4. table.insert(fadeouttable, MiniMapTracking)
  5. table.insert(fadeouttable, MiniMapChallengeMode)
  6. table.insert(fadeouttable, MiniMapInstanceDifficulty)
  7. table.insert(fadeouttable, GuildInstanceDifficulty)
  8.  
  9. local function CreateFrameFadeAnimation(frame)
  10.     if frame.fader then return end
  11.     local animFrame = CreateFrame('frame', nil, frame)
  12.     animFrame.__owner = frame
  13.     frame.fader = animFrame:CreateAnimationGroup()
  14.     frame.fader.__owner = frame
  15.     frame.fader.__animFrame = animFrame
  16.     frame.fader.direction = nil
  17.     frame.fader.setToFinalAlpha = false
  18.     frame.fader.anim = frame.fader:CreateAnimation('Alpha')
  19.     --frame.fader:HookScript("OnFinished", FaderOnFinished)
  20.     --frame.fader:HookScript("OnUpdate", FaderOnUpdate)
  21.  end
  22.  
  23. local function tMinimapFadeOut(frame)
  24.     if frame.fader.direction == 'out' then return end
  25.     frame.fader:Pause()
  26.     frame.fader.anim:SetFromAlpha(1)
  27.     frame.fader.anim:SetToAlpha(0)
  28.     frame.fader.anim:SetDuration(1)
  29.     frame.fader.anim:SetSmoothing('OUT')
  30.     frame.fader.anim:SetStartDelay(1)
  31.     frame.fader.finAlpha = 0
  32.     frame.fader.direction = 'out'
  33.     frame.fader:Play()
  34. end
  35.  
  36. local lasttime
  37. Minimap:SetScript('OnLeave', function()
  38.     if Minimap:IsMouseOver() then return end --failsafe to ensure we don't hide with mouse still on minimap
  39.     if time() == lasttime then return end --another failsafe
  40.     lasttime = time()
  41.  
  42.     for k, v in pairs(fadeouttable) do
  43.         tMinimapFadeOut(v)
  44.     end
  45. end)
  46.  
  47. Minimap:SetScript('OnEnter', function()
  48.     for k, v in pairs(fadeouttable) do
  49.         v.fader:Pause()
  50.         v:SetAlpha(1)
  51.     end
  52. end)

Of note, I didn't understand why you need the onupdate and the onfinished functions. Why is that, exactly?

Last edited by Terenna : 09-25-18 at 08:26 AM.
  Reply With Quote
09-25-18, 02:33 PM   #5
Terenna
A Flamescale Wyrmkin
AddOn Author - Click to view addons
Join Date: Jun 2016
Posts: 105
Ended up having some bugs (naturally) and I wet coded it to:
Lua Code:
  1. LoadAddOn("Blizzard_TimeManager")
  2. local fadeouttable = {}
  3. table.insert(fadeouttable, GameTimeFrame)
  4. table.insert(fadeouttable, TimeManagerClockButton)
  5. table.insert(fadeouttable, MiniMapTracking)
  6. table.insert(fadeouttable, MiniMapChallengeMode)
  7. table.insert(fadeouttable, MiniMapInstanceDifficulty)
  8. table.insert(fadeouttable, GuildInstanceDifficulty)
  9.  
  10. local function FaderOnFinished(self)
  11.     self.__owner:SetAlpha(0)
  12. end
  13.  
  14. local function FaderOnUpdate(self)
  15.     self.__owner:SetAlpha(self.__animFrame:GetAlpha())
  16. end
  17.  
  18. local function CreateFrameFadeAnimation(frame)
  19.     if frame.fader then return end
  20.     local animFrame = CreateFrame('Frame', nil, frame)
  21.     animFrame.__owner = frame
  22.     frame.fader = animFrame:CreateAnimationGroup()
  23.     frame.fader.__owner = frame
  24.     frame.fader.__animFrame = animFrame
  25.     frame.fader.direction = nil
  26.     frame.fader.setToFinalAlpha = false
  27.     frame.fader.anim = frame.fader:CreateAnimation('Alpha')
  28.     frame.fader:HookScript("OnFinished", FaderOnFinished)
  29.     frame.fader:HookScript("OnUpdate", FaderOnUpdate)
  30. end
  31.  
  32. for k, v in pairs(fadeouttable) do
  33.     CreateFrameFadeAnimation(v)
  34. end
  35.  
  36. local function tMinimapFadeOut(frame)
  37.     if frame.fader.direction == 'out' then return end
  38.     frame.fader:Pause()
  39.     frame.fader.anim:SetFromAlpha(1)
  40.     frame.fader.anim:SetToAlpha(0)
  41.     frame.fader.anim:SetDuration(1)
  42.     frame.fader.anim:SetSmoothing('OUT')
  43.     frame.fader.anim:SetStartDelay(1)
  44.     frame.fader.direction = 'out'
  45.     frame.fader:Play()
  46. end
  47.  
  48. local lasttime
  49. Minimap:SetScript('OnLeave', function()
  50.     if Minimap:IsMouseOver() then return end --failsafe to ensure we don't hide with mouse still on minimap
  51.     if time() == lasttime then return end --another failsafe
  52.     lasttime = time()
  53.  
  54.     for k, v in pairs(fadeouttable) do
  55.         tMinimapFadeOut(v)
  56.     end
  57. end)
  58.  
  59. Minimap:SetScript('OnEnter', function()
  60.     for k, v in pairs(fadeouttable) do
  61.         v.fader:Pause()
  62.         v.fader.direction = nil
  63.         v:SetAlpha(1)
  64.     end
  65. end)

Works like a charm, it's a lot longer than my original code, but probably a tiny bit more efficient than doing a meta table look up 20 times.
  Reply With Quote
09-26-18, 03:53 AM   #6
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2008
Posts: 1,740
Looks good.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW)

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Optimizing a fade out

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