-- YAY FOR SPARKLES~!
SparkleFrame = CreateFrame("FRAME");
local Sparkle = SparkleFrame:CreateTexture();
function Sparkle:New (sparkleFrame, sparkleTemplate)
if ( sparkleFrame.freeSparkles[1] ) then
local sparkle = sparkleFrame.freeSparkles[1];
sparkle:Reuse(sparkleTemplate);
tremove(sparkleFrame.freeSparkles, 1);
tinsert(sparkleFrame.sparkles, sparkle);
return sparkle;
end
sparkleTemplate = sparkleTemplate or "SparkleTextureNormal"
local name = sparkleFrame:GetName();
local sparkle;
if ( name ) then
sparkle = sparkleFrame:CreateTexture(name .. "Sparkle" .. sparkleFrame.numSparkles, "ARTWORK", sparkleTemplate)
else
sparkle = sparkleFrame:CreateTexture(nil, "ARTWORK", sparkleTemplate);
end
setmetatable(sparkle, self);
self.__index = self;
tinsert(sparkleFrame.sparkles, sparkle)
sparkleFrame.numSparkles = sparkleFrame.numSparkles + 1;
return sparkle;
end
function Sparkle:Free ()
local sparkleFrame = self:GetParent();
if ( self.OnFinished ) then
self:OnFinished();
end
self:Hide();
for i = 1, self.numArgs do
self["param" .. i] = nil;
end
self.name = nil;
self.elapsed = nil;
self.loop = nil;
self.Animate = nil;
tinsert(sparkleFrame.freeSparkles, self);
end
SparkleDimensions =
{
["SparkleTextureNormal"] = { height = 13, width = 13 },
["SparkleTextureKindaSmall"] = { height = 10, width = 10 },
["SparkleTextureSmall"] = { height = 7, width = 7 },
}
function Sparkle:Reuse (sparkleTemplate)
local dimensions = SparkleDimensions[sparkleTemplate]
if ( not dimensions ) then
error()
end
self:SetHeight(dimensions.height);
self:SetWidth(dimensions.width);
end
function Sparkle:SetOnFinished (func)
self.OnFinished = func;
end
function Sparkle:LinearTranslate (elapsed)
-- Parameters for LinearTranslate:
-- 1 - relativePoint, 2 - xStart, 3 - xStop, 4 - yStart, 5 - yStop, 6 - duration
local relativePoint, xStart, xStop, yStart, yStop, duration = self.param1, self.param2, self.param3, self.param4, self.param5, self.param6;
self:Show();
self.elapsed = self.elapsed + elapsed;
local xRange = xStart - xStop;
local yRange = yStart - yStop;
local xDir = ( xStart < xStop and 1 ) or -1;
local yDir = ( yStart < yStop and 1 ) or -1;
local position = self.elapsed / duration;
self:SetPoint("CENTER", "$parent", relativePoint, xStart + (math.abs(xRange * position)*xDir), yStart + (math.abs(yRange * position)*yDir));
if ( position >= 1 and self.loop ) then
self.elapsed = 0;
elseif ( position >= 1 ) then
return true;
end
return false;
end
function Sparkle:Pulse (elapsed)
-- Parameters for Sparkle:
-- relativePoint, xPos, yPos, startAlpha, maxAlpha, endAlpha, fadeInDuration, holdDuration, fadeOutDuration
local relativePoint, xPos, yPos = self.param1, self.param2, self.param3;
local startAlpha, maxAlpha, endAlpha = self.param4, self.param5, self.param6;
local fadeInDuration, holdDuration, fadeOutDuration = self.param7, self.param8, self.param9;
self:Show();
self:SetPoint("CENTER", "$parent", relativePoint, xPos, yPos);
self.elapsed = self.elapsed + elapsed;
if ( self.elapsed <= fadeInDuration ) then
local range = maxAlpha - startAlpha;
local percentage = self.elapsed/fadeInDuration;
self:SetAlpha(startAlpha + (range*percentage));
elseif ( self.elapsed <= holdDuration ) then
self:SetAlpha(maxAlpha);
elseif ( self.elapsed <= fadeOutDuration ) then
local range = maxAlpha - endAlpha;
local percentage = (self.elapsed-holdDuration)/(fadeOutDuration-holdDuration);
self:SetAlpha(maxAlpha - (range*percentage));
elseif ( self.loop ) then
self.elapsed = 0;
else
return true;
end
return false;
end
local cos = cos;
local sin = sin;
local cosTable = {};
local sinTable = {};
function Sparkle:RadialTranslate (elapsed)
-- Parameters for RadialTranslate:
-- relativePoint, radius, startDegree, stopDegree, duration
local relativePoint, offsetX, offsetY, radius, startDegree, stopDegree, duration = self.param1, self.param2, self.param3, self.param4, self.param5, self.param6, self.param7;
self:Show();
self.elapsed = self.elapsed + elapsed;
local range = startDegree - stopDegree;
local position = self.elapsed/duration
local degree = math.floor(startDegree + (range * position));
local xPos, yPos
local cosVal = cosTable[degree];
if ( cosVal ) then
xPos = offsetX + (radius * cosVal);
else
cosTable[degree] = cos(degree);
xPos = offsetX + (radius * cosTable[degree]);
end
local sinVal = sinTable[degree];
if ( sinVal ) then
yPos = offsetY + (radius * sinVal);
else
sinTable[degree] = sin(degree);
yPos = offsetY + (radius + sinTable[degree]);
end
local xPos = offsetX + (radius * cos(degree));
local yPos = offsetY + (radius * sin(degree));
self:SetPoint("CENTER", "$parent", relativePoint, xPos, yPos);
if ( position >= 1 and self.loop ) then
self.elapsed = 0;
elseif ( position >= 1 ) then
return true;
end
return false;
end
function SparkleFrame:New (parent)
local sparkleFrame;
if ( parent ) then
sparkleFrame = CreateFrame("FRAME", parent:GetName() .. "SparkleFrame", parent);
sparkleFrame:SetPoint("TOPLEFT");
sparkleFrame:SetPoint("BOTTOMRIGHT");
else
sparkleFrame = CreateFrame("FRAME");
end
setmetatable(sparkleFrame, self);
self.__index = self;
sparkleFrame.timeSinceLast = 0;
sparkleFrame.updateTime = 0.0334 -- Roughly 30 frames per second.
-- sparkleFrame.updateTime = 0
sparkleFrame.numSparkles = 0;
sparkleFrame.freeSparkles = {};
sparkleFrame.sparkles = {};
sparkleFrame:SetScript("OnUpdate", sparkleFrame.OnUpdate);
return sparkleFrame;
end
function SparkleFrame:SetFrameRate(framesPerSec)
self.updateTime = 1/(framesPerSec or 30);
end
function SparkleFrame:OnUpdate(elapsed)
local timeSinceLast = self.timeSinceLast + elapsed;
if ( timeSinceLast >= self.updateTime ) then
local sparkles = self.sparkles;
for i = #sparkles, 1, -1 do
if ( sparkles[i] and sparkles[i]:Animate(timeSinceLast) ) then
sparkles[i]:Free();
tremove(sparkles, i);
end
end
self.timeSinceLast = 0;
return;
end
self.timeSinceLast = timeSinceLast;
end
function SparkleFrame:StartAnimation (name, animationType, sparkleTemplate, loop, ...)
if ( not Sparkle[animationType] ) then
return;
end
local sparkle = Sparkle:New(self, sparkleTemplate);
sparkle.numArgs = select("#", ...);
for i = 1, sparkle.numArgs do
sparkle["param"..i] = select(i, ...);
end
sparkle.name = name;
sparkle.elapsed = 0;
sparkle.loop = loop;
sparkle.Animate = Sparkle[animationType];
return sparkle
end
function SparkleFrame:EndAnimation (name)
local sparkles, sparkle = self.sparkles;
for i = #sparkles, 1, -1 do
if ( sparkles[i].name == name ) then
sparkles[i]:Free();
tremove(sparkles, i);
end
end
end
function SparkleFrame:SetAnimationVertexColor (name, r, g, b, a)
for i, sparkle in next, self.sparkles do
if ( sparkle.name == name ) then
sparkle:SetVertexColor(r, g, b, a);
end
end
end