← INDEX / 一覧NYAMCO WORKS89 / 117
p5.js sketchworks/tobasu/sketch.js runs here
作品はここで実行されます(後から差し替え)

WORK 89

Skipped

とばす

YEAR
2026
TOOLS
p5.js
TECHNIQUE
p5.js / one drifting line and a straight chord between now and a fixed distance back

One line keeps drifting toward the right, which is now. From the present point, a straight chord runs back to the point exactly one fixed distance earlier — a way of reading only the two ends. The space between the chord and the line is shaded: the part that reading skips. Most of the time the line wanders to both sides of the chord and comes back, and the shaded part stays thin. The widest gaps open when the whole stretch went off to one side and never returned. That happens less than a third of the time, but it makes up three quarters of the widest gaps. I made this the morning I read a month by its two ends and missed what I had decided in the middle.

一本の線が、右へ、今の方へうねりながら伸びていく。今の点から、ちょうど決まった距離だけ前の点まで、まっすぐな弦を引く。両端だけを読む読み方。弦と線のあいだを淡く塗る。その読み方が飛ばす側。たいていの時間、線は弦の両側を行き来して戻ってくるので、塗られる側は薄い。大きく開くのは、あいだの全部が片側へ行ったまま戻ってこなかったとき。そういう時間は三割に満たないのに、いちばん大きく開いた一割のうち、四分の三を占めていた。一ヶ月を両端だけで読んで、そのあいだに自分が決めていたことを飛ばした朝に作った。

作る前に、予想を三つ書いた。

  1. 塗られる面積は、たいてい小さい。最大はふだんの4倍以上 → 4.1倍。当たったけれど、ぎりぎり。
  2. 線が弦の両側にまたがっている時間の方が長い → 71%。当たった。
  3. 目が弦に行くか、線に行くかは決めなかった。

当たったことより、当てていなかったことの方が残った。いちばん大きく開くのは、線が弦を一度も横切らないとき。横切らない時間は29%しかないのに、上位一割の74%がそれだった。行き来しているあいだは、両端を結んでも大きくは外れない。片側へ行ったきりのとき、山がまるごと一つ飛ぶ。

SOURCE / ソース
// とばす / Skipped
//
// 一本の線が、ゆっくりうねりながら今へ伸びていく。
// 今の点から、ちょうど一ヶ月前にあたる点まで、まっすぐな弦を引く。
// 両端だけを読む読み方。
// 弦とうねりのあいだを、淡く塗る。飛ばされた側。

export const W = 720, H = 720;
export const N = 600;        // 見えている長さ(サンプル数)
export const L = 360;        // 「一ヶ月前」までの距離
export const DX = 1.1;       // 1サンプルあたりの横幅
export const RIGHT = W - 40; // 今の点の x

export function makeY(p) {
  return (i) => {
    const slow = (p.noise(i * 0.0035) - 0.5) * 2;
    const mid = (p.noise(i * 0.012 + 100) - 0.5) * 2;
    const fine = (p.noise(i * 0.05 + 300) - 0.5) * 2;
    return H / 2 + 230 * slow + 60 * mid + 8 * fine;
  };
}

export default function sketch(p) {
  let yAt;

  p.setup = () => {
    p.createCanvas(W, H);
    p.noiseSeed(1001);
    p.noiseDetail(2, 0.5);
    yAt = makeY(p);
  };

  p.draw = () => {
    p.background(14, 15, 20);
    const now = p.frameCount + L + 20;
    const xOf = (i) => RIGHT - (now - i) * DX;

    const a = now - L;
    const ya = yAt(a), yn = yAt(now);
    const chord = (i) => ya + (yn - ya) * ((i - a) / L);

    // 飛ばされた側
    p.strokeWeight(1.2);
    for (let i = a; i <= now; i++) {
      const y = yAt(i), c = chord(i);
      p.stroke(255, 186, 120, 34);
      p.line(xOf(i), c, xOf(i), y);
    }

    // 古いうねり(一ヶ月より前)
    p.noFill();
    p.strokeWeight(1.4);
    // 細かく分けて濃淡を出す
    for (let i = now - N; i < a; i++) {
      const t = (i - (now - N)) / (N - L);
      p.stroke(190, 198, 215, 15 + 80 * t);
      p.line(xOf(i), yAt(i), xOf(i + 1), yAt(i + 1));
    }

    // あいだのうねり
    p.strokeWeight(1.8);
    p.stroke(232, 236, 246, 230);
    for (let i = a; i < now; i++) {
      p.line(xOf(i), yAt(i), xOf(i + 1), yAt(i + 1));
    }

    // 弦
    p.strokeWeight(1);
    p.stroke(255, 196, 140, 210);
    p.line(xOf(a), ya, xOf(now), yn);

    // 両端
    p.noStroke();
    p.fill(255, 210, 170);
    p.circle(xOf(a), ya, 6);
    p.circle(xOf(now), yn, 7);
  };
}