Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Using Color3() to change the color of a GUI?

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.

2 answers

✓ Accepted answer

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.

4 comments

0

A+

0

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.

0

OMG THAT"S AWESOME AMOUNT OF INFO !! More than I expected.. Thanks!

0

Hahah no problem :) I even learned a thing or two writting this one

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.