You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
435 lines
12 KiB
435 lines
12 KiB
------------------------------------------------------------------------
|
|
-- Animation Functions
|
|
------------------------------------------------------------------------
|
|
local E, L, V, P, G = unpack(ElvUI)
|
|
|
|
local _G = _G
|
|
local random, next = random, next
|
|
local unpack, strsub = unpack, strsub
|
|
|
|
--[[ just to test the number thing
|
|
local t = UIParent:CreateFontString(nil, 'OVERLAY', 'GameTooltipText')
|
|
t:SetText(0)
|
|
t:Point('CENTER')
|
|
t:FontTemplate(nil, 20)
|
|
E:SetUpAnimGroup(t, 'Number', 10, 5)
|
|
|
|
local b = CreateFrame('BUTTON', nil, UIParent)
|
|
b:Point('CENTER', 0, -100)
|
|
b:SetTemplate()
|
|
b:Size(40, 30)
|
|
b:EnableMouse(true)
|
|
b:SetScript('OnClick', function()
|
|
if t:GetText() == 10 then
|
|
t.NumberAnim:SetChange(0)
|
|
t.NumberAnimGroup:Play()
|
|
else
|
|
t.NumberAnim:SetChange(10)
|
|
t.NumberAnimGroup:Play()
|
|
end
|
|
end)
|
|
]]
|
|
|
|
E.AnimShake = {{-9,7,-7,12}, {-5,9,-9,5}, {-5,7,-7,5}, {-9,9,-9,9}, {-5,7,-7,5}, {-9,7,-9,5}}
|
|
E.AnimShakeH = {-5,5,-2,5,-2,5}
|
|
E.AnimMoveOut = function(out1) out1.parent:Hide() end
|
|
E.AnimElastic = {
|
|
function(anim) anim:Stop() anim.elastic[2]:Play() end,
|
|
function(anim) anim:Stop() if anim.loop then anim.elastic[1]:Play() end end,
|
|
function(anim) anim:Stop() anim.elastic[4]:Play() end,
|
|
function(anim) anim:Stop() if anim.loop then anim.elastic[3]:Play() end end
|
|
}
|
|
|
|
function E:FlashLoopFinished(requested)
|
|
if not requested then self:Play() end
|
|
end
|
|
|
|
function E:RandomAnimShake(index)
|
|
local p1, p2, p3, p4 = unpack(E.AnimShake[index])
|
|
return random(p1, p2), random(p3, p4)
|
|
end
|
|
|
|
function E:SetUpAnimGroup(obj, animType, ...)
|
|
if not animType then -- default it to something basic
|
|
animType = 'Flash'
|
|
end
|
|
|
|
local shortType = strsub(animType, 1, 5)
|
|
if shortType == 'Flash' then
|
|
obj.anim = obj:CreateAnimationGroup('Flash')
|
|
obj.anim.fadein = obj.anim:CreateAnimation('ALPHA', 'FadeIn')
|
|
obj.anim.fadein:SetFromAlpha(0)
|
|
obj.anim.fadein:SetToAlpha(1)
|
|
obj.anim.fadein:SetOrder(2)
|
|
|
|
obj.anim.fadeout = obj.anim:CreateAnimation('ALPHA', 'FadeOut')
|
|
obj.anim.fadeout:SetFromAlpha(1)
|
|
obj.anim.fadeout:SetToAlpha(0)
|
|
obj.anim.fadeout:SetOrder(1)
|
|
|
|
if animType == 'FlashLoop' then
|
|
obj.anim:SetScript('OnFinished', E.FlashLoopFinished)
|
|
end
|
|
elseif shortType == 'Shake' then
|
|
local shake = obj:CreateAnimationGroup(animType)
|
|
shake:SetLooping('REPEAT')
|
|
shake.path = shake:CreateAnimation('Path')
|
|
|
|
if animType == 'Shake' then
|
|
shake.path:SetDuration(0.7)
|
|
obj.shake = shake
|
|
elseif animType == 'ShakeH' then
|
|
shake.path:SetDuration(2)
|
|
obj.shakeh = shake
|
|
end
|
|
|
|
for i = 1, 6 do
|
|
local point = shake.path:CreateControlPoint()
|
|
point:SetOrder(i)
|
|
|
|
if animType == 'Shake' then
|
|
point:SetOffset(E:RandomAnimShake(i))
|
|
else
|
|
point:SetOffset(E.AnimShakeH[i], 0)
|
|
end
|
|
|
|
shake.path[i] = point
|
|
end
|
|
elseif animType == 'Elastic' then
|
|
local width, height, duration, loop = ...
|
|
local elastic = _G.CreateAnimationGroup(obj)
|
|
obj.elastic = elastic
|
|
|
|
for i = 1, 4 do
|
|
local anim = elastic:CreateAnimation(i < 3 and 'width' or 'height')
|
|
anim:SetChange((i==1 and width*0.45) or (i==2 and width) or (i==3 and height*0.45) or height)
|
|
anim:SetEasing('inout-elastic')
|
|
anim:SetDuration(duration)
|
|
anim:SetScript('OnFinished', E.AnimElastic[i])
|
|
anim.elastic = elastic
|
|
anim.loop = loop
|
|
|
|
elastic[i] = anim
|
|
end
|
|
elseif animType == 'Number' then
|
|
local endingNumber, duration = ...
|
|
obj.NumberAnimGroup = _G.CreateAnimationGroup(obj)
|
|
obj.NumberAnim = obj.NumberAnimGroup:CreateAnimation('number')
|
|
obj.NumberAnim:SetChange(endingNumber)
|
|
obj.NumberAnim:SetEasing('in-circular')
|
|
obj.NumberAnim:SetDuration(duration)
|
|
elseif animType == 'Spinner' then
|
|
if not obj.Spinner then
|
|
local spinner = obj:CreateTexture()
|
|
spinner:SetTexture(443270) -- Interface\Common\StreamFrame
|
|
spinner:SetPoint('CENTER')
|
|
spinner:SetAlpha(0.5)
|
|
obj.Spinner = spinner
|
|
end
|
|
|
|
if not obj.Circle then
|
|
local circle = obj:CreateTexture(nil, 'BORDER')
|
|
circle:SetTexture(443269) -- Interface\Common\StreamCircle
|
|
circle:SetPoint('CENTER')
|
|
obj.Circle = circle
|
|
|
|
local anim = circle:CreateAnimationGroup()
|
|
anim:SetLooping('REPEAT')
|
|
circle.Anim = anim
|
|
|
|
local rotation = anim:CreateAnimation('Rotation')
|
|
rotation:SetDuration(1)
|
|
rotation:SetDegrees(-360)
|
|
anim.Rotation = rotation
|
|
end
|
|
|
|
if not obj.Spark then
|
|
local spark = obj:CreateTexture(nil, 'OVERLAY')
|
|
spark:SetTexture(457289) -- Interface\Common\StreamSpark
|
|
spark:SetPoint('CENTER')
|
|
obj.Spark = spark
|
|
|
|
local anim = spark:CreateAnimationGroup()
|
|
anim:SetLooping('REPEAT')
|
|
spark.Anim = anim
|
|
|
|
local rotation = anim:CreateAnimation('Rotation')
|
|
rotation:SetDuration(1)
|
|
rotation:SetDegrees(-360)
|
|
anim.Rotation = rotation
|
|
end
|
|
else
|
|
local x, y, duration, customName = ...
|
|
local anim = obj:CreateAnimationGroup('Move_In')
|
|
obj[customName or 'anim'] = anim
|
|
|
|
-- anim play will cause it to move
|
|
anim.in1 = anim:CreateAnimation('Translation')
|
|
anim.in1:SetDuration(0)
|
|
anim.in1:SetOrder(1)
|
|
anim.in1:SetOffset(x, y)
|
|
|
|
anim.in2 = anim:CreateAnimation('Translation')
|
|
anim.in2:SetDuration(duration)
|
|
anim.in2:SetOrder(2)
|
|
anim.in2:SetSmoothing('OUT')
|
|
anim.in2:SetOffset(-x, -y)
|
|
|
|
-- out animation to play backwards (to start position of anim play)
|
|
anim.out1 = obj:CreateAnimationGroup('Move_Out')
|
|
anim.out1:SetScript('OnFinished', E.AnimMoveOut)
|
|
anim.out1.parent = obj
|
|
|
|
anim.out2 = anim.out1:CreateAnimation('Translation')
|
|
anim.out2:SetDuration(duration)
|
|
anim.out2:SetOrder(1)
|
|
anim.out2:SetSmoothing('IN')
|
|
anim.out2:SetOffset(x, y)
|
|
end
|
|
end
|
|
|
|
function E:Elasticize(obj, width, height)
|
|
if not obj.elastic then
|
|
E:SetUpAnimGroup(obj, 'Elastic', width or obj:GetWidth(), height or obj:GetHeight(), 2, false)
|
|
end
|
|
|
|
obj.elastic[1]:Play()
|
|
obj.elastic[3]:Play()
|
|
end
|
|
|
|
function E:StopElasticize(obj)
|
|
if obj.elastic then
|
|
obj.elastic[1]:Stop(true)
|
|
obj.elastic[3]:Stop(true)
|
|
end
|
|
end
|
|
|
|
function E:Shake(obj)
|
|
if not obj.shake then
|
|
E:SetUpAnimGroup(obj, 'Shake')
|
|
end
|
|
|
|
obj.shake:Play()
|
|
end
|
|
|
|
function E:StopShake(obj)
|
|
if obj.shake then
|
|
obj.shake:Finish()
|
|
end
|
|
end
|
|
|
|
function E:ShakeHorizontal(obj)
|
|
if not obj.shakeh then
|
|
E:SetUpAnimGroup(obj, 'ShakeH')
|
|
end
|
|
|
|
obj.shakeh:Play()
|
|
end
|
|
|
|
function E:StopShakeHorizontal(obj)
|
|
if obj.shakeh then
|
|
obj.shakeh:Finish()
|
|
end
|
|
end
|
|
|
|
function E:Flash(obj, duration, loop)
|
|
if not obj.anim then
|
|
E:SetUpAnimGroup(obj, loop and 'FlashLoop' or 'Flash')
|
|
end
|
|
|
|
if not obj.anim:IsPlaying() then
|
|
obj.anim.fadein:SetDuration(duration)
|
|
obj.anim.fadeout:SetDuration(duration)
|
|
obj.anim:Play()
|
|
end
|
|
end
|
|
|
|
function E:StopFlash(obj)
|
|
if obj.anim and obj.anim:IsPlaying() then
|
|
obj.anim:Stop()
|
|
end
|
|
end
|
|
|
|
function E:StartSpinner(obj, left, top, right, bottom, size, r, g, b)
|
|
if not obj.Spinner then
|
|
E:SetUpAnimGroup(obj, 'Spinner')
|
|
end
|
|
|
|
obj.Spark:Size(size or 48)
|
|
obj.Spinner:Size(size or 48)
|
|
obj.Circle:Size(size or 48)
|
|
obj.Circle:SetVertexColor(r or 1, g or 0.82, b or 0)
|
|
|
|
obj:ClearAllPoints()
|
|
|
|
if top or bottom or left or right then
|
|
obj:Point('TOPLEFT', left or 0, top or 0)
|
|
obj:Point('BOTTOMRIGHT', right or 0, bottom or 0)
|
|
else
|
|
obj:SetAllPoints()
|
|
end
|
|
|
|
if not obj.Circle.Anim:IsPlaying() then
|
|
obj.Circle.Anim:Play()
|
|
obj.Spark.Anim:Play()
|
|
obj:Show()
|
|
end
|
|
end
|
|
|
|
function E:StopSpinner(obj)
|
|
if obj.Circle and obj.Circle.Anim:IsPlaying() then
|
|
obj.Circle.Anim:Stop()
|
|
obj.Spark.Anim:Stop()
|
|
obj:Hide()
|
|
end
|
|
end
|
|
|
|
function E:SlideIn(obj, customName)
|
|
local anim = obj[customName or 'anim']
|
|
if not anim then return end
|
|
|
|
anim.out1:Stop() -- out1 OnFinish will call Hide, see SlideOut
|
|
anim:Play()
|
|
obj:Show() -- Show is likely a secure var
|
|
end
|
|
|
|
function E:SlideOut(obj, customName)
|
|
local anim = obj[customName or 'anim']
|
|
if not anim then return end
|
|
|
|
anim:Finish()
|
|
anim:Stop()
|
|
anim.out1:Play() -- triggers AnimMoveOut which calls Hide (likely secure var) on obj
|
|
end
|
|
|
|
local FADEFRAMES, FADEMANAGER = {}, CreateFrame('FRAME')
|
|
FADEMANAGER.delay = 0.05
|
|
|
|
function E:UIFrameFade_OnUpdate(elapsed)
|
|
FADEMANAGER.timer = (FADEMANAGER.timer or 0) + elapsed
|
|
|
|
if FADEMANAGER.timer > FADEMANAGER.delay then
|
|
FADEMANAGER.timer = 0
|
|
|
|
for frame, info in next, FADEFRAMES do
|
|
-- Reset the timer if there isn't one, this is just an internal counter
|
|
if frame:IsVisible() then
|
|
info.fadeTimer = (info.fadeTimer or 0) + (elapsed + FADEMANAGER.delay)
|
|
else
|
|
info.fadeTimer = info.timeToFade + 1
|
|
end
|
|
|
|
-- If the fadeTimer is less then the desired fade time then set the alpha otherwise hold the fade state, call the finished function, or just finish the fade
|
|
if info.fadeTimer < info.timeToFade then
|
|
if info.mode == 'IN' then
|
|
frame:SetAlpha((info.fadeTimer / info.timeToFade) * info.diffAlpha + info.startAlpha)
|
|
else
|
|
frame:SetAlpha(((info.timeToFade - info.fadeTimer) / info.timeToFade) * info.diffAlpha + info.endAlpha)
|
|
end
|
|
else
|
|
frame:SetAlpha(info.endAlpha)
|
|
|
|
-- If there is a fadeHoldTime then wait until its passed to continue on
|
|
if info.fadeHoldTime and info.fadeHoldTime > 0 then
|
|
info.fadeHoldTime = info.fadeHoldTime - elapsed
|
|
else
|
|
-- Complete the fade and call the finished function if there is one
|
|
E:UIFrameFadeRemoveFrame(frame)
|
|
|
|
if info.finishedFunc then
|
|
if info.finishedArgs then
|
|
info.finishedFunc(unpack(info.finishedArgs))
|
|
else -- optional method
|
|
info.finishedFunc(info.finishedArg1, info.finishedArg2, info.finishedArg3, info.finishedArg4, info.finishedArg5)
|
|
end
|
|
|
|
if not info.finishedFuncKeep then
|
|
info.finishedFunc = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if not next(FADEFRAMES) then
|
|
FADEMANAGER:SetScript('OnUpdate', nil)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Generic fade function
|
|
function E:UIFrameFade(frame, info)
|
|
if not frame or frame:IsForbidden() then return end
|
|
|
|
if not info.mode then
|
|
info.mode = 'IN'
|
|
end
|
|
|
|
if info.mode == 'IN' then
|
|
if not info.startAlpha then info.startAlpha = 0 end
|
|
if not info.endAlpha then info.endAlpha = 1 end
|
|
if not info.diffAlpha then info.diffAlpha = info.endAlpha - info.startAlpha end
|
|
else
|
|
if not info.startAlpha then info.startAlpha = 1 end
|
|
if not info.endAlpha then info.endAlpha = 0 end
|
|
if not info.diffAlpha then info.diffAlpha = info.startAlpha - info.endAlpha end
|
|
end
|
|
|
|
frame.fadeInfo = info
|
|
frame:SetAlpha(info.startAlpha)
|
|
|
|
if not FADEFRAMES[frame] then
|
|
FADEFRAMES[frame] = info -- read below comment
|
|
FADEMANAGER:SetScript('OnUpdate', E.UIFrameFade_OnUpdate)
|
|
else
|
|
FADEFRAMES[frame] = info -- keep these both, we need this updated in the event its changed to another ref from a plugin or sth, don't move it up!
|
|
end
|
|
end
|
|
|
|
-- Convenience function to do a simple fade in
|
|
function E:UIFrameFadeIn(frame, timeToFade, startAlpha, endAlpha)
|
|
if not frame or frame:IsForbidden() then return end
|
|
|
|
if frame.FadeObject then
|
|
frame.FadeObject.fadeTimer = nil
|
|
else
|
|
frame.FadeObject = {}
|
|
end
|
|
|
|
frame.FadeObject.mode = 'IN'
|
|
frame.FadeObject.timeToFade = timeToFade
|
|
frame.FadeObject.startAlpha = startAlpha
|
|
frame.FadeObject.endAlpha = endAlpha
|
|
frame.FadeObject.diffAlpha = endAlpha - startAlpha
|
|
|
|
E:UIFrameFade(frame, frame.FadeObject)
|
|
end
|
|
|
|
-- Convenience function to do a simple fade out
|
|
function E:UIFrameFadeOut(frame, timeToFade, startAlpha, endAlpha)
|
|
if not frame or frame:IsForbidden() then return end
|
|
|
|
if frame.FadeObject then
|
|
frame.FadeObject.fadeTimer = nil
|
|
else
|
|
frame.FadeObject = {}
|
|
end
|
|
|
|
frame.FadeObject.mode = 'OUT'
|
|
frame.FadeObject.timeToFade = timeToFade
|
|
frame.FadeObject.startAlpha = startAlpha
|
|
frame.FadeObject.endAlpha = endAlpha
|
|
frame.FadeObject.diffAlpha = startAlpha - endAlpha
|
|
|
|
E:UIFrameFade(frame, frame.FadeObject)
|
|
end
|
|
|
|
function E:UIFrameFadeRemoveFrame(frame)
|
|
if frame and FADEFRAMES[frame] then
|
|
if frame.FadeObject then
|
|
frame.FadeObject.fadeTimer = nil
|
|
end
|
|
|
|
FADEFRAMES[frame] = nil
|
|
end
|
|
end
|
|
|