Rippling rows
inspired by Bridget Riley, Fall1
Level lines fill the lower screen, rippling faster towards the right edge, their crests leaning. One line is picked out.
Made with Claude Opus 5.5
Colours
- #1C1B1Abackground
- #DAD8CEforeground
- #CF6A4Caccent
Export
FormatThis browser can’t make WebP files.
Shapecropped from 16:9
Crop
SizeThis browser can’t draw a file that large.
Notes
Takes from Bridget Riley’s Fall (1963) the idea of one wavy line repeated until its tightening waves start to move.
Here the lines lie flat and quicken towards the right, and each one lags a little behind the one below it, so the crests lean instead of stacking.
Sources
Source code
wallpapers/riley-fall/design.py, 39 lines
"""Level lines ripple faster towards the right, each a little behind the one below, so the crests lean; one line is picked out."""
import numpy as np
import shapely
from numpy.typing import NDArray
from walldye import ACCENT, ACCENT_3, BG_ALT, UI, Canvas, P, design, ramp
Y0, GAP = 24, 11 # first line below the bottom edge, line pitch
TOL = 0.1 # simplification tolerance: the flat left part collapses to a few points
AMP0, AMP1 = 16, 12 # amplitude eases off at the right so steep neighbours don't close up
F1, POW = 1 / 60, 3 # frequency at the right edge; f(x) ~ x**POW keeps the left flat
DRIFT = 0.3 # phase lag per line, in radians: the crests lean instead of stacking
TAIL = 19 / 60 # lines above the picked-out one, as a share of the lines below it
TONES = ramp(BG_ALT, UI, 7)
@design(aspects="any")
def draw(s: Canvas) -> None:
xs = np.arange(-4, s.w + 5, dtype=float)
t = np.clip(xs / s.w, 0, 1)
phase = 2 * np.pi * F1 * s.w / (POW + 1) * t ** (POW + 1)
amp = AMP0 + (AMP1 - AMP0) * t**2
vein = round((s.h + Y0 - s.pick(landscape=(0, 0.6), portrait=(0, 0.55)).y) / GAP)
def line(i: int) -> NDArray[np.float64]:
# line i sits i pitches above the bottom edge and lags i steps behind line 0
dense = np.column_stack((xs, s.h + Y0 - i * GAP + amp * np.sin(phase - i * DRIFT)))
return shapely.get_coordinates(shapely.simplify(shapely.LineString(dense), TOL))
with s.buckets(TONES, "stroke", stroke_width=2.4) as b:
for i in range(vein + round(vein * TAIL) + 1):
if abs(i - vein) > 1:
# lines step up the tones towards the picked-out one, so the band has a lit fold
lit = max(0.0, 1 - abs(i - vein) / vein) ** 1.5
b[round(6 * lit)].poly(line(i))
s.stroke(P().poly(line(vein - 1)).poly(line(vein + 1)), ACCENT_3, 2)
s.stroke(P().poly(line(vein)), ACCENT, 3)"""Level lines ripple faster towards the right, each a little behind the one below, so the crests lean; one line is picked out."""
import numpy as np
import shapely
from numpy.typing import NDArray
from walldye import ACCENT, ACCENT_3, BG_ALT, UI, Canvas, P, design, ramp
Y0, GAP = 24, 11 # first line below the bottom edge, line pitch
TOL = 0.1 # simplification tolerance: the flat left part collapses to a few points
AMP0, AMP1 = 16, 12 # amplitude eases off at the right so steep neighbours don't close up
F1, POW = 1 / 60, 3 # frequency at the right edge; f(x) ~ x**POW keeps the left flat
DRIFT = 0.3 # phase lag per line, in radians: the crests lean instead of stacking
TAIL = 19 / 60 # lines above the picked-out one, as a share of the lines below it
TONES = ramp(BG_ALT, UI, 7)
@design(aspects="any")
def draw(s: Canvas) -> None:
xs = np.arange(-4, s.w + 5, dtype=float)
t = np.clip(xs / s.w, 0, 1)
phase = 2 * np.pi * F1 * s.w / (POW + 1) * t ** (POW + 1)
amp = AMP0 + (AMP1 - AMP0) * t**2
vein = round((s.h + Y0 - s.pick(landscape=(0, 0.6), portrait=(0, 0.55)).y) / GAP)
def line(i: int) -> NDArray[np.float64]:
# line i sits i pitches above the bottom edge and lags i steps behind line 0
dense = np.column_stack((xs, s.h + Y0 - i * GAP + amp * np.sin(phase - i * DRIFT)))
return shapely.get_coordinates(shapely.simplify(shapely.LineString(dense), TOL))
with s.buckets(TONES, "stroke", stroke_width=2.4) as b:
for i in range(vein + round(vein * TAIL) + 1):
if abs(i - vein) > 1:
# lines step up the tones towards the picked-out one, so the band has a lit fold
lit = max(0.0, 1 - abs(i - vein) / vein) ** 1.5
b[round(6 * lit)].poly(line(i))
s.stroke(P().poly(line(vein - 1)).poly(line(vein + 1)), ACCENT_3, 2)
s.stroke(P().poly(line(vein)), ACCENT, 3)
Run it yourself
$ git clone https://github.com/nickolaj-jepsen/walldye && cd walldye$ uv run walldye render riley-fall --theme fireproof -o riley-fall-fireproof-16x9.svg