Quantcast
Download
(1 MB)
Download
Updated: 10-17-18 04:37 AM
Pictures
File Info
Compatibility:
Battle for Azeroth (8.0.1)
Updated:10-17-18 04:37 AM
Created:12-15-13 12:44 PM
Downloads:31,677
Favorites:122
MD5:
Categories:Suites, Action Bar Mods, Unit Mods, Graphical Compilations
8.0.1

ls: UI  Updated this week!  Popular! (More than 5000 hits)

Version: 80000.12
by: lightspark [More]

Yet another UI, but this one is a bit special.



Options
Use /LSUI to open in-game config.

Feedback and Feature Requests
If you found a bug or want to share an idea on how to improve my UI, either use the issue tracker on GitHub or Curse, or post a comment on WoWInterface or Curse.

Feel free to write feedback on how to improve some class-specific features.

However, keep in mind that I'm not going to implement any features as a replacement for BIG addons.

Localisation
Feel free to add and/or review translations on Curse, alternatively, you may create a PR on project's GitHub page.

License
Please see LICENSE file.

Version 80000.12

- Added options to adjust text size, outline, and shadow of various unit frame elements, e.g.,
health, power, etc;
- Reworked resource gain/loss animations. Added health loss animations, and options to adjust
health, power, class power, and alternative power gain/loss thresholds;
- Tweaked unit frame border textures;
- Fixed compatibility issues with Masque;
- Updated embeds.



Version 80000.11

- Added options to adjust auras' count text and aura type icon. It's also possible to display
actual debuff types instead of generic down arrows;
- Added options to adjust xp bar's text's format and visibility;
- Added options to adjust castbars' colours;
- Added a hack for cooldown numbers. Cooldown spirals are still bugged, but that's a Blizz bug;
- Updated minimap button handling. This should greatly improve compatibility w/ addons that add
various markers, for instance, TomTom, ZygorGuides;
- Updated embeds.

Version 80000.10

- Added cooldown options to the "Unit Frames" and unit frames' "Auras" configs;
- Removed "Show Cooldown Bling" option. The bling is disabled on all handled cooldowns now
because the animation is bugged anyway;
- Updated Simplified Chinese translation. Translated by [email protected];
- Updated embeds.

Version 80000.09

- Reworked fade in and out animations. Previously, their performance was degrading over time, and
after long gaming sessions they could cause micro stuttering and/or big freezes when being played;
- Added unit frame tag validation to avoid issues caused by invalid tags;
- Added options to colour minimap border and to adjust border's and text's colours;
- Added options to adjust xp bar's text;
- Added the option to colour player orb's border;
- Normal and war mode phase indicators now use different icons, blue and red respectively;
- Updated both Spanish translations. Translated by [email protected];
- Updated embeds.

Version 80000.08

- Fixed the "Inventory" micro button's currency tracker;
- Fixed an issue where getting and/or setting a key binding text for a button with no name would
result in an error. This issue mainly affected the Pet Battle UI;
- Blizz castbar's movers are now properly disabled when the default castbars aren't actually
used;
- Player's buffs, debuffs, and totems are now hidden while doing pet battles.

Version 80000.07

- Reworked UF config tables' structure. Target, target of target, focus, target of focus, and boss
frames' settings are cross-layout, so their settings are shared between "Orbs" and "Classic" UI
layouts. Player and pet frames' settings will stay tied to UI layouts because those frames are
unique. Unit frame settings of the currently active UI layout will be copied, but some settings
may be lost. This will also help people with copying profiles from one char to another, even if
different UI layouts are used on those chars;
- Fixed numerous bugs in the "Unit Frames" config. Copying settings between unit frame, incl. aura
filters, should work as intended now;
- Unit frame auras' min and max sizes are set to 24px and 64px respectively. These will also be
applied to automatic size calculations;
- Reduced the xp bar's width and updated the artwork;
- Updated embeds.

Version 80000.06

- Fixed action buttons' icons' colouring.

Version 80000.05

- Added "Desaturation" section to "Action Bars" config. Replaces "Desaturate on Cooldown" and
"Desaturate when Not Usable" options;
- Fixed the default castbars' skin.

Version 80000.04

- Reworked cooldowns' handling. Action bars, auras, and aura tracker received a set of options to
customise cooldowns' appearance. Unit frames will get a similar update a bit later;
- Reworked mirror timers, e.g., fatigue, breath, etc. They now show the remaining time in the M:SS
format;
- Added the default cast bars' skin for people who don't use my unit frames;
- Updated "Blizzard" config section. Added options to customise mirror timers, digsite bar;
- Updated "Action Bars" config section. In addition to aforementioned cooldown changes, I also
added options to customise action buttons' colours and to desaturate icons when buttons are
unusable;
- Updated the loot frame, so it's impossible to click through it;
- Numerous bug fixes and tweaks;
- Updated embeds.

NOTE #1: You'll have to restart WoW client to make things work after the update.

NOTE #2: Aura module's config is now cross-layout, which means that it'll use the same settings
for both "Orbs" and "Classic" layouts. Although almost everything should be copied, some data loss
may occur.

Version 80000.03

- Reworked micro menu. Again. Added options to split micro menu into two bars and to assign each
button to either bar individually;
- Fixed loot frame error that occurred for people who like to spam-click things;
- Updated both Spanish translations. Translated by [email protected]

Version 80000.02

- Fixed "Classic" layout.

Version 80000.01

- Added 8.0.1 support;
- Added custom loot frame;
- Added mouseover key binding. Use "/lsui kb" command or "Binding Mode" button in the config;
- Added options to enable DK runes' sorting and colouring by spec;
- Reworked action bar hub. Retired bag bar;
- Reworked micro menu and its config. Added "Inventory" micro button;
- Reworked tooltips. Added tooltip mover and the option to attach it to the mouse cursor;
- Numerous bug fixes and tweaks;
- Updated embeds.
Archived Files (11)
File Name
Version
Size
Author
Date
80000.11
1MB
lightspark
09-28-18 10:00 AM
80000.10
1MB
lightspark
09-17-18 06:58 AM
80000.09
1MB
lightspark
08-16-18 02:06 AM
80000.08
1MB
lightspark
07-28-18 06:23 AM
80000.07
1MB
lightspark
07-27-18 02:57 AM
80000.06
1MB
lightspark
07-25-18 06:47 AM
80000.05
1MB
lightspark
07-25-18 04:26 AM
80000.04
1MB
lightspark
07-24-18 09:32 AM
80000.03
1MB
lightspark
07-19-18 08:50 PM
80000.02
1MB
lightspark
07-18-18 05:20 AM
80000.01
1MB
lightspark
07-17-18 10:39 AM


Post A Reply Comment Options
Unread 12-15-13, 03:22 PM  
saxitoxin
A Wyrmkin Dreamwalker
 
saxitoxin's Avatar
AddOn Author - Click to view AddOns

Forum posts: 59
File comments: 98
Uploads: 7
Good Job

Just wanted to say that you have done a good job on this one
Report comment to moderator  
Reply With Quote
Unread 12-15-13, 04:59 PM  
10leej
A Molten Giant
 
10leej's Avatar
AddOn Author - Click to view AddOns

Forum posts: 573
File comments: 419
Uploads: 21
Great implementation of what I assume to be zork's oUF_Donut
__________________
Tweets Website
Report comment to moderator  
Reply With Quote
Unread 12-15-13, 05:08 PM  
wildbill
A Kobold Labourer

Forum posts: 1
File comments: 2
Uploads: 0
Your work is gorgeous. I hope it gets more exposure.
Report comment to moderator  
Reply With Quote
Unread 12-15-13, 09:03 PM  
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view AddOns

Forum posts: 305
File comments: 799
Uploads: 6
Originally Posted by 10leej
Great implementation of what I assume to be zork's oUF_Donut
Nope, these are just usual statusbars and textures. I just spent quite much time on positioning elements, doing visuals and coding but of course I was inspired by zork's UI and diablo in general. One of the early versions was more diablo themed. But then I started everything from scratch, both visuals and code. Want it to have a unique style

Thx, everyone will do my best!

Feedback! Yay!
Last edited by lightspark : 12-15-13 at 09:12 PM.
Report comment to moderator  
Reply With Quote
Unread 12-15-13, 09:30 PM  
p3lim
A Pyroguard Emberseer
 
p3lim's Avatar
AddOn Author - Click to view AddOns

Forum posts: 1669
File comments: 1221
Uploads: 31
Take a look at http://www.wowinterface.com/forums/s...ad.php?t=45918 if you want to fill the bars in actual circular motion.
Other than that, looks good
Report comment to moderator  
Reply With Quote
Unread 12-15-13, 09:45 PM  
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view AddOns

Forum posts: 305
File comments: 799
Uploads: 6
Originally Posted by p3lim
Take a look at http://www.wowinterface.com/forums/s...ad.php?t=45918 if you want to fill the bars in actual circular motion.
Other than that, looks good
Thx, now, when I finally managed to release this UI, it's time to look for different ways to improve it!
Cuz previously if i tried to do some research I would end up rewriting the whole thing
Report comment to moderator  
Reply With Quote
Unread 12-15-13, 09:57 PM  
10leej
A Molten Giant
 
10leej's Avatar
AddOn Author - Click to view AddOns

Forum posts: 573
File comments: 419
Uploads: 21
Originally Posted by lightspark
Originally Posted by p3lim
Take a look at http://www.wowinterface.com/forums/s...ad.php?t=45918 if you want to fill the bars in actual circular motion.
Other than that, looks good
Thx, now, when I finally managed to release this UI, it's time to look for different ways to improve it!
Cuz previously if i tried to do some research I would end up rewriting the whole thing
Ah well that thread talks about zork's theory he turned to reality in oUF_Donut you can look at that addon for a working implementation for a circular motion.
__________________
Tweets Website
Report comment to moderator  
Reply With Quote
Unread 12-15-13, 10:07 PM  
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view AddOns

Forum posts: 305
File comments: 799
Uploads: 6
Originally Posted by 10leej
Ah well that thread talks about zork's theory he turned to reality in oUF_Donut you can look at that addon for a working implementation for a circular motion.
Yeah, already testing his oUF_Donut, but still have to read theory. if I'm to use it as a reference, I have to fully understand how it works
Report comment to moderator  
Reply With Quote
Unread 12-16-13, 01:43 AM  
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view AddOns

Forum posts: 1726
File comments: 3699
Uploads: 123
Great job, the layout looks awesome, I really like the textures. The radial approach works best for 90, 180, 270 or 360 ring segments. Doing tinier ring segments require way to much hacking. It is done by using scrollframes since they crop textures. The simplest example is described here:
http://www.wowinterface.com/forums/s...95&postcount=9

You could still use it for most of your outer rings except for the runes. Since any other power source can be translated into an rotation angle from 0-180.

Currently the idea is to use fixed set of scrollframes and just rotate a bunch of texture inside the scrollchild of each scrollframe. This has merits though. Rings need to start/end and 0,90,180 or 270.
Making it possible to start a ring at any angle is nearly impossible. Some parts can be solved by tricky texure creation though. Using the alpha layer to hide specific texture parts for example.

Currently doing your petframe as a ring is nearly impossible.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW) | TDMOG

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
Last edited by zork : 12-16-13 at 04:16 AM.
Report comment to moderator  
Reply With Quote
Unread 12-16-13, 07:27 AM  
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view AddOns

Forum posts: 305
File comments: 799
Uploads: 6
Originally Posted by zork
Great job, the layout looks awesome, I really like the textures. The radial approach works best for 90, 180, 270 or 360 ring segments. Doing tinier ring segments require way to much hacking. It is done by using scrollframes since they crop textures. The simplest example is described here:
http://www.wowinterface.com/forums/s...95&postcount=9

You could still use it for most of your outer rings except for the runes. Since any other power source can be translated into an rotation angle from 0-180.

Currently the idea is to use fixed set of scrollframes and just rotate a bunch of texture inside the scrollchild of each scrollframe. This has merits though. Rings need to start/end and 0,90,180 or 270.
Making it possible to start a ring at any angle is nearly impossible. Some parts can be solved by tricky texure creation though. Using the alpha layer to hide specific texture parts for example.

Currently doing your petframe as a ring is nearly impossible.
TY! Ur rTestRing helped me to learn ScrollFrames well and after performing few tests I decided to stick with 180 segments.

It's quite easy to control texture rotation by animation's OnPlay, OnFinish and may be OnStop scripts. First we animate it, @OnPlay we calculate texture's new angel, @OnFinish we set it. Then next time we play animation again we start where we stopped before.

Dirty, but works fine. This code makes texture constantly rotate with an 18 step! Wicked! Just in case someone else wants to do the same, use this code for better understanding

Lua Code:
  1. local rt1 = sc1:CreateTexture(nil,"BACKGROUND",nil,-6)
  2.   rt1:SetTexture("Interface\\AddOns\\rTestRing\\media\\ring_half")
  3.   rt1:SetSize(sqrt(2) * f.w, sqrt(2) * f.h)
  4.   rt1:SetPoint("CENTER", -128, 0)
  5.   rt1:SetVertexColor(1,0,0)
  6.   local angle = 180 * 0.1 * 1 -- angle of segment, how "far" we want to rotate ouf texture, direction
  7.   rt1:SetRotation(math.rad(0)) -- we can set any angle as initial point
  8.   rt1.degrees = 0
  9.  
  10.   local ag = rt1:CreateAnimationGroup()
  11.   ag.anim = ag:CreateAnimation("Rotation")
  12.   ag.anim:SetDegrees(angle)
  13.   ag.anim:SetDuration(1)
  14.   ag.anim:SetSmoothing("OUT")
  15.   ag:SetIgnoreFramerateThrottle(true)
  16.  
  17.   ag:SetScript("OnFinished", function (table, ...)
  18.     rt1:SetRotation(math.rad(rt1.degrees))
  19.     table.anim:SetStartDelay(0)
  20.     table:Play()
  21.     table:Finish()
  22.   end)
  23.  
  24.   ag:SetScript("OnPlay", function (table, ...)
  25.     if rt1.degrees >= 360 then
  26.       rt1.degrees = rt1.degrees - 360 + (table.anim:GetDegrees())
  27.     elseif rt1.degrees <= -360 then
  28.       rt1.degrees = 0 + (table.anim:GetDegrees())
  29.     else
  30.       rt1.degrees = rt1.degrees + (table.anim:GetDegrees())
  31.     end
  32.   end)
  33.   ag.anim:SetStartDelay(2)
  34.   ag:Play()
  35.   ag:Finish()

I think I'll implement powerbars (mana, rage, etc) and all but runes and totems via ScrollFrames. Need to code an adequate interface to access and manage animations, rotations, etc. Once again TY!
Last edited by lightspark : 12-16-13 at 07:35 AM.
Report comment to moderator  
Reply With Quote
Unread 12-16-13, 11:17 AM  
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view AddOns

Forum posts: 1726
File comments: 3699
Uploads: 123
No, do not use animationgroups for those rings. That was just for my testing purpose. There is an even better solution.

Create a fake statusbar. Lets say your healthbar should be a 180 ring, so you create:
Lua Code:
  1. local rad = rad
  2.  
  3. local function OnValueChanged(self,...)
  4.   local hmin, hmax, hcur = self:GetMinMaxValues(), self:GetValue()
  5.   local hper = 0
  6.   if hmax > 0 then hper = hcur/hmax end
  7.   local hrad = rad(hper*self.maxRadius)
  8.   self.ringTexture:SetRotation(hrad)
  9. end
  10.  
  11. local self.Health = CreateFrame("StatusBar",nil,self)
  12. self.Health.maxRadius = 180
  13. self.Health.ringTexture = ringTexture --reference to the scrollframe ring texture that should be your health ring
  14. self.Health:SetScript("OnValueChanged",OnValueChanged)

That way oUF_Smooth can still be applied to your oUF health object. The onvaluechanged event will trigger the ring updates. The same technique can be used for all the other bars.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW) | TDMOG

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
Last edited by zork : 12-16-13 at 11:24 AM.
Report comment to moderator  
Reply With Quote
Unread 12-16-13, 11:28 AM  
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view AddOns

Forum posts: 305
File comments: 799
Uploads: 6
Tested - Works!

Originally Posted by zork
No, do not use animationgroups for those rings. That was just for my testing purpose. There is an even better solution.

Create a fake statusbar. Lets say your healthbar should be a 180 ring, so you create:

....

That way oUF_Smooth can still be applied to your oUF health object. The onvaluechanged event will trigger the ring updates. The same technique can be used for all the other bars.
Tried to implement Burning Embers using ScrollFrame. Rough, but works.

Results:


Lua Code:
  1. ag:SetScript("OnFinished", function (table, ...)
  2.   rt1:SetRotation(math.rad(rt1.degrees))
  3. end)
  4.  
  5. ag:SetScript("OnStop", function (table, ...)
  6.   rt1:SetRotation(math.rad(rt1.degrees))
  7.   print("STOPPED!")
  8. end)
  9.  
  10. ag:SetScript("OnPlay", function (table, ...)
  11.   if rt1.degrees >= 360 then
  12.     rt1.degrees = rt1.degrees - 360 + (table.anim:GetDegrees())
  13.   elseif rt1.degrees <= -360 then
  14.     rt1.degrees = 0 + (table.anim:GetDegrees())
  15.   else
  16.     rt1.degrees = rt1.degrees + (table.anim:GetDegrees())
  17.   end
  18. end)
  19.  
  20.  
  21. local function SF_OnEvent(self, event, unit, powerType)
  22.   if powerType ~= "BURNING_EMBERS" and not event == "PLAYER_ENTERING_WORLD" then return end
  23.  
  24.   if event == "PLAYER_ENTERING_WORLD" then
  25.     sf1.oldCur = 0
  26.   end
  27.  
  28.   local cur = UnitPower("player", SPELL_POWER_BURNING_EMBERS, true)
  29.   local max = UnitPowerMax("player", SPELL_POWER_BURNING_EMBERS, true)
  30.  
  31.   local step = 180 / max
  32.  
  33.   local direction = -1
  34.  
  35.   if self.oldCur > cur then
  36.     direction = 1
  37.   elseif self.oldCur < cur then
  38.     direction = -1
  39.   end
  40.  
  41.   local steps_to_do = math.abs(cur - self.oldCur)
  42.   self.oldCur = cur
  43.  
  44.   if steps_to_do ~= 0 then
  45.     print("steps:", steps_to_do, "direction:", direction, "current:", cur)
  46.  
  47.     ag.anim:SetDegrees(step * direction * steps_to_do)
  48.  
  49.     if ag:IsPlaying() then ag:Stop() end
  50.    
  51.     ag:Play()
  52.     ag:Finish()
  53.   end
  54. end
  55.  
  56. sf1:RegisterEvent('PLAYER_ENTERING_WORLD')
  57. sf1:RegisterEvent('UNIT_DISPLAYPOWER')
  58. sf1:RegisterEvent('UNIT_POWER_FREQUENT')
  59. sf1:SetScript("OnEvent", SF_OnEvent)

As I said before it's quite easy to control texture position by OnPlay, OnFinish and OnStop scripts, OnStop and OnFinish r doing the same thing. We need OnStop, when we're forcing animation to stop, but we still need to update textures angle.

That's simple, but here starts magic. To make ScrollFrame and animated texture behave like StatusBar we have to perform few calculations:
1) Size of a step
2) Direction where to rotate.
3) Amount of steps we have to perform.

Knowing these variables allows us to calculate how "far" we have to rotate at once, instead of animating step-by-step. For example, when we login, reload UI or, in this case, when we cast Chaos Bolt, which consumes 10 pieces of ember.

At least I learnt something new, haha. I'll test ur method tomorrow :3
Last edited by lightspark : 12-16-13 at 11:34 AM.
Report comment to moderator  
Reply With Quote
Unread 12-17-13, 01:33 AM  
zork
A Pyroguard Emberseer
 
zork's Avatar
AddOn Author - Click to view AddOns

Forum posts: 1726
File comments: 3699
Uploads: 123
Re: Tested - Works!

You can apply the smooth module to any statusbar. Thus you could use self:SmoothBar(self.SoulShards) for soulshards (or any other bar). Thus once the bar has its value changed the smoothing will be applied.

The animation groups use an onupdate system aswell, just on c-side. You are right, both concepts will work, but you already got smoothing as a module and the animationgroup has to call setrotation aswell, even in the process of rotation.

What I find pretty important is that the smooth module is consistent independent of fps, thus the smoothing will be the same for any framerate. http://code.google.com/p/rothui/sour..._Smooth.lua#40

But I think animationgroups do that aswell since you need to add a duration for your animation. Hmmm...you use fixed 1 second as a duration, I do not think that this will work. You need to adjust the duration based on the how much big the percentage change is in relation to the ring radius. Otherwise the movement is inconsistent.

But nonetheless I like your animationgroup approach, if you can get it consistent it could work out pretty nicely.
__________________
| Simple is beautiful.
| WoWI AddOns | GitHub | Zork (WoW) | TDMOG

"I wonder what the non-pathetic people are doing tonight?" - Rajesh Koothrappali (The Big Bang Theory)
Last edited by zork : 12-17-13 at 01:44 AM.
Report comment to moderator  
Reply With Quote
Unread 12-17-13, 04:25 AM  
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view AddOns

Forum posts: 305
File comments: 799
Uploads: 6
Re: Re: Tested - Works!

Originally Posted by zork
You can apply the smooth module to any statusbar. Thus you could use self:SmoothBar(self.SoulShards) for soulshards (or any other bar). Thus once the bar has its value changed the smoothing will be applied.
Currently all of my statusbars r smoothed

Originally Posted by zork
The animation groups use an onupdate system aswell, just on c-side. You are right, both concepts will work, but you already got smoothing as a module and the animationgroup has to call setrotation aswell, even in the process of rotation.

What I find pretty important is that the smooth module is consistent independent of fps, thus the smoothing will be the same for any framerate. http://code.google.com/p/rothui/sour..._Smooth.lua#40

But I think animationgroups do that aswell since you need to add a duration for your animation. Hmmm...you use fixed 1 second as a duration, I do not think that this will work. You need to adjust the duration based on the how much big the percentage change is in relation to the ring radius. Otherwise the movement is inconsistent.
As for the way how animations work, AGs also have this feature, my original AG's code for testing was:
Lua Code:
  1. local ag = rt1:CreateAnimationGroup()
  2. ag.anim = ag:CreateAnimation("Rotation")
  3. ag.anim:SetDuration(0.5)
  4. ag.anim:SetSmoothing("OUT")
  5. ag:SetIgnoreFramerateThrottle(true)
as u can c, i use SetIgnoreFramerateThrottle function, it allows me to render animation at the real fps, thus there is need to adjust duration on the fly and i just set it to 0.5, but 0.4 is even better! Runs smoothly, even when texture rotates >90 degrees at once, there's almost no need to call Stop() function.
Possible problem is when texture starts rotating >90 degrees, then we have to stop the animation, and play it again starting at new angle. In this case movement will be a lil bit inconsistent. But sure there is something else...

Originally Posted by zork
But nonetheless I like your animationgroup approach, if you can get it consistent it could work out pretty nicely.
TY! But for now I'll use ur method with a fake statusbar, maybe I'll switch to AG method later, but only if it allows me to use less memory and write less or more elegant code Christmas time, almost no work to do and single, I have plenty of time to try different approaches haha, shi~ sounds quite sad

[UPDATE]

Back to AG topic. Tested this thingy more.
Result: It's quite easy to control animation by element's PostUpdate function, which usually passes current, maximum amount of power and, sometimes, if new maximum amount is different from previous one (oldMax ~= newMax)

current - amount of steps we need to perform.
maximum - amount of degrees per step.
oldMax ~= newMax - determines if need to reset rotation progress and force update animation, cuz amount of degrees per step was changed.

[UPDATE 2]
It's possible to make everything extremely smooth via animations, smoother than oUF_Smooth, especially when fps drops to 15-20, or power regen case, tested monk's energy, with registered UNIT_POWER_FREQUENT. But AG method has one disadvantage - animations are NOT played, while WoW is minimized. Not sure bout how serious this disadvantage is, but... what do u think, zork?
Last edited by lightspark : 12-17-13 at 09:42 AM.
Report comment to moderator  
Reply With Quote
Unread 12-17-13, 11:55 PM  
lightspark
A Rage Talon Dragon Guard
 
lightspark's Avatar
AddOn Author - Click to view AddOns

Forum posts: 305
File comments: 799
Uploads: 6
Okay, done with testing, implemented powers(mana, rage, etc) via Animations and fake StatusBar element.
We need a fake SB to utilize oUF's PostUpdate hooks.
Lua Code:
  1. local function CF_CreatePowerBar(self, texture, position)
  2.     local POWER_LAYOUT = {
  3.         ["LEFT"] = {"RIGHT", 70, 140, 0.5, 0, -1, 1, 0},
  4.         ["TOP"] = {"BOTTOM", 140, 70, 0, -0.5, -1, 1, 270},
  5.         ["RIGHT"] = {"LEFT", 70, 140, -0.5, 0, 1, -1, 180},
  6.         ["BOTTOM"] = {"TOP", 140, 70, 0, 0.5, 1, -1, 90},
  7.     }
  8.     local anchorPoint, width, height, w_multiplier, h_multiplier, CW, ACW, initAngle = unpack(POWER_LAYOUT[position])
  9.  
  10.     local scrollFrame = CreateFrame("ScrollFrame", nil, self)
  11.     scrollFrame:SetSize(width, height)
  12.     scrollFrame:SetPoint(anchorPoint, self, "CENTER", 0, 0)
  13.  
  14.     local scrollChild = CreateFrame("Frame")
  15.     scrollChild:SetSize(width, height)
  16.  
  17.     scrollFrame:SetScrollChild(scrollChild)
  18.  
  19.     local scrollTexture = scrollChild:CreateTexture("$parentActualPowerBar", "BACKGROUND", nil, -6)
  20.     scrollTexture:SetTexture(texture)
  21.     scrollTexture:SetSize(sqrt(2) * math.max(width, height), sqrt(2) * math.max(width, height))
  22.     scrollTexture:SetPoint("CENTER", width * w_multiplier, height * h_multiplier)
  23.  
  24.     scrollTexture.ag = scrollTexture:CreateAnimationGroup()
  25.     scrollTexture.ag:SetIgnoreFramerateThrottle(true)
  26.  
  27.     local AG = scrollTexture.ag
  28.  
  29.     AG.anim = AG:CreateAnimation("Rotation")
  30.     AG.anim:SetSmoothing("OUT")
  31.  
  32.     AG.oldCur, AG.oldMax, AG.initAngle, AG.initUpdate, AG.CW, AG.ACW = 0, 0, initAngle, true, CW, ACW
  33.  
  34.     scrollTexture:SetRotation(math.rad(AG.initAngle))
  35.     scrollTexture.degrees = AG.nit_angle
  36.  
  37.     AG:SetScript("OnFinished", function (self, ...)
  38.         local scrollTexture = self:GetParent()
  39.         self.oldCur = self.newCur
  40.         scrollTexture:SetRotation(math.rad(scrollTexture.degrees))
  41.     end)
  42.  
  43.     AG:SetScript("OnStop", function (self, ...)
  44.         local scrollTexture = self:GetParent()
  45.         scrollTexture:SetRotation(math.rad(scrollTexture.degrees))
  46.     end)
  47.  
  48.     AG:SetScript("OnPlay", function (self, ...)
  49.         self.initUpdate = false
  50.  
  51.         local scrollTexture = self:GetParent()
  52.         if scrollTexture.degrees >= 360 then
  53.             scrollTexture.degrees = scrollTexture.degrees - 360 + (self.anim:GetDegrees())
  54.         elseif scrollTexture.degrees <= -360 then
  55.             scrollTexture.degrees = 0 + (self.anim:GetDegrees())
  56.         else
  57.             scrollTexture.degrees = scrollTexture.degrees + (self.anim:GetDegrees())
  58.         end
  59.     end)
  60.  
  61.     return scrollTexture
  62. end
  63.  
  64. local function CF_UpdatePowerBar(self, unit, cur, max)
  65.     local AG = self.actualBar.ag
  66.     local step = 180 / max
  67.  
  68.     if AG.oldMax ~= max then -- this part is mostly for class resources, here we reset our bar to its initial state.
  69.         if AG:IsPlaying() then AG:Stop() end
  70.  
  71.         AG.initUpdate = true
  72.         AG.oldCur = 0
  73.  
  74.         self.actualBar:SetVertexColor(self:GetStatusBarColor())
  75.         self.actualBar:SetRotation(math.rad(AG.initAngle))
  76.         self.actualBar.degrees = AG.initAngle
  77.     end
  78.  
  79.     AG.oldMax = max
  80.  
  81.     local direction
  82.     if AG.oldCur > cur then -- ACW
  83.         direction = AG.ACW
  84.     elseif AG.oldCur <= cur then -- CW
  85.         direction = AG.CW
  86.     end
  87.  
  88.     if not AG:IsPlaying() and (AG.anim:IsDone() or AG.initUpdate) then
  89.         local steps_to_do = math.abs(cur - AG.oldCur)
  90.  
  91.         if steps_to_do ~= 0 then
  92.             AG.newCur = cur
  93.  
  94.             AG.anim:SetDuration(0.175 + 0.475 * math.max(steps_to_do / max, 10 / GetFramerate())) -- fps dependent duration
  95.             AG.anim:SetDegrees(step * direction * steps_to_do)
  96.  
  97.             AG:Play()
  98.             AG:Finish()
  99.         end
  100.     end
  101.  
  102.     ns.UpdatePower(self, unit, cur, max)
  103. end
  104.  
  105. self.Power = CreateFrame("StatusBar", "$parentPower", self)
  106. self.Power.actualBar = CF_CreatePowerBar(self, ppTexture, "RIGHT")
  107. self.Power.PostUpdate = unit == "player" and CF_UpdatePowerBar or ns.UpdatePower
  108. self.Power.Smooth = unit ~= "player"

CF_CreatePowerBar's body is not that different from one in zork's rTestRing, although i did some adjustments. U can find details on OnPlay, OnStop and OnFinish scripts in my previous posts.

CF_UpdatePowerBar function. As I said before I utilize power's postupdate hook, but instead of my previous idea to animate each power regen tick separately, I decided to stack few ticks together, while previous animation is being played and then animate them all together.
As for smoothness of an animation, thx to zork I took a deeper look into this part, we stack ticks together, but when fps drops really low, around 8, rotation becomes inconsistent, to avoid this effect I made duration be fps dependent. When fps drops, we make our animation play longer, so we can stack more ticks, which allows us to get rid of inconsistency.

If u plan to use this ScrollFrame/AnimationGroup approach in ur layout, please, credit zork and me for our work.
Last edited by lightspark : 12-18-13 at 09:44 AM.
Report comment to moderator  
Reply With Quote
Post A Reply



Category Jump: