Art を読む
以下の例はすべて実際に動きます。押せばその場で描かれ、 「試す」に持って行けば、書き換えながら試せます。
手引き — 二十五歩
はじめから順に、一歩ずつ。どれもそのまま走る短い作品です。 押すと「試す」へ持って行きます — そこで書き換えながら読んでください。
言語の形
Art は「何が在るか」を書きます。計算機が何をするかは書きません。
draw() も、フレームの数え上げも、状態の更新もありません。
文はどれも、「絵に何かを足す」か「その先の文脈を変える」かのどちらかです。 改行に意味はありません — 一行に詰めても同じ絵が出ます。
形を置く
画布の座標は短いほうの辺が 100です。原点は中心、y は上向き。
だから circle radius: 22 は「短辺の 22%」を意味します。
画布の大きさを変えても、絵の構図は保たれます。
| 形 | 引数 |
|---|---|
circle | radius: |
ellipse | width: height: |
rect | width: height: round: |
square | 大きさをひとつ、名前なしで |
line | from: to: |
path | ブロックの中に to line curve |
text | size: weight: tracking: |
置く場所は、引数ではなく囲みで指定します。
at [x y] { circle radius: 6 } と書きます。これは
frame { move x: x y: y circle radius: 6 } の短い形です。
circle radius: 6 at [x y] と書くと at は次の文になり、
丸は原点に残ります。そのときは、言語がそう知らせます。
入れ子と変形
frame { } は座標系をひとつ作ります。中で move rotate
scale をすると、その中だけが動きます。外へは漏れません。
属性はカスケードします。 fill は「その先の文」に効きます。
frame の中で塗り替えても、外の色は変わりません。
繰り返し
repeat n as i { }。中の変形は累積します — 毎回リセットされません。
これが「らせん」や「輪」を一行で書ける理由です。
単位
裸の数がピクセルを意味することはありません。
角度には deg turn rad、
時間には s ms beat bar、
長さには mm in pt px。
単位を書き忘れると、指摘されます。黙って解釈することはありません。
単位は括弧の直後に、空白なしで置きます — (i / 7)turn。
% — その場所にとっての全体
裸の数は短いほうの辺の何%です。circle radius: 22 の 22 は
「短辺の 22%」でした。明示的に % と書くこともできます — そして % は、
その場所にとっての自然な全体を指します。
| 書く場所 | 50% の意味 |
|---|---|
位置 move x: at line to: | その軸の広がりの半分 |
軸のある寸法 width: height: | その軸の広がりの半分 |
軸の無い寸法 radius: size: stroke width: | 短辺の半分 |
時間 over 50% delay 50% | いまの duration の半分 |
濃さ /50%、scale、speed | 0.5 |
だから at [50% 50%] { … } は、どんな画布でも右上の角です。
正方形の画布では、裸の数と % は同じ値になります。
違いが出るのは、縦横の違う画布や bounds の中だけです。
mm in pt px は実寸です。
印刷やプロッタに出すときは、こちらを書きます —
stroke #333 width: 0.22mm は、どんな大きさで出しても 0.22mm です。
色
#rrggbb のほか、OKLCh が第一の色空間です。
oklch(l: 明るさ, c: 鮮やかさ, h: 色相)。
/50% を後ろに付ければ薄くなります。
palette p = [ … ] で並びにして、p[0] で引けます。
範囲の外を引いたら塗りません。そして、そう知らせます。
時間は寸法と同じ場所に書く
これが Art のいちばん大きな違いです。
数を書ける場所には、区間 3..9 も、時間に開いた区間 3..9 over 2s も書けます。
フレームを数える必要はありません。だからどの時刻へも飛べます。
| 書き方 | 意味 |
|---|---|
a..b over 2s | 2 秒かけて a から b へ |
pingpong | 行って戻る |
loop | 繰り返す |
ease inout | 緩急を付ける |
delay 0.5s | その先の時をずらす |
tempo 2x | その先の時を速める |
場 — 点ごとに色を決める
field { } の中では、x と y がその点の場所です。
返した色がそこに置かれます。塗りつぶしの色でも、端から端への流れでもなく、
式が場所ごとに答える。囲んだ図形の形に切り取られます。
step: は桝の粗さです。小さくすると細かくなり、そのぶん計算は重くなります
(一枚あたりの計算量は「揺らぎを引く回数 × 桝の数」で決まります)。
拡げるときは十六点で混ぜるので、0.7 前後までは角が出ません。
t も読めます。読めば毎フレーム塗り直し、読まなければ一度作って使い回します。
最初のページの絵は、これだけでできています — 図形は地と矩形の二つだけです。
にじみ・粒・型抜き
blur は以降の兄弟要素をぼかします(blur 0 で戻します)。
grain は画面ぜんぶに粒を置きます — 種から決まるので、同じ作品なら同じ粒です。
mask { 型 } { 中身 } は、型の形で中身を切り抜きます。
にじみ・粒・型抜きは画素の上で起きます。SVG で書き出すと、 そのぶんは出せません — 言語はそれを黙らずに知らせます(§18.3)。
偶然は再現する
random 1..5 の値は「種 × 構造的同一性」から決まります。
呼ばれた順ではありません。だから兄弟を増やしても、自分の乱数は動きません。
時刻を戻せば同じ絵が出ます。
つまみ — 作品は絵の族である
param は言語の一部です。範囲と見出しを添えると、
道具がつまみを出します。一つの原文が、絵の族になります。
回しても絵が変わらないつまみは警告されます。 黙って無視することはありません。
自分の語彙
define 名前(引数: 既定) { }。既定値は必須です。書き忘れると指摘されます。
本体は呼ばれた場所の変形と色を継ぎますが、
let で結んだ名前はファイルの最上位と自分の引数だけを見ます。
isolated を付けると、呼ばれた場所の変形と色を継ぎません。
測ることは言語の一部
as 名前 で、置いたものの測られた広がりを受け取れます。
自分で座標を計算する必要がありません。
外の物を読む
data("../data/sales.csv") は表を読みます。行の並びが返るので、
repeat でそのまま回せます。
picture("../data/test.png") は絵を読みます。
.width .height のほか、.at([x y]) で
その画素の色を訊けます(座標は画素で数えます。外を訊いたら端の色が返ります)。
let 写 = picture("../data/test.png")
repeat 16 as i { frame {
move x: (-38 + i * 5)
fill 写.at([i, 8])
rect width: 4 height: 40 } }
パスは作品ファイルからの相対です。読めなければ、そう知らせて先へ進みます(P7)—
黙って白い絵にはしません。
picture は読む絵で、図形にはなりません。置きたいときは image です。
入力 — 触れる作品
mouse key audio camera midi。
繋がっていなければ 0 を返します — 落ちませんし、
何も繋がっていない場所でも「静かな既定の絵」が出ます。
| 入力 | 読めるもの |
|---|---|
mouse | .x .y .down .speed — 画布の単位で |
key | .any .space .arrow.x .arrow.y ほか |
audio | .level .bass .mid .high .beat |
camera | .motion と .frame — 絵としてそのまま置けます |
midi | .cc[n] .held[n] .note .velocity |
音
sound { } は時間の関数です。絵と同じ t を使います。
純粋な関数なので、飛べる・巻き戻せる・書き出せる。
「試す」へ持って行くと、実際に鳴らせます — ♪ 音 を押してください。
WAV で持ち帰ることもできます。コマンドラインからは、
export wav seconds: 2 と書いて node proto/export.js を実行します。
奥行き
space { } の中では move z: と rotate x: y: z: が効きます。
核が持つのはそれと facing、つまりその面がどれだけ手前を向いているかだけで、
陰影も箱も球も、Art 自身で書かれています — std/solid.art です。
import "../std/solid.art"
space {
rotate x: 0.12turn
rotate y: (0.05 + sin((t / 8)turn) * 0.04)turn
box(size: 18, base: #6688cc, light: 0.6) }
書き出す
一つの原文から十七の形へ。すべて自前で書いています — 外部ライブラリはありません。
| 種類 | 形式 |
|---|---|
| ベクタ | svg pdf dxf plot ペンプロッタ |
| 画素 | png jpg tga tiff |
| 動き | gif mp4 frames |
| 音 | wav |
| 数 | json csv tsv txt |
| ページ | web — 処理系ごと入った一枚の HTML |
書き出したものは自分の作り方を持ち歩きます — 原文・種・つまみの上書き、 そして署名が中に入ります。原文は消せますが、姿は消せません。
文字だけは、形式によって幅が変わります。 Art は書体を同梱しません(§15)—
文字の輪郭は表示する機械の書体から借ります。
だから svg は見る人の書体で組まれ、png は書き出した機械の書体で組まれます。
同じ原文でも、文字の幅と位置は少しずれます(測ると、文字のある帯で画素の一割ほど)。
形をそろえたいときは png で書き出すか、文字を path で描いてください。
署名
Art は同じ入力から必ず同じ絵を出します。だから逆に辿れます。 作品の刻みは三段です。
| 刻み | 落とすもの | 捕まえるもの |
|---|---|---|
印 | 何も落とさない | 同じファイル |
骨 | 空白・註釈・宣言の順 | 書き直しただけの複製 |
姿 | 数・色・見出し・あなたの名前 | つまみを回した複製 |
絵の側は、8×8 の区画ごとに縁を刻みます。回転と鏡像は八通り試し、 向きまで言い当てます。 その場で確かめられます →