Tween Explorer: an experiment with tween and custom easing functions (Codea 1.5)

tween() is a new feature in Codea version 1.5 that facilitates animation. The code below allows the form of the built-in easing functions to be explored, and illustrates the use of a custom easing function (myEasing(t, b, c, d)).

The code also uses the callback argument of the parameter.boolean() and parameter.integer() functions.


--
-- Tween Explorer
--

-- A custom easing function
-- t is the current time
-- d is the duration of the animation
-- b is the initial animated value
-- c is the change in the animated value by the end of the animation
function myEasing(t, b, c, d)
    t = t / d
    return b + c * math.pow(math.sin(t * math.pi * 2.5), 2)
end

supportedOrientations(LANDSCAPE_ANY)
function setup()
    easingType = {
        "quad", "cubic", "quart", "quint",
        "expo", "sine",
        "circ", -- Undocumented in Codea 1.5(16)
        "back", "bounce", "elastic"}
    inOutType = {"In", "Out", "InOut", "OutIn"}
    duration = 3
    dim = math.min(WIDTH, HEIGHT)
    offset = dim / 4
    margin = dim / 20
    width = margin / 10
    dim = dim - offset * 2 - margin - width
    easingFunction = 1
    inOutFunction = 1
    parameter.boolean("isCustomEasingFunction", true, reset)
    parameter.integer("easingFunction", 1, #easingType, 1,
        resetEF)
    parameter.watch("easingType[easingFunction]")
    parameter.integer("inOutFunction", 1, #inOutType, 1, resetEF)
    parameter.watch("inOutType[inOutFunction]")
    local col = color(255, 255, 0)
    fill(col)
    stroke(col.r * 0.5, col.g * 0.5, col.b * 0.5)
    rectMode(CORNER)
    spriteMode(CORNER)
    ellipseMode(CORNER)
    fontSize(32)
end

function draw()
    background(64)
    text(easingString..": touch Viewer to rerun.",
        WIDTH / 2, HEIGHT - 50)
    strokeWidth(5)
    line(offset, offset + margin,
        offset + margin + dim + width, offset + margin)
    line(offset + margin, offset,
        offset + margin, offset + margin + dim + width)
    noStroke()
    rect(offset, subjectY.y + offset + margin, margin, width)
    rect(subjectX.x + offset + margin, offset, width, margin)
    setContext(img)
    ellipse(subjectX.x, subjectY.y + offset + margin, width)
    setContext()
    sprite(img, offset + margin, 1)
end

function touched(touch)
    if touch.state == BEGAN then reset() end
end

function resetEF()
    if isCustomEasingFunction then return end
    reset()
end

function reset()
    img = image(dim + width, dim + width + offset * 2)
    subjectX = {x = 1}
    local targetX = {x = dim}
    tween(duration, subjectX, targetX)
    subjectY = {y = 1}
    local targetY = {y = dim}
    if isCustomEasingFunction then
        easingString = "myEasing"
        tweenId = tween(duration, subjectY, targetY, myEasing)
    else
        easingString = easingType[easingFunction]..
            inOutType[inOutFunction]
        tweenId = tween(duration, subjectY, targetY, easingString)
    end
end

Thanks @mpilgrem. @Simeon: this project freezes randomly on my ipad1. When i touch panel button (top left) then the project un-freezes. Seems to be the same kind of pb as the ‘black screen’ i’ve reported, although here there is no black screen, just a freeze.

same problem here an im on the 3`Gen ipad

.@Jmv38 @warox I can reproduce this here, thanks for the report. We’ll be seeing a quick 1.5.1 bug fix patch for this issue.

np @simeon ;3

.@warox I have fixed this issue in 1.5.1.

Will tween become available in the Xcode runtime?