anim ライブラリ
anim は、アニメーションでよく使う計算をまとめた補助ライブラリです。
補間・イージング・波・範囲変換・ベクトル・ノイズ・色変換と、便利な定数を提供します。
これらは標準 Lua にはない、このエフェクト独自の関数です。
定数
| 定数 | 値 | 説明 |
anim.tau | math.pi * 2 | 円一周分のラジアン。周期運動に使う |
anim.e | ネイピア数 | 自然対数の底 |
anim.phi | (1 + sqrt(5)) / 2 | 黄金比 |
anim.sqrt2 | sqrt(2) | 2 の平方根 |
obj.x = obj.x + math.sin(time * anim.tau) * 100
補間・イージング
イージング関数はおおむね 0.0 ~ 1.0 の進行度 t を受け取り、変化のカーブを返します。
obj.t をそのまま渡すのが定番です。
| 関数 | 説明 |
anim.lerp(a, b, t) | a と b を t で線形補間 |
anim.smoothstep(e0, e1, x) | e0 ~ e1 をエルミート補間で滑らかに遷移 |
anim.smootherstep(e0, e1, x) | 2 次導関数まで連続な、より滑らかな遷移 |
anim.ease_in(t) | 2 次イーズイン(加速) |
anim.ease_out(t) | 2 次イーズアウト(減速) |
anim.ease_in_out(t) | 2 次イーズイン・アウト(加速後減速) |
anim.elastic(t) | 弾むようなスプリングイージング(t は 0 ~ 1 にクランプ) |
anim.back(t) | 行き過ぎてから戻るイージング |
anim.bounce(t) | バウンドするイージング(t は 0 ~ 1 にクランプ) |
anim.step(edge, x) | x が edge 以上なら 1.0、未満なら 0.0 |
anim.bezier(t, p0, p1, p2, p3) | t における 3 次ベジェ曲線の値(t は 0 ~ 1 にクランプ) |
2 点間をイージングで移動
local tx, ty = 200, -100
local p = anim.ease_in_out(obj.t)
obj.x = anim.lerp(obj.x, tx, p)
obj.y = anim.lerp(obj.y, ty, p)
弾むように登場
local p = anim.duration(time, 0.3)
obj.zoom = obj.zoom * anim.elastic(p)
範囲・周期
| 関数 | 説明 |
anim.clamp(v, lo, hi) | v を lo ~ hi に収める |
anim.map(v, a1, b1, a2, b2) | 範囲 a1~b1 の v を a2~b2 に変換 |
anim.norm(v, lo, hi) | v が lo~hi のどの割合(0.0~1.0)かを返す |
anim.wrap(v, lo, hi) | v を lo ~ hi でループさせる |
anim.pingpong(t, len) | 0 ~ len を往復する値 |
anim.sign(v) | 符号(正=1, 負=-1, ゼロ=0) |
anim.fract(v) | 小数部分のみ |
anim.oscillate(t, lo, hi, freq) | 周波数 freq で lo~hi を正弦波で往復 |
anim.triangle(t, freq) | 周波数 freq で 0.0~1.0 を往復する三角波 |
anim.square(t, freq) | 周波数 freq で 1.0 と 0.0 を切り替える矩形波 |
anim.duration(t, dur) | 時間 dur に対する割合(0.0~1.0、クランプあり) |
anim.delay(t, d) | 時間 d を引いた値(0 未満は 0) |
値の範囲変換
obj.rz = anim.map(obj.track0, 0, 100, -180, 180)
滑らかな明滅
obj.alpha = anim.oscillate(time, 64, 255, 1)
ベクトル・幾何
| 関数 | 戻り値 | 説明 |
anim.len(x, y) | 数値 | ベクトル (x, y) の長さ |
anim.dist(x1, y1, x2, y2) | 数値 | 2 点間の距離 |
anim.dot(x1, y1, x2, y2) | 数値 | 2 ベクトルの内積 |
anim.normalize(x, y) | x, y | 正規化した方向ベクトル(2 値で返す) |
anim.polar(r, a) | x, y | 半径 r・角度 a(度)から移動量 |
anim.rotate(x, y, a) | x, y | (x, y) を a(度)回転させた座標 |
円運動
local r = obj.track0
local dx, dy = anim.polar(r, time * 90)
obj.x = obj.x + dx
obj.y = obj.y + dy
ノイズ・乱数
| 関数 | 説明 |
anim.noise(x [, y [, z]]) | 1 ~ 3 次元の滑らかなノイズ(0.0 ~ 1.0)。同じ座標では常に同じ値 |
anim.rand(s) | シード s に基づく 0.0 ~ 1.0 の安定した乱数 |
anim.rand(max, s) | 0.0 ~ max の安定した乱数 |
anim.rand(min, max, s) | min ~ max の安定した乱数 |
anim.rand はシードのみで決まる小数の乱数です(フレームは関与しません)。
整数で、フレームによっても変えたい場合は
obj.rand を使ってください。
安定した乱数で個体差をつける
local offset = anim.rand(-50, 50, obj.layer)
obj.x = obj.x + offset
ノイズで揺らぐ手ぶれ風
obj.x = obj.x + (anim.noise(time * 2, 0, 0) - 0.5) * 20
obj.y = obj.y + (anim.noise(0, time * 2, 0) - 0.5) * 20
obj.rz = (anim.noise(0, 0, time * 2) - 0.5) * 10
色変換
| 関数 | 戻り値 | 説明 |
anim.hsv_to_rgb(h, s, v) | r, g, b | HSV(色相 0~360, 彩度 0~1, 明度 0~1)を RGB(0~255)へ変換 |
anim.rgb_to_hsv(r, g, b) | h, s, v | RGB(0~255)を HSV へ変換 |
時間で色相を回す
local hue = anim.wrap(time * 60, 0, 360)
local cr, cg, cb = anim.hsv_to_rgb(hue, 1, 1)
local pd = obj.getpixeldata()
local n = pd.width * pd.height
for i = 0, n - 1 do
local base = i * 4
pd:set(base + 1, pd:get(base + 1) * cr / 255)
pd:set(base + 2, pd:get(base + 2) * cg / 255)
pd:set(base + 3, pd:get(base + 3) * cb / 255)
end