You can use this code to generate nice-looking icons for your projects (with a simple description, too). I personally prefer this style of icon more than the default.
Syntax:
IconObject = icon(string ProgramName, string ProgramDescription, [color BackgroundColor, color TextColor, number GradientContrast (range 0-255)] )
The code:
--# Main
-- Icons_v2
-- Use this function to perform your initial setup
function setup()
ico = icon("IconMaker", "IconMaker v2", color(150, 100, 0), nil, nil)
local im = ico:render(123)
saveImage("Project:Icon", im)
end
-- This function gets called once every frame
function draw()
-- This sets a dark background color
background(255, 255, 255, 255)
-- This sets the line thickness
strokeWidth(5)
local im = ico:render()
sprite(im, WIDTH / 2, HEIGHT / 2)
-- Do your drawing here
end
--# icon
icon = class()
function icon:init(title, description, backing, tcolor, contrast)
local c = contrast or 30
-- you can accept and set parameters here
self.t = title
self.d = description
self.bg = backing or color(100)
self.bg2 = backing and color(backing.r + c, backing.g + c, backing.b + c) or color(100 + c)
self.tc = tcolor or color(235)
pixMode(2)
end
function icon:render(size)
size = size or 123
local hdr = 50
local hdrh = 30
local rd = 30 * renderMode
local im = image(size, size)
setContext(im)
noStroke()
fill(hdr)
ellipseMode(CENTER)
rectMode(CORNERS)
textMode(CENTER)
rEllipse(rd / 2, size * renderMode - rd / 2, rd, rd)
rEllipse(size * renderMode - rd / 2, size * renderMode - rd / 2, rd, rd)
rect(rd / 2 / renderMode, size, size - rd / 2 / renderMode, size - hdrh)
rect(0, size - rd / 2 / renderMode, size, size - hdrh)
fill(self.tc)
fontSize(18)
textWrapWidth(0)
font("HelveticaNeue-Bold")
local x, y = textSize(self.t)
if 18 * 103 / x <= hdrh - 10 then
fontSize(18 * 103 / x)
else
fontSize(hdrh - 10)
end
textWrapWidth(103)
text(self.t, size / 2, size - hdrh / 2)
fontSize(18)
fill(self.bg2)
rEllipse(rd / 2, rd / 2, rd, rd)
rEllipse(size * renderMode - rd / 2, rd / 2, rd, rd)
rect(rd / 2 / renderMode, rd / 2 / renderMode, size - rd / 2 / renderMode, 0)
gradient(0, size - hdrh, size, rd / 2 / renderMode, self.bg2, self.bg)
textMode(CORNER)
--textAlign(CENTER)
fill(self.tc)
local x, y = textSize(self.d)
if y >= size - hdrh - 15 then
fontSize(18 * y / (size - hdrh + 5))
end
local x, y = textSize(self.d)
text(self.d, 10, size - hdrh - y - 5)
setContext()
return im
end
function icon:save()
saveImage("Project:Icon", self:render())
end
function icon:draw()
-- Codea does not automatically call this method
end
function icon:touched(touch)
-- Codea does not automatically call this method
end
--# Gradient
function gradient(x1, y1, x2, y2, c1, c2)
local m1 = mesh()
m1.vertices = {vec2 (x1,y2), vec2(x2,y1),vec2(x2,y2)}
local m2 = mesh()
m2.vertices = {vec2(x1,y1),vec2(x2,y1),vec2(x1,y2)}
m1.colors = {c1,c2,c1}
m2.colors = {c2,c2,c1}
m1:draw()
m2:draw()
end
--# Retina
vertex = [[
uniform mat4 modelViewProjection;
attribute vec4 position;
attribute vec2 texCoord;
varying highp vec2 vTexCoord;
void main()
{
//Tex coords are from -1, 1
vTexCoord = vec2(texCoord.x * 2.0 - 1.0, texCoord.y * 2.0 - 1.0);
//Multiply the vertex position by our combined transform
gl_Position = modelViewProjection * position;
}
]]
fragment = [[
precision highp float;
uniform lowp sampler2D texture;
varying highp vec2 vTexCoord;
uniform lowp vec4 fillColor;
uniform lowp vec4 strokeColor;
uniform highp vec2 radius;
uniform highp float strokeWidth;
void main()
{
highp vec2 RadiusAA = vec2(radius.x - 2.0, radius.y - 2.0);
highp vec2 scaledPointSq = vec2( (vTexCoord.x * radius.x) *
(vTexCoord.x * radius.x),
(vTexCoord.y * radius.y) *
(vTexCoord.y * radius.y) );
highp float c = (scaledPointSq.x / (radius.x*radius.x)) +
(scaledPointSq.y / (radius.y*radius.y));
highp float cAA = (scaledPointSq.x / (RadiusAA.x*RadiusAA.x)) +
(scaledPointSq.y / (RadiusAA.y*RadiusAA.y));
highp vec2 innerRadius = vec2( radius.x - strokeWidth * 2.0,
radius.y - strokeWidth * 2.0 );
highp vec2 innerRadiusAA = vec2( radius.x - strokeWidth * 2.0 - 2.0,
radius.y - strokeWidth * 2.0 - 2.0 );
highp float cInner = (scaledPointSq.x / (innerRadius.x*innerRadius.x)) +
(scaledPointSq.y / (innerRadius.y*innerRadius.y));
highp float cInnerAA = (scaledPointSq.x /
(innerRadiusAA.x*innerRadiusAA.x)) +
(scaledPointSq.y /
(innerRadiusAA.y*innerRadiusAA.y));
//Premult
lowp vec4 fragCol = mix( fillColor, strokeColor,
smoothstep( cInner / cInnerAA, 1.0, cInner ) );
gl_FragColor = mix( fragCol, vec4(0,0,0,0),
smoothstep( c / cAA, 1.0, c ) );
}
]]
retinaShader = shader(vertex, fragment)
noSmooth()
local mode = 2
if ContentScaleFactor == 2 then
shader_src = retinaShader
else
shader_src = shader("Patterns:Ellipse")
end
function pixMode(str)
if str == "RETINA" then
mode = 2
elseif type(str) == "number" then
mode = str
else
mode = 1
end
renderMode = mode
end
local ellipseMesh = mesh()
rEllipse = function(x, y, w, h)
--noSmooth()
m = mesh()
--m.texture = CAMERA
m.shader = shader_src
local r, g, b, a = fill()
m.shader.fillColor = vec4(r / 255, g / 255, b / 255, 1)
local r, g, b, a = stroke()
m.shader.strokeColor = vec4(r / 255, g / 255, b / 255, 1)
m.shader.radius = vec2(w, h)
m.shader.strokeWidth = strokeWidth()
rIdx = m:addRect(0, 0, 1, 1)
m:setRect(rIdx, x / mode, y / mode, w / mode, h / mode)
m:draw()
end
I’ll be updating it soon, to add more options (and code comments).
Feel free to use this and edit it as you wish.