Making Rainbow Text - jorjic/fivem-docs GitHub Wiki
Please stop abusing math.random to create "rainbow" text. Today, I'll be outlining using math.sin to create visually appealing rainbows. For the lazy, I'll post the full example code.
local function RGBRainbow( frequency )
local result = {}
local curtime = GetGameTimer() / 1000
result.r = math.floor( math.sin( curtime * frequency + 0 ) * 127 + 128 )
result.g = math.floor( math.sin( curtime * frequency + 2 ) * 127 + 128 )
result.b = math.floor( math.sin( curtime * frequency + 4 ) * 127 + 128 )
return result
end
Citizen.CreateThread( function()
while true do
Wait( 0 )
SetTextFont( 4 )
SetTextScale( 1.0, 1.0 )
local rainbow = RGBRainbow( 1 )
SetTextColour( rainbow.r, rainbow.g, rainbow.b, 255 )
SetTextOutline()
SetTextEntry( "STRING" )
AddTextComponentString( "Rainbow Text" )
DrawText( 0.029, 0.75 )
end
end )
Explanation
Time to break this down. Let's build a function to create a rainbow sine wave. For those of you that skipped trigonometry, sine waves look like this:
We can create a basic sine wave by using the math.sin function and passing the current up time in milliseconds as the first argument.
math.sin( GetGameTimer() )
This gives us a range of values, depending on when we run it, ranging between -1 and 1. By applying a little bit of math, we can get it to return between 0 and 255.
math.sin( GetGameTimer() ) * 127 + 128
Now we can directly apply this value to create an RGB value, without violating the numerical boundaries of 0 and 255. However, using this value for red, blue, and green at the same time will cause our text to change between black and white. We can tweak our code above to produce an out-of-phase sine wave, which will get us the results we want.
math.sin( GetGameTimer() + 0 ) * 127 + 128
math.sin( GetGameTimer() + 2 ) * 127 + 128
math.sin( GetGameTimer() + 4 ) * 127 + 128
By combining these out-of-phase waves into an RGB value, we end up following this path on the hue-saturation wheel:
With the above information in our knowledge, we can finally build a function to handle the work for us. In the below example, I'll be doing things a little differently than I did above. I've added comments in the code to explain my reasoning.
local function RGBRainbow( frequency )
--Create a table to store our values, so that we can give them as a result.
local result = {}
--Convert the millisecond result of GetGameTimer() into seconds, purely to make frequencies nicer
local curtime = GetGameTimer() / 1000
--Create new entries in the results table, and assign values to them.
--I've added math.floor() to each equation, which will chop off the remaining decimal and leave us with a nice integer.
--( GTA will otherwise treat the value as a float and produce yucky colors )
result.r = math.floor( math.sin( curtime * frequency + 0 ) * 127 + 128 )
result.g = math.floor( math.sin( curtime * frequency + 2 ) * 127 + 128 )
result.b = math.floor( math.sin( curtime * frequency + 4 ) * 127 + 128 )
return result
end
Result
Now, we can simply call our new function and use the values to make aesthetically-appealing rainbow text. Below is an example usage of the function:
Citizen.CreateThread( function()
while true do
Wait( 0 )
SetTextFont( 4 )
SetTextScale( 1.0, 1.0 )
local rainbow = RGBRainbow( 1 )
SetTextColour( rainbow.r, rainbow.g, rainbow.b, 255 )
SetTextOutline()
SetTextEntry( "STRING" )
AddTextComponentString( "Rainbow Text" )
DrawText( 0.029, 0.75 )
end
end )
Here's how it looks:
Source and Thanks
Huge thanks to krazydad! http://krazydad.com/tutorials/makecolors.php