I already know how to do this on a non rotated texture. By setting texture width/height and texcoords. But when rotation is used you use 8 values instead of 4. And I just don't know how to work that into clipping part of the texture to fill it when rotating.
Nah not cosmetic. But being able to rotate a texture like a statusbar can and applying a fill to it. So its not animation. The filling would be animation though.
I might be able to use that if I can minipulate the values somehow.
Problem is rotation uses SetTexCoord and filling uses the same function.
So I'm not sure how to do it.
-------------------------------------------------------------------------------
-- SetFill
--
-- Subfunction of SetFillTexture, SetFillTimeTexture
--
-- Texture Texture to setfill to.
-- Value Between 0 and 1
-- Spark Internal use only. If not nil then a spark is shown on the
-- texture edge.
--
-- NOTE: SetFillDirectionTexture() will control the fill that this function will use.
-- Cant set texture width to 0 so use 0.001 this will make the texture not be
-- visible. Setting texture size to 0 doesn't hide the texture.
-------------------------------------------------------------------------------
local function SetFill(Texture, Value, Spark)
local ReverseFill = Texture.ReverseFill
local FillDirection = Texture.FillDirection
local Width, Height = Texture.Width, Texture.Height
-- Flag setfill for onsizechanged.
Texture.SetFill = 1
if Texture.Type == 'texture' then
local SubTexture = Texture.SubTexture
local TexLeft, TexRight, TexTop, TexBottom = SubTexture.TexLeft, SubTexture.TexRight, SubTexture.TexTop, SubTexture.TexBottom
local TextureWidth = Width
local TextureHeight = Height
-- Clip the amount if out of range.
Value = Value > 1 and 1 or Value < 0 and 0 or Value
-- Calculate the texture width
if FillDirection == 'HORIZONTAL' then
TextureWidth = Width * Value
-- Check for reverse fill.
if ReverseFill then
TexLeft = TexRight - (TexRight - TexLeft) * Value
SubTexture:SetPoint('TOPLEFT', Width - TextureWidth, 0)
else
TexRight = TexLeft + (TexRight - TexLeft) * Value
SubTexture:SetPoint('TOPLEFT')
end
else
-- Calculate the texture height.
TextureHeight = Height * Value
-- Check for reverse fill
if ReverseFill then
TexBottom = TexTop + (TexBottom - TexTop) * Value
SubTexture:SetPoint('TOPLEFT')
else
TexTop = TexBottom - (TexBottom - TexTop) * Value
SubTexture:SetPoint('TOPLEFT', 0, (Height - TextureHeight) * -1)
end
end
SubTexture:SetSize(TextureWidth > 0 and TextureWidth or 0.001, TextureHeight > 0 and TextureHeight or 0.001)
SubTexture:SetTexCoord(TexLeft, TexRight, TexTop, TexBottom)
else
-- Set statusbar value.
Texture.SubFrame:SetValue(Value)
end
Texture.Value = Value
-- Display spark if not nil
if Spark then
local x = nil
local y = nil
if FillDirection == 'HORIZONTAL' then
y = Height * 0.5 * -1
if ReverseFill then
x = Width - Width * Value + 1 -- Offset spark by 1
else
x = Width * Value
end
-- Set spark size.
Spark:SetSize(TextureSparkSize, Height * 2.3)
else
x = Width * 0.5
if ReverseFill then
y = Height * Value * -1 + 1 -- Offset spark by 1
else
y = (Height - Height * Value) * -1
end
-- Set spark size.
Spark:SetSize(Width * 2.3, TextureSparkSize)
end
Spark:Show()
Spark:SetPoint('CENTER', Spark.ParentFrame, 'TOPLEFT', x, y)
end
end
I am a bit lost. What do you mean by fill? I assumed you mean stretches from border to border. That makes not much sense with rotation.
Can you post a picture of what you want vs. what you got?
Also your code is a bit without context. Textures normaly have no field Type or Subtexture.
Fill means you fill it like a status bar. It grows, like a healthbar.
Yeah its a function out of a 3400 line code. But it can fill a texture just like a statusbar can. Taken from blizzards own code on the demonic fury bar.
To grow a texture you need to set its width and height. Also set its TexCoords so it don't stretch. Problem is to rotate a texture you need to use settexcoords. Blizzards own rotate texture uses the same function. But in order to grow a texture you need to settexcoords it which will undo the rotation.
No picture needed its the same thing as a statusbar, statusbar can rotate 90degrees and fill.
I'd use a statusbar to do it, but statusbars are weird when it comes to reverse fill. Plus if I do it this way I could have more than just 0 and 90 degrees.
Edit: I should point out, that I don't think what you want is possible this way. But unless you give an example picture of what you want I can't be sure.
The right image is not a 180° degree, it is either 90° or 270°, proably a typo.
These four (0, 90, 180, 270) are all easy. You don't need much code for that.
The non-rectangular angles are a bit more involved. Can you follow the math I posted? If not someone might be willing to do so for you.
Here is an example code for rotation with the current texcoord settings for any angle, I also use it for my range indicator on raid panel.
__OriginTexCoord is used to keep the texcoord settings, so if change the texture or SetTexCoord, just clear it from the texture object.
I hope it can help you.
--[======[
@name RotateRaid
@type method
@desc Rotate texture for radian with current texcoord settings
@param radian number, the rotation raidian
@return nil
]======]
function RotateRadian(self, radian)
if type(radian) ~= "number" then
error("Usage: Texture:RotateRadian(radian) - 'radian' must be number.", 2)
end
if not self.__OriginTexCoord then
self.__OriginTexCoord = {self:GetTexCoord()}
self.__OriginWidth = self:GetWidth()
self.__OriginHeight = self:GetHeight()
end
while radian < 0 do
radian = radian + 2 * math.pi
end
radian = radian % (2 * math.pi)
local angle = radian % (math.pi /2)
local left = self.__OriginTexCoord[1]
local top = self.__OriginTexCoord[2]
local right = self.__OriginTexCoord[7]
local bottom = self.__OriginTexCoord[8]
local dy = self.__OriginWidth * math.cos(angle) * math.sin(angle) * (bottom-top) / self.__OriginHeight
local dx = self.__OriginHeight * math.cos(angle) * math.sin(angle) * (right - left) / self.__OriginWidth
local ox = math.cos(angle) * math.cos(angle) * (right-left)
local oy = math.cos(angle) * math.cos(angle) * (bottom-top)
local newWidth = self.__OriginWidth*math.cos(angle) + self.__OriginHeight*math.sin(angle)
local newHeight = self.__OriginWidth*math.sin(angle) + self.__OriginHeight*math.cos(angle)
local ULx -- Upper left corner X position, as a fraction of the image's width from the left (number)
local ULy -- Upper left corner Y position, as a fraction of the image's height from the top (number)
local LLx -- Lower left corner X position, as a fraction of the image's width from the left (number)
local LLy -- Lower left corner Y position, as a fraction of the image's height from the top (number)
local URx -- Upper right corner X position, as a fraction of the image's width from the left (number)
local URy -- Upper right corner Y position, as a fraction of the image's height from the top (number)
local LRx -- Lower right corner X position, as a fraction of the image's width from the left (number)
local LRy -- Lower right corner Y position, as a fraction of the image's height from the top (number)
if radian < math.pi / 2 then
-- 0 ~ 90
ULx = left - dx
ULy = bottom - oy
LLx = right - ox
LLy = bottom + dy
URx = left + ox
URy = top - dy
LRx = right + dx
LRy = top + oy
elseif radian < math.pi then
-- 90 ~ 180
URx = left - dx
URy = bottom - oy
ULx = right - ox
ULy = bottom + dy
LRx = left + ox
LRy = top - dy
LLx = right + dx
LLy = top + oy
newHeight, newWidth = newWidth, newHeight
elseif radian < 3 * math.pi / 2 then
-- 180 ~ 270
LRx = left - dx
LRy = bottom - oy
URx = right - ox
URy = bottom + dy
LLx = left + ox
LLy = top - dy
ULx = right + dx
ULy = top + oy
else
-- 270 ~ 360
LLx = left - dx
LLy = bottom - oy
LRx = right - ox
LRy = bottom + dy
ULx = left + ox
ULy = top - dy
URx = right + dx
URy = top + oy
newHeight, newWidth = newWidth, newHeight
end
self:SetTexCoord(ULx, ULy, LLx, LLy, URx, URy, LRx, LRy)
self:SetWidth(newWidth)
self:SetHeight(newHeight)
end
The right image is not a 180° degree, it is either 90° or 270°, proably a typo.
These four (0, 90, 180, 270) are all easy. You don't need much code for that.
The non-rectangular angles are a bit more involved. Can you follow the math I posted? If not someone might be willing to do so for you.
Thought 90 degree was horizontal? Which would make 180 another 90 degrees to vertical. And 360 would be direct opposite of 180?
Maybe thats what you need?
Problem is rotation uses SetTexCoord and filling uses the same function.
So I'm not sure how to do it.
Can you post a picture of what you want vs. what you got?
Also your code is a bit without context. Textures normaly have no field Type or Subtexture.
Yeah its a function out of a 3400 line code. But it can fill a texture just like a statusbar can. Taken from blizzards own code on the demonic fury bar.
To grow a texture you need to set its width and height. Also set its TexCoords so it don't stretch. Problem is to rotate a texture you need to use settexcoords. Blizzards own rotate texture uses the same function. But in order to grow a texture you need to settexcoords it which will undo the rotation.
No picture needed its the same thing as a statusbar, statusbar can rotate 90degrees and fill.
I'd use a statusbar to do it, but statusbars are weird when it comes to reverse fill. Plus if I do it this way I could have more than just 0 and 90 degrees.
Do you know how to use the 8-arg SetTexCoord at all? Won't it just be a matter of moving the relevant points as the bar fills up?
This is done with:
this is equivalent to
Unfortunately :SetRotation will probably overwrite this. But please try it.
If you need to do a manual rotation you should first attempt to manually calculate the texture coords for a rotation.
I don't want to do the math right now, please read
http://wowpedia.org/SetTexCoord_Transformations
and
http://wowpedia.org/API_Texture_SetRotation
Edit: I should point out, that I don't think what you want is possible this way. But unless you give an example picture of what you want I can't be sure.
If this could be done at any angle, even better. Cant try this out right now.
These four (0, 90, 180, 270) are all easy. You don't need much code for that.
The non-rectangular angles are a bit more involved. Can you follow the math I posted? If not someone might be willing to do so for you.
__OriginTexCoord is used to keep the texcoord settings, so if change the texture or SetTexCoord, just clear it from the texture object.
I hope it can help you.
Thought 90 degree was horizontal? Which would make 180 another 90 degrees to vertical. And 360 would be direct opposite of 180?
Thanks Kurapica