Hi, I just wanted to ask how I can change the color of a GUI witha fade effect. Like A blue turns into semi-blue-green and then ultimately green. I have no idea how.
Using Color3() to change the color of a GUI?
2 answers
To do this you will have to do some sort of interpolation between each of the values.
Linear Interpolation of RGB
The simplest way would be a straight linear interpolation for the r, b, and g color components. The formula for this as follows:
value0*(1 - alpha) + value1*alpha
Where value0 is the initial value, value1 is the end value, and alpha is the "percentage" of the way between the two.
local function linearInterpolation(v0, v1, alpha)
return v0*(1-alpha) + v1*alpha
end
Now to use this function we will have to use a loop to update the value of the color over time:
-- Assuming function linearInterpolation is defined above
local gui = ScreenGui.Frame -- Placeholder
local color0 = Color3.new(1, 1, 1)
local color1 = Color3.new(0, 0, 0)
local duration = 1
local elapsed = 0
local alpha = 0
while (alpha < 1) do
elapsed = elapsed + wait()
alpha = math.min(elapsed/duration, 1)
local newColor = Color3.new(
linearInterpolation(color0.r, color1.r, alpha),
linearInterpolation(color0.g, color1.g, alpha),
linearInterpolation(color0.b, color1.b, alpha)
)
gui.BackgroundColor3 = newColor
end
This will successfully interpolate between colors. However you might notice that the intermediate is a little 'dull'. To fix this we can convert the colors to another color space. In this case I think that the HSV color space looks very good.
###RBG to HSV This can look quite daunting, but it is simple to use once it is implemented. This is a generic algorithm that is most widely used:
local function RGBtoHSV(r, g, b)
local min, max, delta
local h, s, v
min = math.min(r, g, b)
max = math.max(r, g, b)
v = max
delta = max - min
if max ~= 0 then
s = delta/max
else
s = 0
h = -1
return h, s, v
end
if r == max then
h = ( g - b ) / delta
elseif g == max then
h = 2 + ( b - r ) / delta
else
h = 4 + ( r - g ) / delta
end
h = h*60
if h < 0 then
h = h + 360
end
return h, s, v
end
local function HSVtoRGB(h, s, v)
local r, g, b
local i, f, q, p, t
if s == 0 then
return v, v, v
end
h = h/60
i = math.floor(h)
f = h - i
p = v*(1 - s)
q = v*(1 - s*f)
t = v*(1 - s*(1 - f))
if i == 0 then
r, g, b = v, t, p
elseif i == 1 then
r, g, b = q, v, p
elseif i == 2 then
r, g, b = p, v, t
elseif i == 3 then
r, g, b = p, q, v
elseif i == 4 then
r, g, b = t, p, v
else
r, g, b = v, p, q
end
return r, g, b
end
Now that we have those functions defined we don't have to worry about the definition. All we need to know is that we can successfully covert to and from HSV and RGB.
###Linear Interpolation of HSV
This is going to be very similar to the one we made before, except we have to decide which way we want to interpolate. HSV is like a cylinder, with the hue being determined by the degree around the cylinder (see this diagram).
So we will need to decide if you should travel clockwise or counter-clockwise. I did this by comparing the distance from the start to end, and then the difference of the start + 360 degrees (1 trip around the circle) and the end:
local differenceCW = color0.X - color1.X;
local differenceCCW = (color0.X + 360) - color1.X;
local CW = differenceCW > differenceCCW
Now that we know what direction to travel we figure out how to interpolate the Hue. If it is clockwise then you can just linearly interpolate from start to end. If it is counter-clockwise then you interpolate from start + 360 to end:
local hue
if CW then
hue = linearInterpolation(color0.X, color1.X, alpha),
else
hue = linearInterpolation(color0.X + 360, color1.X, alpha),
end
How putting it all together:
-- Assuming functions RGBtoHSV, HSVtoRGB, and linear interpolation are defined above
local gui = ScreenGui.Frame -- Placeholder
local color0 = Vector3.new(RGBtoHSV(255, 0, 0))
local color1 = Vector3.new(RGBtoHSV(0, 0, 255))
local differenceCW = color0.X - color1.X;
local differenceCCW = (color0.X + 360) - color1.X;
local CW = differenceCW > differenceCCW
local duration = 5
local elapsed = 0
local alpha = 0
while (alpha < 1) do
elapsed = elapsed + wait()
alpha = math.min(elapsed/duration, 1)
local hue
if CW then
hue = linearInterpolation(color0.X, color1.X, alpha)
else
hue = linearInterpolation(color0.X + 360, color1.X, alpha)
end
local newColor = Vector3.new(HSVtoRGB(
hue,
linearInterpolation(color0.Y, color1.Y, alpha),
linearInterpolation(color0.Z, color1.Z, alpha)
))
gui.BackgroundColor3 = Color3.new(newColor.X/255, newColor.Y/255, newColor.Z/255)
end
Note the you need to input values between 0 and 255 into the RBGtoHSV function and thus have to divide the values returned from HSVtoRGB by 255 to store them correctly in a Color3 datatype.
Interpolations in Action
For a comparison of the two color space interpolations I covered, check out this gif.
You could make a loop for example
for i=1,255 do
gui.BackgroundColor3 = Color3.new(0/255,0/255,i/255)
wait(0.1)
end
This discussion is preserved as it was. New answers, comments, and votes are closed.

4 comments
A+
After about two and a half hours of tinkering, I fixed all the little bugs and even included a little gif at the bottom so you can see the difference.
OMG THAT"S AWESOME AMOUNT OF INFO !! More than I expected.. Thanks!
Hahah no problem :) I even learned a thing or two writting this one