gabagoo-LineWalk

 

 

APPROACH: I really wanted to create a line that alternates between lines and curves. I got stuck with applying and reapplying matrix transformation with push() and pop(). I ended up using a stack of matrix transformations. I also wanted the animation of watching the line 'walk' be really satisfying so I used p5.func to use several different easing functions. I found that tuning various parameters in the way I transform the matrix between strokes was incredible sensitive and produced several interesting results.

LIVE EXAMPLE + CODE
let FUNCS = ['quadraticIn', 'quadraticOut', 'quadraticInOut', 'doubleQuadraticBezier', 'doubleQuadraticSigmoid', 'quadraticBezier', 'quadraticBezierStaircase', 'cubicIn', 'cubicOut', 'cubicInOut', 'brycesCubic', 'cubicBezier', 'cubicBezierThrough2Points', 'doubleCubicOgee', 'doubleCubicOgeeSimplified', 'quarticIn', 'quarticOut', 'quarticInOut', 'generalizedQuartic', 'quinticIn', 'quinticOut', 'quinticInOut']
let MIN_SPEED = 5, MAX_SPEED = 15, UPDATE = 0.1
let context = {}
let transforms = []
let e = new p5.Ease()

function setup() {
    createCanvas(windowWidth, windowHeight, SVG)
    angleMode(DEGREES)
    stroke(0)
    strokeWeight(5)
    updateContext(width/2, height/2)
    
}

function draw() {

    // apply transformations
    push()
    for (const [type, vec] of transforms) {
        switch (type) {
            case 'translate': translate(vec.x, vec.y); break;
            case 'rotate': rotate(atan2(vec.y, vec.x)); break;
        }
    }

    // draw line
    line(...lineargs())

    // exit condition
    if (context.prog >= 1) updateContext(context.width, 0)
    context.prog = min(1, context.prog + UPDATE * context.speed)
    pop()
}

function lineargs() {
    var val = e[context.easing](context.prog) * context.width
    return [0, 0, val, 0]
}

function updateContext(x, y) {
    context.start = createVector(x, y)

    if (context.dir == undefined) context.dir = p5.Vector.random2D()
    else context.dir = createVector(random(-.1, .1), random(1, 4))
    // else context.dir = createVector(1, random(-1, 1))

    context.speed = random(MIN_SPEED, MAX_SPEED)
    context.easing = random(FUNCS)
    context.width = random(random(0,10), random(10, 100))
    // context.width = 5
    context.prog = 0.

    transforms.push(['translate', context.start])
    transforms.push(['rotate', context.dir])
}

function keyPressed() {
    if (key == 'd') {
        noLoop()
        save('plot.svg')
        loop()
    }
}