Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

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

Asked by 8 years ago

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

Log in to vote
6
Answered by
BlackJPI 2658 Snack Break Moderation Voter Community Moderator
8 years ago

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.

0
A+ ScriptGuider 5640 — 8y
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. BlackJPI 2658 — 8y
0
OMG THAT"S AWESOME AMOUNT OF INFO !! More than I expected.. Thanks! buoyantair 123 — 8y
0
Hahah no problem :) I even learned a thing or two writting this one BlackJPI 2658 — 8y
Ad
Log in to vote
0
Answered by 8 years ago

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

Answer this question