Gradients
gradient (Mesh variant)
Synopsis
mesh = gradientMesh( direction, color1, color2, ... )
Creates a gradient object (actually Mesh) from a table of colors to be evenly spaced throughout the gradient. This is better version of gradient function below.
Arguments
string direction
- Gradient direction (horizontal or vertical).
table color1
- First color table.
table color2
- Second color table.
table ...
- Additional color table.
Returns
Mesh mesh
- The gradient object.
Source
-- Color multipler local COLOR_MUL = love._version >= "11.0" and 1 or 255 function gradientMesh(dir, ...) -- Check for direction local isHorizontal = true if dir == "vertical" then isHorizontal = false elseif dir ~= "horizontal" then error("bad argument #1 to 'gradient' (invalid value)", 2) end -- Check for colors local colorLen = select("#", ...) if colorLen < 2 then error("color list is less than two", 2) end -- Generate mesh local meshData = {} if isHorizontal then for i = 1, colorLen do local color = select(i, ...) local x = (i - 1) / (colorLen - 1) meshData[#meshData + 1] = {x, 1, x, 1, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)} meshData[#meshData + 1] = {x, 0, x, 0, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)} end else for i = 1, colorLen do local color = select(i, ...) local y = (i - 1) / (colorLen - 1) meshData[#meshData + 1] = {1, y, 1, y, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)} meshData[#meshData + 1] = {0, y, 0, y, color[1], color[2], color[3], color[4] or (1 * COLOR_MUL)} end end -- Resulting Mesh has 1x1 image size return love.graphics.newMesh(meshData, "strip", "static") end
Notes
The resulting Mesh has dimensions of 1x1. Scaling factor in love.graphics.draw determines the size of the gradient. drawinrect function below is not needed (can't be used really) when using this variant.
gradient (Image variant)
Synopsis
gradient {color1, color2, color3, ..., direction = 'horizontal' or 'vertical'}
Creates a gradient object (really just an Image) from a table of colors to be evenly spaced throughout the gradient, in the direction specified by the "direction" key of the parameter table.
Source
function gradient(colors) local direction = colors.direction or "horizontal" if direction == "horizontal" then direction = true elseif direction == "vertical" then direction = false else error("Invalid direction '" .. tostring(direction) .. "' for gradient. Horizontal or vertical expected.") end local result = love.image.newImageData(direction and 1 or #colors, direction and #colors or 1) for i, color in ipairs(colors) do local x, y if direction then x, y = 0, i - 1 else x, y = i - 1, 0 end result:setPixel(x, y, color[1], color[2], color[3], color[4] or 255) end result = love.graphics.newImage(result) result:setFilter('linear', 'linear') return result end
drawinrect
Synopsis
drawinrect(img, x, y, w, h, r, ox, oy, kx, ky)
A convenience function to draw scaled images in a rectangle of absolute size (rather than with a size relative to the size of the image, which is what love.graphics.draw() does). Useful for gradients, because you will almost always want to draw them scaled, and you don't want their bounds to change if the number of colors does.
Source
function drawinrect(img, x, y, w, h, r, ox, oy, kx, ky) return -- tail call for a little extra bit of efficiency love.graphics.draw(img, x, y, r, w / img:getWidth(), h / img:getHeight(), ox, oy, kx, ky) end
Examples
drawing horizontal rainbow that fills the entire screen using Mesh variant
-- assume you already have gradientMesh function local rainbow function love.load() rainbow = gradientMesh("horizontal", {255, 0, 0}; {255, 255, 0}; {0, 255, 0}; {0, 255, 255}; {0, 0, 255}; {255, 0, 0}; ) end function love.draw() love.graphics.draw(rainbow, 0, 0, 0, love.graphics.getDimensions()) end
draw a 100x100 horizontal rainbow (that is, red on top, purple on bottom) in the center of the screen
require "gradient" local rainbow = gradient { direction = 'horizontal'; {255, 0, 0}; {255, 255, 0}; {0, 255, 0}; {0, 255, 255}; {0, 0, 255}; {255, 0, 0}; } function love.draw() drawinrect(rainbow, love.graphics.getWidth() / 2 - 50, love.graphics.getHeight() / 2 - 50, 100) end
draw a vertical greyscale spectrum (that is, black on left, white on right) filling the whole screen
require "gradient" local greyscale = gradient { direction = 'vertical'; {0, 0, 0}; {255, 255, 255}; } function love.draw() drawinrect(greyscale, 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) end