Advertisement
Guest User

SPINNERS

a guest
Feb 11th, 2016
21
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.03 KB | None | 0 0
  1. -- Usage:
  2. -- spinner = CreateSpinner(parent)
  3. -- spinner:SetTexture('texturePath')
  4. -- spinner:SetBlendMode('blendMode')
  5. -- spinner:SetVertexColor(r, g, b)
  6. -- spinner:SetClockwise(boolean) -- true to fill clockwise, false to fill counterclockwise
  7. -- spinner:SetReverse(boolean) -- true to empty the bar instead of filling it
  8. -- spinner:SetValue(percent) -- value between 0 and 1 to fill the bar to
  9.  
  10. -- Some math stuff
  11. local cos, sin, pi2, halfpi = math.cos, math.sin, math.rad(360), math.rad(90)
  12. local function Transform(tx, x, y, angle, aspect) -- Translates texture to x, y and rotates about its center
  13.     local c, s = cos(angle), sin(angle)
  14.     local y, oy = y / aspect, 0.5 / aspect
  15.     local ULx, ULy = 0.5 + (x - 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x - 0.5) * s) * aspect
  16.     local LLx, LLy = 0.5 + (x - 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x - 0.5) * s) * aspect
  17.     local URx, URy = 0.5 + (x + 0.5) * c - (y - oy) * s, (oy + (y - oy) * c + (x + 0.5) * s) * aspect
  18.     local LRx, LRy = 0.5 + (x + 0.5) * c - (y + oy) * s, (oy + (y + oy) * c + (x + 0.5) * s) * aspect
  19.     tx:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
  20. end
  21.  
  22. -- Permanently pause our rotation animation after it starts playing
  23. local function OnPlayUpdate(self)
  24.     self:SetScript('OnUpdate', nil)
  25.     self:Pause()
  26. end
  27.  
  28. local function OnPlay(self)
  29.     self:SetScript('OnUpdate', OnPlayUpdate)
  30. end
  31.  
  32. local function SetValue(self, value)
  33.     -- Correct invalid ranges, preferably just don't feed it invalid numbers
  34.     if value > 1 then value = 1
  35.     elseif value < 0 then value = 0 end
  36.    
  37.     -- Reverse our normal behavior
  38.     if self._reverse then
  39.         value = 1 - value
  40.     end
  41.    
  42.     -- Determine which quadrant we're in
  43.     local q, quadrant = self._clockwise and (1 - value) or value -- 4 - floor(value / 0.25)
  44.     if q >= 0.75 then
  45.         quadrant = 1
  46.     elseif q >= 0.5 then
  47.         quadrant = 2
  48.     elseif q >= 0.25 then
  49.         quadrant = 3
  50.     else
  51.         quadrant = 4
  52.     end
  53.    
  54.     -- Show/hide necessary textures if we need to
  55.     if self._quadrant ~= quadrant then
  56.         self._quadrant = quadrant
  57.         if self._clockwise then
  58.             for i = 1, 4 do
  59.                 self._textures[i]:SetShown(i < quadrant)
  60.             end
  61.         else
  62.             for i = 1, 4 do
  63.                 self._textures[i]:SetShown(i > quadrant)
  64.             end
  65.         end
  66.     end
  67.    
  68.     -- Move scrollframe/wedge to the proper quadrant
  69.     self._scrollframe:SetAllPoints(self._textures[quadrant])   
  70.  
  71.     -- Rotate the things
  72.     local rads = value * pi2
  73.     if not self._clockwise then rads = -rads + halfpi end
  74.     Transform(self._wedge, -0.5, -0.5, rads, self._aspect)
  75.     self._rotation:SetRadians(-rads)
  76. end
  77.  
  78. local function SetClockwise(self, clockwise)
  79.     self._clockwise = clockwise
  80. end
  81.  
  82. local function SetReverse(self, reverse)
  83.     self._reverse = reverse
  84. end
  85.  
  86. local function OnSizeChanged(self, width, height)
  87.     self._wedge:SetSize(width, height) -- it's important to keep this texture sized correctly
  88.     self._aspect = width / height -- required to calculate the texture coordinates
  89. end
  90.  
  91. -- Creates a function that calls a method on all textures at once
  92. local function CreateTextureFunction(func, self, ...)
  93.     return function(self, ...)
  94.         for i = 1, 4 do
  95.             local tx = self._textures[i]
  96.             tx[func](tx, ...)
  97.         end
  98.         self._wedge[func](self._wedge, ...)
  99.     end
  100. end
  101.  
  102. -- Pass calls to these functions on our frame to its textures
  103. local TextureFunctions = {
  104.     SetTexture = CreateTextureFunction('SetTexture'),
  105.     SetBlendMode = CreateTextureFunction('SetBlendMode'),
  106.     SetVertexColor = CreateTextureFunction('SetVertexColor'),
  107. }
  108.  
  109. local function CreateSpinner(parent)
  110.     local spinner = CreateFrame('Frame', nil, parent)
  111.    
  112.     -- ScrollFrame clips the actively animating portion of the spinner
  113.     local scrollframe = CreateFrame('ScrollFrame', nil, spinner)
  114.     scrollframe:SetPoint('BOTTOMLEFT', spinner, 'CENTER')
  115.     scrollframe:SetPoint('TOPRIGHT')
  116.     spinner._scrollframe = scrollframe
  117.    
  118.     local scrollchild = CreateFrame('frame', nil, scrollframe)
  119.     scrollframe:SetScrollChild(scrollchild)
  120.     scrollchild:SetAllPoints(scrollframe)
  121.    
  122.     -- Wedge thing
  123.     local wedge = scrollchild:CreateTexture()
  124.     wedge:SetPoint('BOTTOMRIGHT', spinner, 'CENTER')
  125.     spinner._wedge = wedge
  126.    
  127.     -- Top Right
  128.     local trTexture = spinner:CreateTexture()
  129.     trTexture:SetPoint('BOTTOMLEFT', spinner, 'CENTER')
  130.     trTexture:SetPoint('TOPRIGHT')
  131.     trTexture:SetTexCoord(0.5, 1, 0, 0.5)
  132.    
  133.     -- Bottom Right
  134.     local brTexture = spinner:CreateTexture()
  135.     brTexture:SetPoint('TOPLEFT', spinner, 'CENTER')
  136.     brTexture:SetPoint('BOTTOMRIGHT')
  137.     brTexture:SetTexCoord(0.5, 1, 0.5, 1)
  138.    
  139.     -- Bottom Left
  140.     local blTexture = spinner:CreateTexture()
  141.     blTexture:SetPoint('TOPRIGHT', spinner, 'CENTER')
  142.     blTexture:SetPoint('BOTTOMLEFT')
  143.     blTexture:SetTexCoord(0, 0.5, 0.5, 1)
  144.    
  145.     -- Top Left
  146.     local tlTexture = spinner:CreateTexture()
  147.     tlTexture:SetPoint('BOTTOMRIGHT', spinner, 'CENTER')
  148.     tlTexture:SetPoint('TOPLEFT')
  149.     tlTexture:SetTexCoord(0, 0.5, 0, 0.5)
  150.    
  151.     -- /4|1\ -- Clockwise texture arrangement
  152.     -- \3|2/ --
  153.  
  154.     spinner._textures = {trTexture, brTexture, blTexture, tlTexture}
  155.     spinner._quadrant = nil -- Current active quadrant
  156.     spinner._clockwise = true -- fill clockwise
  157.     spinner._reverse = false -- Treat the provided value as its inverse, eg. 75% will display as 25%
  158.     spinner._aspect = 1 -- aspect ratio, width / height of spinner frame
  159.     spinner:HookScript('OnSizeChanged', OnSizeChanged)
  160.    
  161.     for method, func in pairs(TextureFunctions) do
  162.         spinner[method] = func
  163.     end
  164.    
  165.     spinner.SetClockwise = SetClockwise
  166.     spinner.SetReverse = SetReverse
  167.     spinner.SetValue = SetValue
  168.    
  169.     local group = wedge:CreateAnimationGroup()
  170.     local rotation = group:CreateAnimation('Rotation')
  171.     spinner._rotation = rotation
  172.     rotation:SetDuration(0)
  173.     rotation:SetEndDelay(1)
  174.     rotation:SetOrigin('BOTTOMRIGHT', 0, 0)
  175.     group:SetScript('OnPlay', OnPlay)
  176.     group:Play()
  177.    
  178.     return spinner
  179. end
  180.  
  181. ----------
  182. -- Demo
  183. ----------
  184.  
  185. local spinner1 = CreateSpinner(UIParent)
  186. spinner1:SetPoint('BOTTOMRIGHT', UIParent, 'CENTER', -2, 2)
  187. spinner1:SetSize(64, 64)
  188. spinner1:SetTexture('interface/icons/inv_mushroom_11')
  189.  
  190. spinner1:SetClockwise(false)
  191. spinner1:SetReverse(false)
  192.  
  193. local spinner2 = CreateSpinner(UIParent)
  194. spinner2:SetPoint('BOTTOMLEFT', UIParent, 'CENTER', 2, 2)
  195. spinner2:SetSize(64, 64)
  196. spinner2:SetTexture('interface/icons/inv_mushroom_11')
  197.  
  198. spinner2:SetClockwise(true)
  199. spinner2:SetReverse(false)
  200.  
  201. local spinner3 = CreateSpinner(UIParent)
  202. spinner3:SetPoint('TOPRIGHT', UIParent, 'CENTER', -2, -2)
  203. spinner3:SetSize(64, 64)
  204. spinner3:SetTexture('interface/icons/inv_mushroom_11')
  205.  
  206. spinner3:SetClockwise(true)
  207. spinner3:SetReverse(true)
  208.  
  209. local spinner4 = CreateSpinner(UIParent)
  210. spinner4:SetPoint('TOPLEFT', UIParent, 'CENTER', 2, -2)
  211. spinner4:SetSize(64, 64)
  212. spinner4:SetTexture('interface/icons/inv_mushroom_11')
  213.  
  214. spinner4:SetClockwise(false)
  215. spinner4:SetReverse(true)
  216.  
  217. local f = CreateFrame('frame')
  218. local timespent = 0
  219. f:SetScript('OnUpdate', function(self, elapsed)
  220.     timespent = timespent + elapsed
  221.     if timespent >= 3 then
  222.         timespent = 0
  223.     end
  224.    
  225.     local value = timespent / 3
  226.     spinner1:SetValue(value)
  227.     spinner2:SetValue(value)
  228.     spinner3:SetValue(value)
  229.     spinner4:SetValue(value)
  230. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement