Project Icon Maker

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.

@FLCode, it might be handy if you include the shader as well ;p just saying

looking forward to test this :slight_smile:

EDIT: when commenting out the shader parts, it looks like it has some nice potential, nice job sir, and keep up the good work :slight_smile:

Thanks, I’ll fix that.
EDIT: Fixed. Thanks!

Not bad, not bad at all, looking really good :slight_smile:

Might use this in the future :slight_smile:

The user and all related content has been deleted.

Instant crash for me on iPad Mini iOS 8, until I deleted the Retina tab and changed all the rEllipse calls to ellipse calls

The user and all related content has been deleted.

For my icons, I added a clause to my scene manager class where I tell it which scene I want and it snaps a pic 5 seconds into that scene and saves it. Works out really well most of the time, other times I have to get a pic by hand.

The user and all related content has been deleted.

Yeah, if you have a non-Retina device, do what JakAttak said or it might not work.