12-22-22, 08:20 AM | #1 |
Alright guys I need your help on this one.
It's been many years since I posted on here. But I'm back and need a lot of help with this code.
We all know WeakAuras has a ring feature for Unit Frames health, mana, power or anything you can think of for it but I'm trying to make a stand alone add-on just for the Unit Frames. This code works but the animation doesn't run as smoothly as it does in WeakAuras or have key features like a option display in game so we can set the start and end angles where we need them to be, which color to pick, ect. So I'm asking for anyone who would like to help build this code up more and get it to that level of greatness. That's what it's all about. Someone here might be an expert on how to display options in game for this or someone else might know how to make the animation run smoother. Your welcome to have a crack at it. Lots of credit goes to Fizzlemizz she helped me with most of the code while I would be in game putting it in place. Sorry I don't have the textures to share to see it in game but if you know anyway to add in a start and end angle option or make this run smoother with the animation please do! Thank you!!! Code:
-- Usage: -- spinner = CreateSpinner(parent) -- spinner:SetTexture('texturePath') -- spinner:SetBlendMode('blendMode') -- spinner:SetVertexColor(r, g, b) -- spinner:SetClockwise(boolean) -- true to fill clockwise, false to fill counterclockwise -- spinner:SetReverse(boolean) -- true to empty the bar instead of filling it -- spinner:SetValue(percent) -- value between 0 and 1 to fill the bar to -- Some math stuff local cos, sin, pi2, halfpi = math.cos, math.sin, math.rad(360), math.rad(90) local function Transform(tx, x, y, angle, aspect) -- Translates texture to x, y and rotates about its center local c, s = cos(angle), sin(angle) local y, oy = y / aspect, 0.5 / aspect local ULx, ULy = 0.5 + (x - 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x - 0.5) * s) * aspect local LLx, LLy = 0.5 + (x - 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x - 0.5) * s) * aspect local URx, URy = 0.5 + (x + 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x + 0.5) * s) * aspect local LRx, LRy = 0.5 + (x + 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x + 0.5) * s) * aspect tx:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy) end -- Permanently pause our rotation animation after it starts playing local function OnPlayUpdate(self) self:SetScript('OnUpdate', nil) self:Pause() end local function OnPlay(self) self:SetScript('OnUpdate', OnPlayUpdate) end local function SetValue(self, value) -- Correct invalid ranges, preferably just don't feed it invalid numbers if value > 1 then value = 1 elseif value < 0 then value = 0 end -- Reverse our normal behavior if self._reverse then value = 1 - value end -- Determine which quadrant we're in local q, quadrant = self._clockwise and (1 - value) or value -- 4 - floor(value / 0.25) if q >= 0.75 then quadrant = 1 elseif q >= 0.5 then quadrant = 2 elseif q >= 0.25 then quadrant = 3 else quadrant = 4 end if self._quadrant ~= quadrant then self._quadrant = quadrant -- Show/hide necessary textures if we need to if self._clockwise then for i = 1, 4 do self._textures[i]:SetShown(i < quadrant) end else for i = 1, 4 do self._textures[i]:SetShown(i > quadrant) end end -- Move scrollframe/wedge to the proper quadrant self._scrollframe:SetAllPoints(self._textures[quadrant]) end -- Rotate the things local rads = value * pi2 if not self._clockwise then rads = -rads + halfpi end Transform(self._wedge, -0.5, -0.5, rads, self._aspect) self._rotation:SetRadians(-rads) end local function SetClockwise(self, clockwise) self._clockwise = clockwise end local function SetReverse(self, reverse) self._reverse = reverse end local function OnSizeChanged(self, width, height) self._wedge:SetSize(width, height) -- it's important to keep this texture sized correctly self._aspect = width / height -- required to calculate the texture coordinates end -- Creates a function that calls a method on all textures at once local function CreateTextureFunction(func, self, ...) return function(self, ...) for i = 1, 4 do local tx = self._textures[i] tx[func](tx, ...) end self._wedge[func](self._wedge, ...) end end -- Pass calls to these functions on our frame to its textures local TextureFunctions = { SetTexture = CreateTextureFunction('SetTexture'), SetBlendMode = CreateTextureFunction('SetBlendMode'), SetVertexColor = CreateTextureFunction('SetVertexColor'), } local function CreateSpinner(parent) local spinner = CreateFrame('Frame', nil, parent) -- ScrollFrame clips the actively animating portion of the spinner local scrollframe = CreateFrame('ScrollFrame', nil, spinner) scrollframe:SetPoint('BOTTOMLEFT', spinner, 'CENTER') scrollframe:SetPoint('TOPRIGHT') spinner._scrollframe = scrollframe local scrollchild = CreateFrame('frame', nil, scrollframe) scrollframe:SetScrollChild(scrollchild) scrollchild:SetAllPoints(scrollframe) -- Wedge thing local wedge = scrollchild:CreateTexture() wedge:SetPoint('BOTTOMRIGHT', spinner, 'CENTER') spinner._wedge = wedge -- Top Right local trTexture = spinner:CreateTexture() trTexture:SetPoint('BOTTOMLEFT', spinner, 'CENTER') trTexture:SetPoint('TOPRIGHT') trTexture:SetTexCoord(0.5, 1, 0, 0.5) -- Bottom Right local brTexture = spinner:CreateTexture() brTexture:SetPoint('TOPLEFT', spinner, 'CENTER') brTexture:SetPoint('BOTTOMRIGHT') brTexture:SetTexCoord(0.5, 1, 0.5, 1) -- Bottom Left local blTexture = spinner:CreateTexture() blTexture:SetPoint('TOPRIGHT', spinner, 'CENTER') blTexture:SetPoint('BOTTOMLEFT') blTexture:SetTexCoord(0, 0.5, 0.5, 1) -- Top Left local tlTexture = spinner:CreateTexture() tlTexture:SetPoint('BOTTOMRIGHT', spinner, 'CENTER') tlTexture:SetPoint('TOPLEFT') tlTexture:SetTexCoord(0, 0.5, 0, 0.5) -- /4|1\ -- Clockwise texture arrangement -- \3|2/ -- spinner._textures = {trTexture, brTexture, blTexture, tlTexture} spinner._quadrant = nil -- Current active quadrant spinner._clockwise = true -- fill clockwise spinner._reverse = false -- Treat the provided value as its inverse, eg. 75% will display as 25% spinner._aspect = 1 -- aspect ratio, width / height of spinner frame spinner:HookScript('OnSizeChanged', OnSizeChanged) for method, func in pairs(TextureFunctions) do spinner[method] = func end spinner.SetClockwise = SetClockwise spinner.SetReverse = SetReverse spinner.SetValue = SetValue local group = wedge:CreateAnimationGroup() local rotation = group:CreateAnimation('Rotation') spinner._rotation = rotation rotation:SetSmoothing("IN_OUT") rotation:SetDuration(0) rotation:SetEndDelay(1) rotation:SetOrigin('BOTTOMRIGHT', 0, 0) group:SetScript('OnPlay', OnPlay) group:Play() return spinner end local spinner1 = CreateSpinner(UIParent) spinner1:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait) spinner1:SetSize(116, 108) spinner1:SetTexture("Interface\\Addons\\Images\\Ring_20px") spinner1:SetVertexColor(0, 1, 0) spinner1:SetClockwise(false) spinner1:SetReverse(false) spinner1:Hide() spinner1.Background = spinner1:CreateTexture() spinner1.Background:SetDrawLayer("BACKGROUND", -1) spinner1.Background:SetSize(155, 142) spinner1.Background:SetPoint("CENTER", TargetFrame.TargetFrameContainer.Portrait) spinner1.Background:SetTexture("Interface\\Addons\\Images\\FullCircleFrameTwo") local CenterOverlay = CreateFrame("Frame", nil, spinner1) CenterOverlay:SetFrameLevel(0) CenterOverlay:SetSize(100, 100) CenterOverlay:SetPoint("CENTER") CenterOverlay.Texture = CenterOverlay:CreateTexture() CenterOverlay.Texture:SetAllPoints() CenterOverlay.Texture:SetTexture("Interface\\Masks\\CircleMaskScalable") CenterOverlay.Texture:SetVertexColor(0, 0, 0) local healthmax = 0 local health = 0 spinner1:RegisterUnitEvent("UNIT_HEALTH", target) spinner1:RegisterEvent("PLAYER_TARGET_CHANGED") spinner1:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_TARGET_CHANGED" then if not UnitExists("target") then spinner1:Hide() return end spinner1:Show() end healthmax = UnitHealthMax("target") health = UnitHealth("target") local h = health / healthmax spinner1:SetValue(h) end) local spinner2 = CreateSpinner(UIParent) spinner2:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait) spinner2:SetSize(158, 148) spinner2:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundTwo") spinner2:SetVertexColor(1, 1, 1) spinner2:SetClockwise(true) spinner2:SetReverse(false) spinner2:Hide() local powermax = 0 local power = 0 spinner2:RegisterUnitEvent("UNIT_POWER_FREQUENT", target) spinner2:RegisterEvent("PLAYER_TARGET_CHANGED") spinner2:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_TARGET_CHANGED" then if not UnitExists("target") then spinner2:Hide() return end spinner2:Show() end powermax = UnitPowerMax("target") power = UnitPower("target") local p = power / powermax spinner2:SetValue(p) end) local spinner3 = CreateSpinner(UIParent) spinner3:SetFrameLevel(1) spinner3:SetSize(90, 90) spinner3:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait) spinner3:SetTexture("Interface\\Masks\\CircleMaskScalable") spinner3:SetVertexColor(0.2, 0.2, 0.8) spinner3:SetClockwise(true) spinner3:SetReverse(false) spinner3:Hide() local manamax = 0 local mana = 0 spinner3:RegisterUnitEvent("UNIT_POWER_UPDATE", "target") spinner3:RegisterEvent("PLAYER_TARGET_CHANGED") spinner3:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_TARGET_CHANGED" then if not UnitExists("target") then spinner3:Hide() return end spinner3:Show() end local mana = UnitPower("target", Enum.PowerType.Mana) if not mana or mana == 0 then spinner3:SetValue(0) return end local manaMax = UnitPowerMax("target", Enum.PowerType.Mana) spinner3:SetValue(mana / manaMax) end) local spinner1 = CreateSpinner(UIParent) spinner1:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait) spinner1:SetSize(116, 108) spinner1:SetTexture("Interface\\Addons\\Images\\Ring_20px") spinner1:SetVertexColor(0, 1, 0) spinner1:SetClockwise(false) spinner1:SetReverse(false) spinner1:Hide() spinner1.Background = spinner1:CreateTexture() spinner1.Background:SetDrawLayer("BACKGROUND", -1) spinner1.Background:SetSize(155, 142) spinner1.Background:SetPoint("CENTER", TargetFrame.TargetFrameContainer.Portrait) spinner1.Background:SetTexture("Interface\\Addons\\Images\\FullCircleFrameTwo") local CenterOverlay = CreateFrame("Frame", nil, spinner1) CenterOverlay:SetFrameLevel(0) CenterOverlay:SetSize(100, 100) CenterOverlay:SetPoint("CENTER") CenterOverlay.Texture = CenterOverlay:CreateTexture() CenterOverlay.Texture:SetAllPoints() CenterOverlay.Texture:SetTexture("Interface\\Masks\\CircleMaskScalable") CenterOverlay.Texture:SetVertexColor(0, 0, 0) local healthmax = 0 local health = 0 spinner1:RegisterUnitEvent("UNIT_HEALTH", target) spinner1:RegisterEvent("PLAYER_TARGET_CHANGED") spinner1:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_TARGET_CHANGED" then if not UnitExists("target") then spinner1:Hide() return end spinner1:Show() end healthmax = UnitHealthMax("target") health = UnitHealth("target") local h = health / healthmax spinner1:SetValue(h) end) local spinner2 = CreateSpinner(UIParent) spinner2:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait) spinner2:SetSize(158, 148) spinner2:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundTwo") spinner2:SetVertexColor(1, 1, 1) spinner2:SetClockwise(true) spinner2:SetReverse(false) spinner2:Hide() local powermax = 0 local power = 0 spinner2:RegisterUnitEvent("UNIT_POWER_FREQUENT", target) spinner2:RegisterEvent("PLAYER_TARGET_CHANGED") spinner2:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_TARGET_CHANGED" then if not UnitExists("target") then spinner2:Hide() return end spinner2:Show() end powermax = UnitPowerMax("target") power = UnitPower("target") local p = power / powermax spinner2:SetValue(p) end) local spinner1 = CreateSpinner(UIParent) spinner1:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait) spinner1:SetSize(116, 108) spinner1:SetTexture("Interface\\Addons\\Images\\Ring_20px") spinner1:SetVertexColor(0, 1, 0) spinner1:SetClockwise(false) spinner1:SetReverse(false) spinner1:Hide() spinner1.Background = spinner1:CreateTexture() spinner1.Background:SetDrawLayer("BACKGROUND", -1) spinner1.Background:SetSize(155, 142) spinner1.Background:SetPoint("CENTER", TargetFrame.TargetFrameContainer.Portrait) spinner1.Background:SetTexture("Interface\\Addons\\Images\\FullCircleFrameTwo") local CenterOverlay = CreateFrame("Frame", nil, spinner1) CenterOverlay:SetFrameLevel(0) CenterOverlay:SetSize(100, 100) CenterOverlay:SetPoint("CENTER") CenterOverlay.Texture = CenterOverlay:CreateTexture() CenterOverlay.Texture:SetAllPoints() CenterOverlay.Texture:SetTexture("Interface\\Masks\\CircleMaskScalable") CenterOverlay.Texture:SetVertexColor(0, 0, 0) local healthmax = 0 local health = 0 spinner1:RegisterUnitEvent("UNIT_HEALTH", target) spinner1:RegisterEvent("PLAYER_TARGET_CHANGED") spinner1:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_TARGET_CHANGED" then if not UnitExists("target") then spinner1:Hide() return end spinner1:Show() end healthmax = UnitHealthMax("target") health = UnitHealth("target") local h = health / healthmax spinner1:SetValue(h) end) local spinner2 = CreateSpinner(UIParent) spinner2:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait) spinner2:SetSize(158, 148) spinner2:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundTwo") spinner2:SetVertexColor(1, 1, 1) spinner2:SetClockwise(true) spinner2:SetReverse(false) spinner2:Hide() local powermax = 0 local power = 0 spinner2:RegisterUnitEvent("UNIT_POWER_FREQUENT", target) spinner2:RegisterEvent("PLAYER_TARGET_CHANGED") spinner2:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_TARGET_CHANGED" then if not UnitExists("target") then spinner2:Hide() return end spinner2:Show() end powermax = UnitPowerMax("target") power = UnitPower("target") local p = power / powermax spinner2:SetValue(p) end) local spinner3 = CreateSpinner(UIParent) spinner3:SetFrameLevel(1) spinner3:SetSize(90, 90) spinner3:SetPoint('CENTER', TargetFrame.TargetFrameContainer.Portrait) spinner3:SetTexture("Interface\\Masks\\CircleMaskScalable") spinner3:SetVertexColor(0.2, 0.2, 0.8) spinner3:SetClockwise(true) spinner3:SetReverse(false) spinner3:Hide() local manamax = 0 local mana = 0 spinner3:RegisterUnitEvent("UNIT_POWER_UPDATE", "target") spinner3:RegisterEvent("PLAYER_TARGET_CHANGED") spinner3:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_TARGET_CHANGED" then if not UnitExists("target") then spinner3:Hide() return end spinner3:Show() end local mana = UnitPower("target", Enum.PowerType.Mana) if not mana or mana == 0 then spinner3:SetValue(0) return end local manaMax = UnitPowerMax("target", Enum.PowerType.Mana) spinner3:SetValue(mana / manaMax) end) local spinner4 = CreateSpinner(UIParent) spinner4:SetPoint('CENTER', PlayerFrame.PlayerFrameContainer.PlayerPortraitMask) spinner4:SetSize(116, 108) spinner4:SetTexture("Interface\\Addons\\Images\\Ring_20px") spinner4:SetVertexColor(0, 1, 0) spinner4:SetClockwise(true) spinner4:SetReverse(false) spinner4:Hide() spinner4.Background = spinner1:CreateTexture() spinner4.Background:SetDrawLayer("BACKGROUND", -1) spinner4.Background:SetSize(155, 142) spinner4.Background:SetPoint("CENTER", PlayerFrame.PlayerFrameContainer.PlayerPortraitMask) spinner4.Background:SetTexture("Interface\\Addons\\Images\\FullCircleFrameTwo") local CenterOverlay = CreateFrame("Frame", nil, spinner4) CenterOverlay:SetFrameLevel(0) CenterOverlay:SetSize(100, 100) CenterOverlay:SetPoint("CENTER", PlayerFrame.PlayerFrameContainer.PlayerPortraitMask) CenterOverlay.Texture = CenterOverlay:CreateTexture() CenterOverlay.Texture:SetAllPoints() CenterOverlay.Texture:SetTexture("Interface\\Masks\\CircleMaskScalable") CenterOverlay.Texture:SetVertexColor(0, 0, 0) local healthmax = 0 local health = 0 spinner4:RegisterUnitEvent("UNIT_HEALTH", player) spinner4:RegisterEvent("PLAYER_ENTERING_WORLD") spinner4:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_ENTERING_WORLD" then if not UnitExists("player") then spinner6:Show() return end spinner4:Show() end healthmax = UnitHealthMax("player") health = UnitHealth("player") local h = health / healthmax spinner4:SetValue(h) end) local spinner5 = CreateSpinner(UIParent) spinner5:SetPoint('CENTER', PlayerFrame.PlayerFrameContainer.PlayerPortraitMask) spinner5:SetSize(158, 148) spinner5:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundPlayer") spinner5:SetVertexColor(1, 1, 1) spinner5:SetClockwise(true) spinner5:SetReverse(false) spinner5:Hide() spinner5.Background = spinner1:CreateTexture() spinner5.Background:SetDrawLayer("BACKGROUND", -1) spinner5.Background:SetSize(155, 142) spinner5.Background:SetPoint("CENTER", PlayerFrame.PlayerFrameContainer.PlayerPortraitMask) spinner5.Background:SetTexture("Interface\\Addons\\Images\\DragonCircleBackgroundPlayer") spinner5.Background:SetVertexColor(0, 0, 0) local powermax = 0 local power = 0 spinner5:RegisterUnitEvent("UNIT_POWER_FREQUENT", player) spinner5:RegisterEvent("PLAYER_ENTERING_WORLD") spinner5:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_ENTERING_WORLD" then if not UnitExists("player") then spinner5:Hide() return end spinner5:Show() end powermax = UnitPowerMax("player") power = UnitPower("player") local p = power / powermax spinner5:SetValue(p) end) local spinner6 = CreateSpinner(UIParent) spinner6:SetFrameLevel(1) spinner6:SetSize(90, 90) spinner6:SetPoint('CENTER', PlayerFrame.PlayerFrameContainer.PlayerPortraitMask) spinner6:SetTexture("Interface\\Masks\\CircleMaskScalable") spinner6:SetVertexColor(0.2, 0.2, 0.8) spinner6:SetClockwise(true) spinner6:SetReverse(false) spinner6:Hide() local manamax = 0 local mana = 0 spinner6:RegisterUnitEvent("UNIT_POWER_UPDATE", "player") spinner6:RegisterEvent("PLAYER_ENTERING_WORLD") spinner6:SetScript("OnEvent", function(self, event, ...) if event == "PLAYER_ENTERING_WORLD" then if not UnitExists("player") then spinner6:Hide() return end spinner6:Show() end local mana = UnitPower("player", Enum.PowerType.Mana) if not mana or mana == 0 then spinner6:SetValue(0) return end local manaMax = UnitPowerMax("player", Enum.PowerType.Mana) spinner6:SetValue(mana / manaMax) end)
__________________
The Maddness Within lua |
|
12-22-22, 10:53 AM | #2 |
Take a look at zork's old project "RingThing"
https://www.wowinterface.com/downloa...heRingMod.html
__________________
AddOns: Tim @ WoWInterface Battle Tag: Mysterio#11164 Current PC Setup: PCPartPicker List |
|
12-31-22, 05:34 AM | #3 |
Fascinating title
You can also take a look at my HUD here https://github.com/watchout-mods/Elementary Particularily at the inline libraries ArcBar and LibRotate. |
|
WoWInterface » Developer Discussions » Lua/XML Help » Alright guys I need your help on this one. |
«
Previous Thread
|
Next Thread
»
|
Thread Tools | |
Display Modes | |
|
|