Design an animation for aliens featuring a unique clock that
doesn't measure time based on Earth's rotation or celestial
movements. Instead, invent a new timekeeping system,
which could be continuous or discrete, cyclical or unidirectional.
P5.js
Blender
Figma
The project had a short timeline, with only 1.5 hours for the initial
idea and about a week to complete. I wanted to keep things simple
given the limited time, but I also saw it as a chance to push myself
by experimenting with coding and 3D concepts.
On an alien world with a sun, the inhabitants don’t have eyes
and can’t see light. Instead, they sense time by feeling the
energy from trees. The trees’ energy changes as the sun rises
and sets, helping the aliens know when it's day or night. My clock
shows this by using waves and colors to represent how the trees'
energy shifts, giving the aliens a way to understand time.
The project was inspired by nature, particularly the steady, slow rhythms of trees. I wondered how aliens, who can’t see light, might perceive time differently—perhaps through the energy frequencies emitted by living organisms like trees. This idea led me to explore how time could be measured in an alien world using something other than Earth’s rotation or the sun’s cycles. Such as colors, frequency.
The clock interface was inspired by vintage radio waves, with a design that appeals to humans while remaining simple for aliens.
The clock starts where the teal section of the wave begins, and the waves that follow represent signals captured from the tree.
I used p5.js to create a wave animation with moving vertical bars. The wave height changes over time, and noise functions generate random heights for the top and bottom of the bars. A gradient from dark blue to light teal adds visual depth, with the bars wrapping around the canvas for a continuous effect.
I struggled with getting the wave speed and height to flow smoothly. Starting from scratch was difficult, especially since I’m not very confident with coding, and balancing the visual design with functionality was tough.
let numRects = 50; // Number of vertical bars
let speed = 1.5; // Speed of horizontal movement
let offset = 4; // Horizontal offset for movement
let baseAmplitude = 30; // Base amplitude (minimum wave height)
let maxAmplitude = 780; // Maximum amplitude (when the wave is largest)
let noiseOffset = 0.1; // Offset for noise function
function setup() {
let canvas = createCanvas(windowWidth, windowHeight);
canvas.parent('p5-canvas');
noStroke();
}
function draw() {
background(0); // Black background
let rectWidth = width / numRects;
offset += speed;
noiseOffset += 0.01; // Increment noise over time for movement
// growing/shrinking effect
let waveAmplitude = baseAmplitude + (sin(frameCount * 0.01) + 1) / 2 * (maxAmplitude - baseAmplitude);
for (let i = 0; i < numRects; i++) {
let inter = map(i, 0, numRects, 0, 1);
// Define the gradient colors: #031056 -> #0959B0 -> #9AD4BB
let startColor = color('#031056'); // Dark blue
let middleColor = color('#0959B0'); // Medium blue
let endColor = color('#9AD4BB'); // Light teal
let c;
if (inter < 0.5) {
c = lerpColor(startColor, middleColor, inter * 2); //
} else {
c = lerpColor(middleColor, endColor, (inter - 0.5) * 2); //
}
fill(c);
// generate random heights for the wave
let waveHeightTop = noise(noiseOffset + i * 0.1) * waveAmplitude;
let waveHeightBottom = noise(noiseOffset + i * 0.1) * waveAmplitude;
let x = (i * rectWidth + offset) % width;
// Draw the top wave (starting from the top and descending)
rect(x, 0, rectWidth, waveHeightTop);
// Wrap around for top wave
rect(x - width, 0, rectWidth, waveHeightTop);
// Draw the bottom wave (starting from the bottom and ascending)
rect(x, height - waveHeightBottom, rectWidth, waveHeightBottom);
// Wrap around for bottom wave
rect(x - width, height - waveHeightBottom, rectWidth, waveHeightBottom);
}
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
}