Skip to content

対象APIレベル: 10

mtは、アニメーションの計算、色の操作、レイアウト、パス、時間制御などに使用する ユーティリティをまとめた名前空間です。

NOTE

timeまたはtには、通常、アニメーション開始からの経過時間を渡します。クリップ先頭から 開始する場合はctx.time、途中から開始する場合はctx.time - startTimeを使用します。

用途別索引 ​

用途API
値の制限・区間写像mt.clamp / mt.saturate / mt.remap / mt.wrap
補間・キーフレームmt.lerp / mt.inverse_lerp / mt.lerp_angle / mt.smoothstep / mt.keyframes
進行度の分配(ドミノ・順次時間差・タイピング)mt.distribute / mt.stagger / mt.stagger_progress / mt.stagger_pattern
手動の描画順・Write On順mt.order_text / mt.CHAR / mt.PART / mt.NOT
距離による影響度(波紋・光沢・衝撃波)mt.falloff
決定論的乱数・ノイズ(散乱・手ブレ揺らぎ)mt.random / mt.random_range / mt.distributed_random / mt.noise1 / mt.noise2 / mt.wiggle
周期・ばね(浮遊・波・減衰振動)mt.cycle / mt.pingpong / mt.wave / mt.wave_square / mt.wave_triangle / mt.wave_sawtooth / mt.spring
極座標からの変位(放射状散乱・公転)mt.polar_offset_2d
方向ベクトルから回転角(アスペクト比補正可)mt.direction_to_rotation_2d
物理モーション(弾道・着地バウンス・摩擦減速)mt.bounce_y / mt.bounce_x / mt.bounce_ground / mt.bounce_wall / mt.impact_squash / mt.projectile_2d / mt.friction_decay
色(色相回転・補間・知覚的一様)mt.color.resolve_fill / mt.color.from_* / mt.color.to_* / mt.color.lerp* / mt.color.with_alpha
要素のシャドウ・ぼかし・ストローク・テクスチャの解決(上位の段階から継承する値の取得)mt.shadow.resolve / mt.blur.resolve / mt.stroke.resolve / mt.texture.resolve
イージングmt.ease.*
再組版・行単位のグループ化mt.layout.reflow / mt.layout.group_by_line
Canvas上の位置・距離・支点mt.layout.place_2d / mt.layout.get_canvas_position_2d / mt.layout.canvas_to_offset_2d / mt.layout.radial_distance / mt.layout.pivot_at_2d
2D変換後の境界mt.layout.measure_bounds_2d
パス上への整列mt.layout.queue_on_path
モーションパスmt.path.bezier / mt.path.catmull_rom / mt.path.arc_length
パスの作成・編集mt.svg_path / path:*
UTF-8テキスト処理mt.text.slice / mt.text.classify
文字・パーツの指定文字列mt.target.chars / mt.target.parts
クリップ時間mt.timeline.progress / mt.timeline.duration / mt.timeline.remaining / mt.timeline.intro_outro_seconds / mt.timeline.window_progress / mt.timeline.window_ctx / mt.timeline.chain
非推奨の互換APImt.storage / mt.polar_offset / mt.layout.retypeset / mt.layout.canvas_to_offset / mt.layout.set_canvas_position / mt.layout.group_bounds / mt.timeline.intro_outro

1. 値の制限・区間写像 ​

mt.clamp(value, low, high) ​

APIレベル: 1+

値を閉区間 [low, high] へ制限します。

引数 ​

引数型単位省略時内容
valuenumber-指定必須制限する値
lownumber-指定必須下限
highnumber-指定必須上限

戻り値 ​

型単位内容
number-制限後の値

mt.saturate(value) ​

APIレベル: 1+

mt.clamp(value, 0.0, 1.0) の短縮形です。進行度やアルファ値を0-1に収めるときに使います。

引数 ​

引数型単位省略時内容
valuenumber-指定必須0-1へ制限する値

戻り値 ​

型単位内容
number0-10-1へ制限された値

mt.remap(value, in_low, in_high, out_low, out_high, clamped?) ​

APIレベル: 1+

値を入力区間から出力区間へ写します。「秒数を進行度に変換する」など区間の変換全般に使います。

引数 ​

引数型単位省略時内容
valuenumber-指定必須変換する値
in_low / in_highnumber-指定必須入力区間
out_low / out_highnumber-指定必須出力区間
clampedboolean-falsetrueなら入力位置を0-1へ制限してから変換します

戻り値 ​

型単位内容
number-変換後の値

制約・エラー ​

条件内容
in_low == in_high入力区間の幅が0になるため指定できません

使用例 ​

lua
-- 0.5秒から1.2秒にかけて、Yオフセットを0.7から0.5へ
character.offset_y = mt.remap(ctx.time, 0.5, 1.2, 0.7, 0.5, true)

mt.wrap(value, boundaryA, boundaryB) ​

APIレベル: 1+

値を2つの境界のうち小さい方を含み、大きい方を含まない半開区間 [min(boundaryA, boundaryB), max(boundaryA, boundaryB))内で周回させます。 境界はどちらの順でも指定できます。角度や色相の周期化に使います。

APIレベル6での変更: 境界をlow / highではなくboundaryA / boundaryBとして扱い、 逆順の指定でも小さい境界から大きい境界までの区間を周回するようになりました。

引数 ​

引数型単位省略時内容
valuenumber-指定必須周回させる値
boundaryAnumber-指定必須区間を決める一方の境界
boundaryBnumber-指定必須区間を決めるもう一方の境界

戻り値 ​

型単位内容
number-周回後の値

制約・エラー ​

2つの境界が等しい場合は、その境界値を返します。

2. 補間・キーフレーム ​

mt.lerp(from, to, t) ​

APIレベル: 1+

from から to への線形補間です。

引数 ​

引数型単位省略時内容
fromnumber-指定必須t = 0のときの値
tonumber-指定必須t = 1のときの値
tnumber-指定必須補間係数。クランプされないため、0-1の外を渡すと外挿されます

戻り値 ​

型単位内容
number入力値と同じfrom + (to - from) * t

mt.inverse_lerp(from, to, value) ​

APIレベル: 1+

mt.lerp の逆関数です。value が区間 [from, to] のどの位置にあるかを補間係数として返します。

引数 ​

引数型単位省略時内容
fromnumber-指定必須係数0に対応する区間の始端
tonumber-指定必須係数1に対応する区間の終端
valuenumber-指定必須位置を求める値

戻り値 ​

型単位内容
number-(value - from) / (to - from)。クランプされません

制約・エラー ​

from == toの場合は0を返します。


mt.lerp_angle(from, to, t) ​

APIレベル: 1+

角度(degree)を最短方向で補間します。mt.lerp(350, 10, t) のような遠回りを避けたいときに 使います(350°→10°を+20°側で補間)。

引数 ​

引数型単位省略時内容
fromnumberdegree指定必須開始角度
tonumberdegree指定必須目標角度
tnumber-指定必須補間係数。クランプされません

戻り値 ​

型単位内容
numberdegree補間後の角度

mt.smoothstep(edge0, edge1, value) ​

APIレベル: 1+

value が edge0 から edge1 を横切る間、0から1へ滑らかに遷移する値を返します (Hermite補間。両端で速度が0になります)。

引数 ​

引数型単位省略時内容
edge0number-指定必須結果が0になる遷移の開始位置
edge1number-指定必須結果が1になる遷移の終了位置
valuenumber-指定必須評価する値

戻り値 ​

型単位内容
number0-1滑らかな遷移値。区間外はクランプされます

制約・エラー ​

条件内容
edge0 == edge1遷移区間の幅が0になるため指定できません

mt.keyframes(keys, time) ​

APIレベル: 1+

複数区間のキーフレームを評価します。ctx.timeから直接呼べるため、 落下→バウンド→静止のような多段の振り付けを clamp + inverse_lerp の手書きなしで書けます。

引数 ​

引数型単位省略時内容
keystable[]-指定必須キーフレームの配列。各要素は{ t = <時刻>, v = <値>, ease = <省略可> }で、tを昇順に並べます
timenumber秒指定必須評価する時刻

各キーの v は number または { r, g, b, a } 形式の color テーブルのいずれかで、1つの keys 配列内で混在させることはできません。ease は省略可(既定は線形)で、そのキーへ到達するまでの 区間に適用されます。mt.ease.out_bounce のような名前の文字列、または function(t) ... end の 形の任意のイージング関数を渡せます。

time が最初のキーより前なら最初の値、最後のキーより後なら最後の値を返します(クランプ)。

戻り値 ​

型単位内容
number | colorキーの値と同じ区間内で補間された値

使用例 ​

lua
-- 0.0〜0.3秒でバウンドしながら落下し、0.3〜0.5秒は静止、
-- 0.5秒以降クリップ終端に向けてゆっくり退場する
local y = mt.keyframes({
    { t = 0.0, v = 1.2 },
    { t = 0.3, v = 0.5, ease = "out_bounce" },
    { t = 0.8, v = 0.5 },
    { t = 1.3, v = -0.2, ease = "in_cubic" },
}, ctx.time)

-- color もそのまま補間できる
local tint = mt.keyframes({
    { t = 0.0, v = { r = 1.0, g = 1.0, b = 1.0, a = 1.0 } },
    { t = 1.0, v = { r = 1.0, g = 0.4, b = 0.1, a = 1.0 } },
}, ctx.time)
character.fill.color = tint

3. 進行度の分配 ​

mt.distribute(index, count) ​

APIレベル: 1+

1始まりの index を 0-1 へ均等に割り付けます。先頭が 0、末尾が 1 になります。

引数 ​

引数型単位省略時内容
indexinteger-指定必須1始まりのindex。ctx.chars[index]のindexなどを渡します
countinteger-指定必須総数。ctx.char_countなどを渡します

戻り値 ​

型単位内容
number0-1(index - 1) / (count - 1)を0-1へ制限した値。count <= 1の場合は0

使用例 ​

lua
-- 文字位置に応じて色相を虹状に配置
local hue = mt.distribute(index, ctx.char_count)
character.fill.use = true
character.fill.color = mt.color.from_okhsv(hue, 0.8, 1.0)

mt.order_text(entries) ​

APIレベル: 8+

文字またはglobal partのindexを符号化した配列から、検証済みのctx.output.manual_order_textを生成します。入力順と重複は維持します。

文字は1始まりのindexをそのまま、またはmt.CHAR | indexで指定し、global partはmt.PART | indexで指定します。各indexは1以上1024以下のintegerでなければなりません。manual orderには除外構文がないため、mt.NOTは使用できません。

引数 ​

引数型単位省略時内容
entriesinteger[]-指定必須出力順に並べた文字・global partの符号化index

戻り値 ​

型単位内容
string-入力順を表す有効なmanual order文字列。空配列では空文字列

使用例 ​

lua
local order = {}
for index = ctx.char_count, 1, -1 do
    order[#order + 1] = mt.CHAR | index
end
ctx.output.manual_order_enabled = true
ctx.output.manual_order_text = mt.order_text(order)

mt.CHAR ​

値は0x0000。1始まりの文字indexと合成する文字種別flagです。値が0のため、indexをそのまま指定しても同じ意味になります。

mt.PART ​

値は0x10000。1始まりのglobal part indexと合成するパーツ種別flagです。下位16bitはindex専用です。

mt.NOT ​

値は0x20000。targets構文用の除外flagです。mt.order_textには渡せません。


mt.each_char(ctx, options?) ​

APIレベル: 6+

整形済み文字を絞り込みつつ反復するイテレータを返します。index は常に ctx.chars 上のindexなので、ctx.chars[index] や mt.layout.* にそのまま渡せます。絞り込み後の通し番号は info.n です。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayout / OnPath の context
options.frominteger-1反復を開始する文字index
options.tointeger-ctx.char_count反復を終了する文字index(この値を含む)
options.lineinteger-絞り込みなしこの line_index の文字だけを通します
options.orderstring-"asc"info.progress の割り当て順。"asc" / "desc" / "center" / "random"
options.seedinteger-0order = "random" のときの並びを決めるseed

戻り値 ​

型内容
functionindex(ctx.chars上のindex)、character、info を返すイテレータ

info の各フィールド:

フィールド型内容
progressnumberorder に沿った 0-1 の正規化位置
ninteger絞り込み後の通し番号(1始まり)
countinteger絞り込み後の要素数(最低1)
first / lastboolean絞り込み後の先頭・末尾かどうか

order の割り当ては次の通りです(訪問順は常にindexの昇順で、変わるのは progress の値だけです)。

指定progress の並び(5要素の場合)
"asc"0, 0.25, 0.5, 0.75, 1
"desc"1, 0.75, 0.5, 0.25, 0
"center"1, 0.5, 0, 0.5, 1
"random"seedで決まる重複のない並び替え

"center" は中点からの距離を正規化した値です。要素数が偶数の場合は中点に要素が乗らないため、最小値は 0 になりません。

注意: info は毎回同じテーブルを使い回します。ループの外へ持ち出す場合は値をコピーしてください。

使用例 ​

lua
-- 2行目だけを、中央から外側へ順に開く
for index, character, info in mt.each_char(ctx, { line = 1, order = "center" }) do
    local delay = info.progress * 0.4
    character.opacity = mt.saturate((ctx.time - delay) * 4.0)
end

mt.each_part(ctx, options?) ​

APIレベル: 6+

整形済みパートを絞り込みつつ反復するイテレータを返します。mt.each_char と同じ規則に加えて、所属文字を info から直接参照でき、所属文字による絞り込みができます。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayout / OnPath の context
options.frominteger-1反復を開始するパートindex
options.tointeger-ctx.part_count反復を終了するパートindex(この値を含む)
options.from_charinteger-絞り込みなし所属文字のindexがこの値以上のパートだけを通します
options.to_charinteger-絞り込みなし所属文字のindexがこの値以下のパートだけを通します
options.lineinteger-絞り込みなしこの line_index のパートだけを通します
options.orderstring-"asc"info.progress の割り当て順。mt.each_char と同じ
options.seedinteger-0order = "random" のときの並びを決めるseed

from / to(パートindexの範囲)と from_char / to_char(所属文字indexの範囲)は別々の軸で、両方指定した場合は両方を満たすパートだけが通ります。

戻り値 ​

型内容
functionindex(ctx.parts上のindex)、part、info を返すイテレータ

info は mt.each_char の全フィールドに加えて次を持ちます。

フィールド型内容
charMtCharacterこのパートが属する文字(ctx.chars の要素)
char_indexinteger属する文字の ctx.chars 上のindex
index_in_charintegerその文字の中での位置

info.progress は絞り込み後の集合全体を通しで 0-1 に張ります。文字の境界でリセットはしません。文字ごとに 0-1 を張りたい場合は mt.each_char と mt.each_part を入れ子にしてください。

使用例 ​

lua
-- 3〜5文字目のパートだけを、通しで順に持ち上げる
for index, part, info in mt.each_part(ctx, { from_char = 3, to_char = 5 }) do
    part.offset_y = info.progress * 0.05
    part.rotation = info.char.rotation * 0.5
end

mt.stagger(time, index, delay, duration) ​

APIレベル: 1+

index ごとに開始をずらしたアニメーション進行度(ドミノ倒し、カスケード登場、タイピング風の順次アニメーション)を返します。文字送りの定番関数です。 index i のアニメーションは delay * (i - 1) 秒遅れて始まり、duration 秒かけて 0から1へ進みます。

引数 ​

引数型単位省略時内容
timenumber秒指定必須アニメーション開始からの経過時間
indexinteger-指定必須1始まりのindex
delaynumber秒指定必須次のindexが開始するまでの遅延
durationnumber秒指定必須各indexのアニメーション時間

戻り値 ​

型単位内容
number0-10-1へクランプされた進行度

制約・エラー ​

条件内容
duration <= 00より大きい値を指定してください

使用例 ​

lua
for index = 1, ctx.char_count do
    local progress = mt.stagger(ctx.time, index, 0.08, 0.4)
    ctx.chars[index].offset_y = 0.5 + (1.0 - mt.ease.out_cubic(progress)) * 0.2
end

mt.stagger_progress(progress, position, span) ​

APIレベル: 6+

0-1へ正規化済みの全体進行度へ、要素位置に応じた開始時間差(一斉・同期登場やグループカスケード)を付けます。 position = 0の要素は全体と同時に開始し、position = 1の要素は全体進行度が spanへ達した時点で開始します。すべての要素は全体進行度が1へ達した時点で完了します。

秒単位の時刻、index、要素ごとのdurationから進行度を作る場合はmt.staggerを使用します。 mt.timeline.intro_outro_secondsなどから得た既存の進行度を分散する場合は mt.stagger_progressを使用します。

引数 ​

引数型単位省略時内容
progressnumber0-1指定必須分散元の全体進行度。範囲外も許可され、戻り値が0-1へクランプされます
positionnumber0-1指定必須要素の正規化位置。範囲外は0-1へクランプされます。通常はinfo.progressを渡します
spannumber0-1未満指定必須全体時間のうち、開始時刻の分散に使用する割合

戻り値 ​

型単位内容
number0-1positionに対応する要素の進行度

戻り値は次の式で計算されます。

lua
mt.saturate((progress - mt.saturate(position) * span) / (1.0 - span))

制約・エラー ​

条件内容
progressまたはpositionが有限数ではないエラー
spanが有限数ではないエラー
span < 0またはspan >= 1エラー

使用例 ​

lua
local introProgress, outroProgress =
    mt.timeline.intro_outro_seconds(ctx, 0.5, 0.5, 5.0)

for _, character, info in mt.each_char(ctx, { order = "center" }) do
    local appear = mt.ease.out_back(
        mt.stagger_progress(introProgress, info.progress, 0.35))
    local disappear = mt.ease.in_cubic(
        mt.stagger_progress(outroProgress, info.progress, 0.25))

    character.scale = appear
    character.opacity = appear * (1.0 - disappear)
end

mt.each_char / mt.each_partのorderを変えると、ループの訪問順を変えずに 開始時間の割り当てだけを変更できます。


mt.stagger_pattern(time, index, count, pattern, delay, duration, seed?) ​

APIレベル: 1+

開始方向や順序(昇順・降順・中央から外側への波紋・重複なしランダム順)を指定できるスタガー進行度を返します。

引数 ​

引数型単位省略時内容
timenumber秒指定必須評価する時刻
indexinteger-指定必須1始まりのindex
countinteger-指定必須総数。ctx.char_countなどを渡します
patternstring-指定必須進行パターン。"asc" / "desc"(別名"right_to_left")/ "center" / "random"
delaynumber秒指定必須開始遅延
durationnumber秒指定必須アニメーション時間
seedinteger-42pattern = "random"のときの乱数種

"random"は各indexへ重複しないランダム順位を割り当てます。順位は必ず1つずつ離れるため、遅延の間隔が均等になります。

APIレベル6での変更: 以前はindexごとに独立した乱数で遅延を決めていたため、数文字が偶然ほぼ同時に動き、逆に何も起きない区間ができることがありました。現在は順列を使うため、同じseedでも以前とは並びが変わります。

戻り値 ​

型単位内容
number0-10-1へクランプされた進行度

制約・エラー ​

条件内容
duration <= 00より大きい値を指定してください

4. 距離による影響度 ​

mt.falloff(distance, radius) ​

APIレベル: 3+

中心で最大、離れるほどなだらかに弱まる影響度の重み(波の通過、光沢の走り、水面の波紋、衝撃波、局所強調)を返します。戻り値は 0〜1 です。

引数 ​

引数型単位省略時内容
distancenumber入力座標系指定必須効果の中心からの距離
radiusnumber入力座標系指定必須減衰の広がり。この距離で重みが約0.37(e^-1)になります

「波の峰」「走る光沢」「注目箇所だけ強調」など、特定の位置を中心に効果を集中させる用途の定番です。

mt.smoothstep との使い分け: smoothstep は範囲外で完全に 0 になる(切れ目ができる)のに対し、falloff は裾が無限に続くため、峰や光が通り抜けていく動きが途切れずに見えます。線形減衰(1 - d/r)のような折れ曲がりも生じません。

戻り値 ​

型単位内容
number0-1距離に応じた影響度の重み

使用例 ​

lua
-- 波の先端 waveFront が通過した文字だけを持ち上げる
local distance = characterRadius - waveFront
character.offset_y = 0.5 + mt.falloff(distance, 0.25) * 0.1

NOTE

radius に 0 を渡した場合は 0 を返します(ゼロ除算を避けるため)。

5. 決定論的乱数・ノイズ ​

mt.random(seed, index, channel?) ​

APIレベル: 1+

(seed, index, channel) の組だけで値が決まる安定乱数です。呼び出し順に依存しないため、 文字・パーツごとのばらつきに安全に使えます(math.random は呼び出し順に依存するため この用途には使えません)。

TIP

"angle"や"distance"のようにchannelへ用途ごとの名前を付けると、seedやindexへ 手作業でsaltを加えずに独立した乱数を得られます。

APIレベル6での追加: 任意の文字列channelを指定できるようになりました。 省略時の結果は以前と同じです。

引数 ​

引数型単位省略時内容
seedinteger-指定必須乱数系列を選ぶ値。同じ用途には同じseedを使います
indexinteger-指定必須系列内の位置。文字indexなどを渡します
channelstring-省略用途を分離する名前。

戻り値 ​

型単位内容
number0-1[0, 1)の乱数。同じ引数なら常に同じ値

制約・エラー ​

channelはUTF-8のバイト列を固定の32bitハッシュへ変換します。Unicode正規化は行わないため、 channel名には"angle"や"color.hue"のようなASCII文字列を推奨します。32bitハッシュには 理論上の衝突があり、暗号用途には使用できません。


mt.random_range(seed, index, low, high, channel?) ​

APIレベル: 1+

mt.random の結果を [low, high) へ変換した値を返します。では、 任意の文字列channelで用途ごとの乱数系列を分離できます。

引数 ​

引数型単位省略時内容
seed / indexinteger-指定必須mt.randomと同じ
low / highnumber-指定必須出力範囲
channelstring-省略mt.randomと同じ。

戻り値 ​

型単位内容
number出力範囲と同じ[low, high)の安定乱数

mt.distributed_random(seed, index, count, low, high, channel?) ​

APIレベル: 8+

count個の等間隔な値を、決定論的な順列で1始まりのindexへ割り当てます。戻り値は[low, high)に収まり、mt.random_rangeを独立に呼ぶ場合と異なり、全体に値の集中や重複がありません。mt.each_charまたはmt.each_partと組み合わせる場合は、絞り込み後もindexが連続するようinfo.nとinfo.countを渡します。

引数 ​

引数型単位省略時内容
seedinteger-指定必須順列と共通offsetを決める値
indexinteger-指定必須1以上count以下の割り当て位置
countinteger-指定必須値の個数。1以上
low / highnumber-指定必須low < highを満たす有限の出力境界
channelstring-省略独立した割り当てを分離する名前

戻り値 ​

型単位内容
number出力範囲と同じ[low, high)内の安定した割り当て値。sort後の隣接値は(high - low) / countずつ離れます

使用例 ​

lua
for _, character, info in mt.each_char(ctx) do
    local phase = mt.distributed_random(
        ctx.meta.instance_seed, info.n, info.count, 0.0, math.pi * 2.0, "phase")
    character.offset_y = 0.5 + mt.wave(ctx.time, 0.5, phase) * 0.03
end

mt.noise1(x, seed?) ​

APIレベル: 1+

決定論的な1次元 value noise です。x に対して滑らかに連続する「揺らぎ」を返します。 x に時間を渡せば時間方向の揺らぎ、位置を渡せば空間方向の揺らぎになります。

引数 ​

引数型単位省略時内容
xnumber-指定必須サンプル位置。整数間隔の格子点間が滑らかに補間されます
seedinteger-0揺らぎのパターンを変える値

戻り値 ​

型単位内容
number-1-1同じ引数に対して常に同じ連続値

使用例 ​

lua
-- 文字ごとに位相の違う手ぶれ風の揺れ
character.rotation = mt.noise1(ctx.time * 0.8, index) * 4.0

mt.noise2(x, y, seed?) ​

APIレベル: 1+

決定論的な2次元 value noise です。位置 (x, y) に対して滑らかな揺らぎを返します。 片方の軸に時間、もう片方に文字位置を渡すと「空間的に流れる」揺らぎが作れます。

引数 ​

引数型単位省略時内容
x / ynumber-指定必須サンプル位置
seedinteger-0揺らぎのパターンを変える値

戻り値 ​

型単位内容
number-1-1同じ引数に対して常に同じ連続値

mt.wiggle(time, frequency, amplitude, octaves?, seed?) ​

APIレベル: 1+

決定論的ノイズによる有機的な揺らぎ(手ブレ、ランダムな微振動、浮遊感)を計算します。

引数 ​

引数型単位省略時内容
timenumber秒指定必須評価する時刻
frequencynumberHz指定必須1秒あたりの揺れの回数
amplitudenumber出力値と同じ指定必須第1オクターブの振幅。複数オクターブの合計最大値ではありません
octavesinteger-1重ねるノイズのオクターブ数
seedinteger-0乱数種

戻り値 ​

型単位内容
numberamplitudeと同じ揺らぎの値

octaves > 1では振幅を半減しながら加算するため、理論上の絶対値上限は amplitude * (2 - 2^(1 - octaves))で、オクターブ数が増えると2 * amplitudeへ近づきます。

6. 周期・ばね ​

mt.cycle(t, period) ​

APIレベル: 1+

0から1へ繰り返すノコギリ波進行度(ループアニメーション、回転、連続タイマー、レーダー走査)を返します。

引数 ​

引数型単位省略時内容
tnumber秒指定必須評価する時刻
periodnumber秒指定必須1周期の長さ

戻り値 ​

型単位内容
number0-10以上1未満の進行度

制約・エラー ​

条件内容
period <= 00より大きい値を指定してください

mt.pingpong(t, period) ​

APIレベル: 1+

0→1→0を繰り返す往復進行度(振り子運動、シャトル往復)を返します。行って戻るループに使います。

引数 ​

引数型単位省略時内容
tnumber秒指定必須評価する時刻
periodnumber秒指定必須1往復の長さ

戻り値 ​

型単位内容
number0-10-1の往復値

制約・エラー ​

条件内容
period <= 00より大きい値を指定してください

mt.wave(t, frequency, phase?) ​

APIレベル: 1+

正弦波による周期運動(浮遊、上下の揺れ、うねり、呼吸のような緩急)を計算します。短縮形 sin(2π × frequency × t + phase) です。

引数 ​

引数型単位省略時内容
tnumber秒指定必須評価する時刻
frequencynumberHz指定必須1秒あたりの周期数
phasenumberradian0位相オフセット。indexごとに波をずらす用途にも使えます

戻り値 ​

型単位内容
number-1-1波形値

mt.wave_square(t, frequency, phase?) ​

APIレベル: 1+

矩形波による周期的な二値切り替え(点滅、ストロボ、フラッシュ)を計算します。

引数 ​

引数型単位省略時内容
tnumber秒指定必須評価する時刻
frequencynumberHz指定必須1秒あたりの周期数
phasenumberradian0位相オフセット

戻り値 ​

型単位内容
number--1.0または1.0

mt.wave_triangle(t, frequency, phase?) ​

APIレベル: 1+

三角波(トライアングルウェーブ)です。

引数 ​

引数型単位省略時内容
tnumber秒指定必須評価する時刻
frequencynumberHz指定必須1秒あたりの周期数
phasenumberradian0位相オフセット

戻り値 ​

型単位内容
number-1-1-1.0から1.0の間で直線的に往復する値

mt.wave_sawtooth(t, frequency, phase?) ​

APIレベル: 1+

のこぎり波(ソートゥースウェーブ)です。

引数 ​

引数型単位省略時内容
tnumber秒指定必須評価する時刻
frequencynumberHz指定必須1秒あたりの周期数
phasenumberradian0位相オフセット

戻り値 ​

型単位内容
number-1-1-1.0から1.0未満へ直線的に上昇し、繰り返す値

mt.spring(t, frequency, damping) ​

APIレベル: 1+

減衰振動(バネの揺れ戻し、プルプルした弾性、ぐらつき、オーバーシュートからの収束)を計算します。t = 0で1から始まり、振動しながら0へ収束します。

引数 ​

引数型単位省略時内容
tnumber秒指定必須動き始めてからの経過時間。t <= 0では初期値を返します
frequencynumberHz指定必須1秒あたりの振動回数
dampingnumber1/秒指定必須減衰の強さ。大きいほど早く収束します

戻り値 ​

型単位内容
number-初期値1から0へ収束する減衰振動値

t > 0ではexp(-damping * t) * cos(2π * frequency * t)を計算します。

WARNING

戻り値は 0-1 に収まりません。 減衰中に 負の値(および、位相によっては 1 をわずかに 超えない範囲での行き過ぎ)を取り得ます。これはオーバーシュート表現そのものであり、 mt.ease.out_back / elastic が 0-1 の外へはみ出すのと同種です。

  • 向いている用途: offset / rotation / 散らばり量などの変位の残差 (例: 0.5 + settle * 0.1)
  • 向いていない用途: 進行度・opacity・scale / stretch へのそのままの代入や、 mt.lerp の t としての利用。進行度が必要なら mt.ease.* や mt.saturate を使い、 負値をそのまま倍率に掛けないでください(stretch はホスト側の下限クランプがなく、 負のまま描画に渡り得ます。scale は正の下限へクランプされ、opacity は描画直前に 0-1 へクランプされます)

使用例 ​

lua
-- 目標位置からのずれとして使う(t=0で最大、時間とともに収束。負の区間が行き過ぎ)
local settle = mt.spring(ctx.time - start_time, 3.0, 4.0)
character.offset_y = 0.5 + settle * 0.1

7. 極座標からの変位 ​

mt.polar_offset_2d(angleDegrees, radius) ​

APIレベル: 5+

極座標(方向と距離)を Canvas 空間のオフセット 2 値へ変換します(放射状の飛び散り、円運動・公転、爆発演出)。散開・集結・周回といった動きを cos / sin を書かずに表現できます。

引数 ​

引数型単位省略時内容
angleDegreesnumberdegree指定必須方向。座標と同じく、0度は右方向で正の値は時計回りです
radiusnumbercanvas正規化変位指定必須その方向への距離

戻り値 ​

型単位内容
number, numbercanvas正規化変位offsetX, offsetYの2値

入力角度はrotation / shadow.angleと同じ画面基準(90度は下)ですが、戻り値はY-upです。 offset_x / offset_yへそのまま加算できます。mt.projectile_2dも同じ規則です。

使用例 ​

lua
-- 文字ごとに放射状へ散らす
local angle = mt.distribute(index, ctx.char_count) * 360.0
local dx, dy = mt.polar_offset_2d(angle, 0.3 * scatterAmount)
character.offset_x = 0.5 + dx
character.offset_y = 0.5 + dy

mt.direction_to_rotation_2d(dx, dy, aspectRatio?) ​

API level: 15+

Y-up の方向ベクトルから、時計回りを正とする回転角(度)を返します。必須引数 dx・dy は数値です。第3引数を省略する場合、両方ともピクセルなど、同じ縮尺で指定します。右は0度、下は90度、上は-90度です。戻り値は -180〜180 度、ゼロベクトルは0度です。正の半径での mt.polar_offset_2d と逆向きの変換です。

省略可能な第3引数 aspectRatio(既定1)でXの縮尺を補正します。画面幅比・高さ比の変位から求める場合は ctx.canvas.aspect_ratio を指定します。ローカル・グローバル間の変換は行いません。回転の適用先と同じ座標空間の方向を使ってください。未回転時の前方向を +X とする角度なので、元の図柄が別方向を向く場合は補正角を加えます。

lua
local dx, dy = mt.polar_offset_2d(45, 0.1)
character.rotation = mt.direction_to_rotation_2d(dx, dy) -- 45 degrees

-- Heading from normalized canvas deltas, with equally scaled axes:
local heading = mt.direction_to_rotation_2d(deltaX, deltaY, ctx.canvas.aspect_ratio)

8. 物理モーション ​

mt.bounce_y(config) / mt.bounce_x(config) ​

APIレベル: 3+

床面(Y軸)または壁面(X軸)に対する1次元弾道バウンドの位置、速度、Squash & Stretch、 接触位置の補正量を計算して返します。文字やパーツは直接変更しません。設定table形式と 引数並び形式の両方で呼び出せます。

引数 ​

引数型単位省略時内容
configtable-指定必須時刻、衝突面、開始位置、重力または加速度、反発係数、初速、Squash & Stretchの設定

共通のconfig ​

フィールド型単位省略時内容
tnumber秒0.0アニメーション開始からの経過時間
restitutionnumber-0.5反発係数。値が大きいほど衝突後の跳ね返りが強くなります
start_velocitynumbercanvas正規化変位/秒0.0軸方向の初速
squash / squash_strengthnumber係数0.15衝突速度に応じて接触軸を潰す強さ
stretch / stretch_strengthnumber係数0.02移動速度に応じて進行軸を伸ばす強さ
flexibilitynumberradian/秒16.0衝突後に元の形へ戻る振動の速さ
dampingnumber1/秒7.0衝突後の振動が収束する速さ

同じ項目に複数の名前がある場合は、左側の名前を優先して使用します。右側は互換用の別名です。

mt.bounce_y固有のconfig ​

フィールド型単位省略時内容
ground_ynumbercanvas正規化位置0.0衝突する床面のY座標
start_ynumbercanvas正規化位置0.0開始時のY座標
gravitynumbercanvas正規化変位/秒²9.81床面へ向かう加速度の大きさ

mt.bounce_x固有のconfig ​

フィールド型単位省略時内容
wall_x / ground_xnumbercanvas正規化位置0.0衝突する壁面のX座標。ground_xは互換用の別名です
start_xnumbercanvas正規化位置0.0開始時のX座標
acceleration / accel_x / gravitynumbercanvas正規化変位/秒²9.81壁面へ向かう加速度の大きさ。accel_xとgravityは互換用の別名です

引数並び形式 ​

設定tableの代わりに、各値を次の順序で渡すこともできます。

lua
mt.bounce_y(t, groundY, startY, gravity, restitution, startVelocity,
    squashStrength, stretchStrength, flexibility, damping)

mt.bounce_x(t, wallX, startX, acceleration, restitution, startVelocity,
    squashStrength, stretchStrength, flexibility, damping)

各引数は省略でき、対応するconfigフィールドと同じ既定値を使用します。

戻り値(いずれか) ​

型単位内容
table-設定table形式では、位置、速度、変形、衝突状態を持つtable
複数のnumber各値に準拠引数並び形式では、計算結果を8値で返します

戻り値table ​

フィールド型単位内容
posnumbercanvas正規化位置計算後の軸座標
ynumbercanvas正規化位置mt.bounce_yの計算後のY座標。posと同じ値です
xnumbercanvas正規化位置mt.bounce_xの計算後のX座標。posと同じ値です
velocitynumbercanvas正規化変位/秒その時点の軸方向速度
stretch_x / stretch_ynumber倍率Squash & Stretchを反映したX方向とY方向の伸縮率
offset_ynumberbounds_heightに対する比率mt.bounce_yで接地位置を保つための補正量
offset_xnumberbounds_widthに対する比率mt.bounce_xで接触位置を保つための補正量
last_impact_timenumber / nil秒直前の衝突時刻。まだ衝突していない場合はnilです
next_impact_timenumber / nil秒次に衝突する時刻。静止済みの場合はnilです
impact_countinteger回これまでの衝突回数
settledboolean-バウンドが終了して静止したかどうか

tableの[1]〜[5]でも、軸座標、stretch_x、stretch_y、接触位置の補正量、 velocityの順に取得できます。

引数並び形式では、軸座標、stretch_x、stretch_y、接触位置の補正量、velocity、 last_impact_time、next_impact_time、impact_countの順に返します。settledは設定table形式で のみ取得できます。

注意事項 ​

  • restitutionは通常、0以上1未満を指定します。
  • gravityまたはaccelerationの符号は使用されず、絶対値が加速度の大きさとして扱われます。

使用例 ​

lua
-- 詳細設定テーブルで Y 軸バウンド物理を精密計算
local b = mt.bounce_y({
    t = ctx.time,
    ground_y = 0.1,
    start_y = 0.6,
    gravity = 9.81,
    restitution = 0.5,
    squash = 0.2,
    stretch = 0.03,
    flexibility = 18.0,
    damping = 6.0,
})

-- 計算結果を柔軟に適用
local targetY = b.y + b.offset_y * char.geometry.bounds_height
local _, calcOffsetY = mt.layout.canvas_to_offset_2d(ctx, char, curX, targetY)
char.offset_y = calcOffsetY
char.stretch_x = b.stretch_x
char.stretch_y = b.stretch_y

mt.bounce_ground(ctx, item, groundY, config?) ​

APIレベル: 3+

文字またはパーツ item を指定した地面 Canvas 座標 groundY(例: 0.1)に向かってドロップし、ポヨンとバウンド・着地させる簡易便利関数です。offset_y, stretch_x, stretch_y が自動適用されます。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト
itemtable-指定必須変更する文字またはパーツ
groundYnumbercanvas正規化座標指定必須接地先のY座標
configtable-nil開始位置、接地基準、物理パラメータなどの設定

戻り値 ​

型単位内容
table-計算済みのバウンド状態

変更内容 ​

フィールド型単位内容
item.offset_ynumbercanvas正規化変位計算したY方向の変位を設定します
item.offset_xnumbercanvas正規化変位ground_mode = "absolute"の場合に、現在のcanvas上のX位置を保つ変位を設定します
item.stretch_x / item.stretch_ynumber倍率バウンド状態のSquash & Stretchを設定します

config ​

フィールド型単位省略時内容
tnumber秒ctx.time評価する時刻
delaynumber秒0.0動き始めるまでの待ち時間
start_modestring-start_y指定時は"absolute"、それ以外は"relative"開始位置の基準。"relative"では現在位置からdrop_heightだけ上、"absolute"ではstart_yを使用します
start_ynumbercanvas正規化位置nilstart_mode = "absolute"で使用する開始位置
drop_heightnumbercanvas正規化変位0.3start_mode = "relative"で現在位置から上へ離す距離
ground_modestring-start_modeと同じ接地位置の基準。"absolute"ではgroundYをcanvas上の固定位置として扱い、"relative"では上位階層の変換に追従します
align_tostring-"bottom"接地させる位置。"bottom" / "bounds_bottom"はink boundsの下端、"baseline"は文字の横組みベースライン、"center"はink boundsの中心です。ベースラインを持たないパーツで"baseline"を指定すると下端へフォールバックします
gravitynumbercanvas正規化変位/秒²4.0地面へ向かう加速度の大きさ
restitutionnumber-0.45反発係数
start_velocitynumbercanvas正規化変位/秒0.0Y軸方向の初速
squashnumber係数0.15衝突速度に応じて接触軸を潰す強さ
stretchnumber係数0.02移動速度に応じて進行軸を伸ばす強さ
flexibilitynumberradian/秒16.0衝突後に元の形へ戻る振動の速さ
dampingnumber1/秒7.0衝突後の振動が収束する速さ

ground_mode = "absolute"では、回転・スケール適用後のcanvas上の外接矩形を使って接地位置を 求めます。

使用例 ​

lua
-- 画面共通の一定の高さ (0.85) から全文字を垂直落下させて BB 端で接地
mt.bounce_ground(ctx, ctx.chars[i], 0.1, { start_mode = "absolute", start_y = 0.85, align_to = "bottom" })

-- 文字ごとの高さから一定距離 (0.3) 浮かせた位置から落とし、ベースラインに整列
mt.bounce_ground(ctx, ctx.chars[i], 0.1, { start_mode = "relative", drop_height = 0.3, align_to = "baseline" })

-- global.rotation が入っていても、画面の 0.85 から落として画面の 0.1 に正確に接地
mt.bounce_ground(ctx, ctx.chars[i], 0.1, {
    start_mode = "absolute", start_y = 0.85,
    ground_mode = "absolute", align_to = "bottom"
})

NOTE

"absolute" 指定時は、指定 Canvas 位置へ正確に配置するために offset_x と offset_y の 両方 が書き込まれます(回転が入ると2軸が連動するため、片方だけでは目標座標に到達できません)。バウンス軸以外のオフセットは「現在の画面位置を保つための補正」として働きます。


mt.bounce_wall(ctx, item, wallX, config?) ​

APIレベル: 3+

文字またはパーツ item を指定した壁 Canvas 座標 wallX(例: 0.9)に向かって衝突・バウンドさせる簡易便利関数です。offset_x, stretch_x, stretch_y が自動適用されます。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト
itemtable-指定必須変更する文字またはパーツ
wallXnumbercanvas正規化座標指定必須衝突先のX座標
configtable-nil開始位置、衝突基準、物理パラメータなどの設定

戻り値 ​

型単位内容
table-計算済みのバウンド状態

変更内容 ​

フィールド型単位内容
item.offset_xnumbercanvas正規化変位計算したX方向の変位を設定します
item.offset_ynumbercanvas正規化変位config.wall_mode = "absolute"の場合に、現在のcanvas上のY位置を保つ変位を設定します
item.stretch_x / item.stretch_ynumber倍率衝突時のSquash & Stretchを設定します

config ​

フィールド型単位省略時内容
tnumber秒ctx.time評価する時刻
delaynumber秒0.0動き始めるまでの待ち時間
start_modestring-start_x指定時は"absolute"、それ以外は"relative"開始位置の基準。"relative"では現在位置から壁と反対方向へtravel_distanceだけ離し、"absolute"ではstart_xを使用します
start_xnumbercanvas正規化位置nilstart_mode = "absolute"で使用する開始位置
travel_distancenumbercanvas正規化変位0.3start_mode = "relative"で現在位置から壁と反対方向へ離す距離
wall_modestring-start_modeと同じ衝突位置の基準。"absolute"ではwallXをcanvas上の固定位置として扱い、"relative"では上位階層の変換に追従します
align_tostring-進行方向から決定接触させる位置。左から接近する場合は"right"、右から接近する場合は"left"が既定です。"bounds_right"、"bounds_left"、"center"も指定できます
accel / accelerationnumbercanvas正規化変位/秒²4.0壁へ向かう加速度の大きさ。accelが優先されます
restitutionnumber-0.45反発係数
start_velocitynumbercanvas正規化変位/秒0.0X軸方向の初速
squashnumber係数0.15衝突速度に応じて接触軸を潰す強さ
stretchnumber係数0.02移動速度に応じて進行軸を伸ばす強さ
flexibilitynumberradian/秒16.0衝突後に元の形へ戻る振動の速さ
dampingnumber1/秒7.0衝突後の振動が収束する速さ

使用例 ​

lua
-- 画面共通の一定の位置 (0.1) から全パーツを発射して壁 (wallX = 0.9) にバウンド
mt.bounce_wall(ctx, ctx.parts[i], 0.9, { start_mode = "absolute", start_x = 0.1, delay = i * 0.05 })

-- パーツごとの位置から一定距離 (0.25) 引いた位置から発射
mt.bounce_wall(ctx, ctx.parts[i], 0.9, { start_mode = "relative", travel_distance = 0.25 })

mt.impact_squash(config) ​

APIレベル: 3+

衝突の瞬間に潰れて弾む Squash & Stretch のインパルスを計算します。sin(ωt) * exp(-γt) の減衰振動で、衝突直後に最も潰れ、揺れながら元の形へ戻ります。

mt.bounce_* は Squash & Stretch を内部で適用済みなので、この関数は自前のタイミングで衝突を表現したいときに使います(他の文字にぶつかる、地面以外に当たる、など)。

引数 ​

引数型単位省略時内容
configtable-指定必須衝突時刻と変形特性の設定

config ​

フィールド型単位省略時内容
tnumber秒0.0現在時刻。impact_time未満では無変形の値を返します
impact_timenumber秒0.0衝突時刻。mt.bounce_*のlast_impact_timeを渡せます
squashnumber比率0.15潰れ量の最大値。0.2なら最も潰れた瞬間に高さが80%になります
stiffnessnumberradian/秒25.0元の形へ戻る速さ
dampingnumber1/秒12.0振動が収束する速さ

戻り値(多値) ​

型単位内容
number倍率stretchX。X方向の伸縮率
number倍率stretchY。Y方向の伸縮率。stretchXとは体積を保つよう逆数の関係になります
numberbounds_heightに対する比率offsetCorrection。潰れて縮んだ分だけ接地位置がずれるのを補正する値です。bounds_heightに掛けてoffset_yへ加算します

squash の名前と意味は mt.bounce_* の squash と共通です。

使用例 ​

lua
-- 衝突時刻を自分で決めて潰れを適用する
local sx, sy, correction = mt.impact_squash({
    t = ctx.time,
    impact_time = landTime,
    squash = 0.2,
})
character.stretch_x = sx
character.stretch_y = sy
character.offset_y = character.offset_y + correction * character.geometry.bounds_height

TIP

衝突速度に応じて潰れ具合を変えたい場合は、squash 自体を計算してください。 速度を直接渡す引数は用意していません。速度を素直に掛ける方式では、速度が少し大きいだけで 潰れ量が下限に張り付き、それ以上速くしても絵が変わらなくなるためです。下記のように 「どの速度で最大まで潰れるか」を明示するほうが、意図した範囲に収まります。

lua
local squashAmount = 0.3 * mt.saturate(impactSpeed / kFullSquashSpeed)
local sx, sy, correction = mt.impact_squash({ t = ctx.time, impact_time = landTime, squash = squashAmount })

mt.projectile_2d(config) / mt.projectile_2d(t, speed, angle, gravity?, spin?, drag?) ​

APIレベル: 3+

初速と重力による2次元の弾道飛行・放物線運動(打ち上げ、落下、破片の飛び散り)を計算します。mt.bounce_y / mt.bounce_x が「面にぶつかって跳ねる」動きなのに対し、こちらは着地しない「投げ出される」動き(破片の飛散、爆発、放り投げ)向けです。

引数 ​

引数型単位省略時内容
configtable-指定必須発射からの経過時間、初速、方向、重力などの設定

config ​

フィールド型単位省略時内容
tnumber秒0.0発射からの経過時間。負値は0として扱います
speednumbercanvas正規化変位/秒0.0初速
anglenumber度0.0発射方向。0は右で、正方向は時計回りです。-90で真上になります
gravitynumbercanvas正規化変位/秒²4.0下向きの加速度
spinnumber度/秒0.0角速度。戻り値のrotationを同名フィールドへそのまま渡せます
dragnumber1/秒0.0空気抵抗の指数減衰率。0では減衰しません
start_x / start_ynumbercanvas正規化位置0.0発射位置。省略時は原点からの相対変位を返します

引数並び形式 ​

引数型単位省略時内容
tnumber秒0.0発射からの経過時間。負値は0として扱います
speednumbercanvas正規化変位/秒0.0初速
anglenumber度0.0発射方向
gravitynumbercanvas正規化変位/秒²4.0下向きの加速度
spinnumber度/秒0.0角速度
dragnumber1/秒0.0空気抵抗の指数減衰率

引数並び形式では発射位置を指定できないため、原点からの相対変位を返します。

戻り値(いずれか) ​

型単位内容
table-テーブル形式では、x、y、rotation、velocity_x、velocity_yを持つ結果を返します。同じ値を[1]〜[5]でも取得できます
複数のnumber各値に準拠引数並び形式では、x、y、rotation、velocity_x、velocity_yを同じ順に返します

IMPORTANT

角度は画面基準(時計回り)ですが、戻り値の y は Canvas 基準(上が正)です。angle = -90(真上へ発射)とすると y は増加し、重力で減少へ転じます。offset_y にそのまま加算できます。

使用例 ​

lua
-- 破片を扇状に飛ばし、回転させながら落下させる
local angle = mt.random_range(seed, index, -140.0, -40.0, "angle")
local speed = mt.random_range(seed, index, 0.6, 1.2, "speed")
local flight = mt.projectile_2d({
    t = ctx.time - burstTime,
    speed = speed,
    angle = angle,
    gravity = 3.0,
    spin = mt.random_range(seed, index, -360.0, 360.0, "spin"),
})
part.offset_x = 0.5 + flight.x
part.offset_y = 0.5 + flight.y
part.rotation = flight.rotation

放物線を読み取れる状態に保つ ​

戻り値の x / y は常に正しい放物線です。飛び方がおかしく見えるとき、原因が 軌道側にあることはまれで、たいていはその上に重ねた処理です。

  • pivot_* は触らない。 0.5 のままにします。飛行変位を pivot にも加算すると、 破片は弧をたどらず離れた点を中心に円運動します。「ピボットの基準点」を参照してください。
  • 回転量に上限を設ける。 spin は軌道を曲げませんが、毎秒何回転もする破片は その場で転がっているように見え、弧が読み取れなくなります。3D の yaw / pitch は、 経過時間に掛けて無制限に累積させるのではなく、総回転角を指定して姿勢を 落ち着かせる形を推奨します。
  • 真の放射方向だけではほとんど弧を描かない。 一行のテキストでは外向き方向が ほぼ水平なので、落ちてくるための高さが生まれません。方向を真上(-90)へ ブレンドして、破片に十分な浮きを与えてください。

mt.friction_decay(t, speed, friction) ​

APIレベル: 3+

摩擦による指数関数的減速(慣性スライド、ブレーキ、停止アニメーション)を計算します。「勢いよく入ってスーッと止まる」動きを、到達時間ではなく初速と摩擦係数という物理量で制御できます。

引数 ​

引数型単位省略時内容
tnumber秒指定必須経過時間。負値は0として扱います
speednumbercanvas正規化変位/秒指定必須初速
frictionnumber1/秒0.0減衰率。大きいほど早く止まります

戻り値(多値) ​

型単位内容
numbercanvas正規化変位distance。それまでに進んだ距離
numbercanvas正規化変位/秒currentSpeed。その時点での速度

最終的な移動距離は speed / friction に収束します。逆にいえば、止まってほしい距離が決まっているなら speed = distance * friction と置けます。

mt.ease.out_expo との使い分け: イージングは「決まった時間で 0→1 を進む」進行度なのに対し、こちらは初速と摩擦が独立した物理量なので、初速だけを変えて減速の質感は揃えるといった調整ができます。

使用例 ​

lua
-- 左から滑り込んで摩擦で止まる
local travelled = mt.friction_decay(ctx.time - startTime, 2.0, 4.0)
character.offset_x = 0.5 - 0.5 + travelled

NOTE

friction が極めて小さい(1e-4 以下)場合は等速直線運動として扱います。数式上の桁落ちを避けるためで、実用上は摩擦なしと同じ挙動です。

9. 色 ​

color の形式は概念編の「color」を参照してください。 RGBAはcolorの格納形式です。色を計算する場合は、用途に合う色空間を選択してください。

mt.color.resolve_fill(ctx, target, options?) ​

APIレベル: 6+

文字またはパートに適用される塗りを解決し、基本色、塗りモード、オブジェクト不透明度を 返します。OnLayoutとOnPathで使用できます。optionsなしでは対象が描画される最終的な塗りを返し、 options.levelで継承を途中の段階までに止められます(スタイルの継承を参照)。

引数 ​

引数型単位省略時内容
ctxtable-指定必須現在のOnLayout / OnPath context
targetcharacter | part-指定必須ctx.charsまたはctx.partsの要素
optionstable-nil(12+) { level = "global" | "character" | "part" }

戻り値 ​

値型単位内容
colorcolor-継承解決後の単色、またはGlobalグラデーション/Crayonの始端となるctx.global.fill.colorのコピー
modestring-"solid" / "gradient" / "crayon" / "transparent"
opacitynumber0-1Global、所有文字、対象パートのopacityを乗算し、0-1へクランプした値

パートではpart.fill.use、所有文字のfill.use、Globalの順に解決します。文字では文字と Globalだけを解決し、その文字に属するパートの個別色は調べません。個別色が選ばれた場合、 modeは常に"solid"です。

Globalまで継承した場合、fill.transparentがtrueなら"transparent"、 gradient.color_spaceが"none"なら"solid"、"crayon"なら"crayon"、 それ以外のグラデーションモードなら"gradient"を返します。

opacityにはcolor自身のaは乗算されません。返されるcolorは新しいテーブルなので、 変更しても元のfill.colorには影響しません。

lua
for _, part in mt.each_part(ctx) do
    local color, mode, opacity = mt.color.resolve_fill(ctx, part)
    if mode == "gradient" and opacity > 0.0 then
        -- このパートはGlobalグラデーションで塗られる
        print(color.r, ctx.global.gradient.end_color.r)
    end
end

Colorの生成・分解・補間 ​

以下の関数は新しいtableを返し、引数を変更しません。from_*は成分からcolorを作り、 to_*はcolorを成分tableへ分解し、lerp*は2色とtからcolorを作ります。 省略可能なalphaと、to_*へ渡したcolorに存在しないaは1.0になります。 hueは一周を1とする値で、範囲外の入力は[0, 1)へ周回します。すべての補間関数で tはクランプされません。OKHSV/OKHSLのsaturation、value、lightness入力は 0-1へ制限されます。lerp_oklch/lerp_okhsv/lerp_okhslは既定で最短の色相経路を通り、 無彩色端では有彩色端の色相を使います。正確に半周なら元の色相差の符号を維持します。 lerp_oklch(from, to, t, "long")で長い色相経路を選べます。 "short"または省略時は短い経路です。"long"で両端の色相が同じ場合は増加方向へ一周します。 無彩色端が有彩色端の色相を引き継いだ場合も同様です。それ以外のhueMethodはエラーになります。

APIレベル: 1+

  • mt.color.lerp(from, to, t) - RGBA成分を線形補間します。
  • mt.color.from_hsv(hue, saturation, value, alpha?) - 正規化HSVからcolorを作ります。
  • mt.color.with_alpha(color, alpha) - RGBを保ち、alphaだけを置き換えます。
  • mt.color.from_oklch(lightness, chroma, hue, alpha?) - OKLCHからcolorを作ります。chromaは通常0-0.4程度で、RGB出力は0-1へ制限されます。

APIレベル: 8+

  • mt.color.from_oklab(lightness, aAxis, bAxis, alpha?) - OKLab成分からRGBA colorを作ります。RGB出力は0-1へ制限されます。
  • mt.color.to_oklab(color) - { lightness, a, b, alpha }へ変換します。入力RGBは制限しません。
  • mt.color.to_oklch(color) - { lightness, chroma, hue, alpha }へ変換します。無彩色のhueは0です。
  • mt.color.from_okhsv(hue, saturation, value, alpha?) - sRGB gamutに正規化されたOKHSVからcolorを作ります。
  • mt.color.to_okhsv(color) - { hue, saturation, value, alpha }へ変換します。無彩色のhueは0です。
  • mt.color.from_okhsl(hue, saturation, lightness, alpha?) - sRGB gamutに正規化されたOKHSLからcolorを作ります。
  • mt.color.to_okhsl(color) - { hue, saturation, lightness, alpha }へ変換します。無彩色のhueは0です。
  • mt.color.lerp_oklab(from, to, t) - OKLabの直交座標で補間します。
  • mt.color.lerp_oklch(from, to, t, hueMethod?) - OKLCHで補間します。hueMethodは"short"(既定)または"long"です。
  • mt.color.lerp_okhsv(from, to, t) - OKHSVで最短の色相経路に沿って補間します。
  • mt.color.lerp_okhsl(from, to, t) - OKHSLで最短の色相経路に沿って補間します。

10. スタイルの継承 ​

塗り・ストローク・シャドウ・ぼかし・テクスチャは、ctx.global、所属する文字、パートの3段階で継承されます。 要素の use フラグは継承するグループ全体を置き換えるため、shadow.use はシャドウの色とぼかしをまとめて切り替えます。 resolve関数は、要素が描画に使うグループを返します。 mt.color.resolve_fill、mt.shadow.resolve、mt.blur.resolve、mt.stroke.resolve、mt.texture.resolve です。

options なしでは対象の最終値を返します。パートでは自身の上書きを含み、文字ではその文字に属するパートの上書きを含みません。 options.level で継承を途中の段階までに止められます。

level返す値
"global"フレームの値(ctx.global)
"character"所属する文字の上書きまでを反映した値
"part"パートの上書きまでを反映した値(パートの既定)

文字の既定は "character" で、対象自身の段階より下の level はエラーです。上書きしたグループの1項目だけを変えるには、 level で上位の段階を読み、use を設定して値を書き戻します。

lua
function OnLayout(ctx)
    for _, part in mt.each_part(ctx) do
        local shadow = mt.shadow.resolve(ctx, part, { level = "character" })
        -- このパートのシャドウだけぼかしを足し、色は継承した値のままにする。
        part.shadow.use = true
        part.shadow.color = shadow.color
        part.shadow.blur_x = shadow.blur_x + 0.2
        part.shadow.blur_y = shadow.blur_y + 0.2
    end
end

NOTE

shadow.use = true のパートは、個別のシャドウ色と同じく、全体のシャドウがOFFでもシャドウを落とします。

どれも OnLayout と OnPath で使え、返される色は新しいテーブルなので、変更しても元の設定には影響しません。

すべてのresolve関数の引数:

引数型単位既定値説明
ctxtable-必須現在のOnLayoutまたはOnPathのコンテキスト
targetcharacter | part-必須ctx.chars または ctx.parts の要素
optionstable-nil{ level = "global" | "character" | "part" }

APIレベル: 12+

mt.shadow.resolve(ctx, target, options?) ​

シャドウを解決します。{ color, blur_x, blur_y, glow }(シャドウ色、水平・垂直のぼかし(em)、グローの強さ)を返します。

mt.blur.resolve(ctx, target, options?) ​

文字本体のぼかしを解決します。{ amount_x, amount_y, glow }(ぼかし(em)とグローの強さ)を返します。

mt.stroke.resolve(ctx, target, options?) ​

ストロークを解決します。{ width, gap, color, outer_width, outer_color } を返します。order・join・miter_limit は ctx.global.stroke にだけ存在します。

mt.texture.resolve(ctx, target, options?) ​

テクスチャを解決します。{ type, p1, p2, p3, p4, color } を返します。

11. イージング ​

APIレベル: 1+

mt.ease.<name>(t) は進行度 t(通常0-1)を受け取り、緩急のついた進行度を返します。 mt.stagger や mt.cycle が返す直線的な進行度に表情を付けるのが典型的な使い方です。 mt.ease.cubic_bezierを除き、入力tは自動でクランプされません。0-1に制限する場合は、 mt.saturateを通してから渡してください。

名前は「カーブの種類」と「向き」の組み合わせです。

  • in_ - 加速(ゆっくり始まり、速く終わる)。退場向き
  • out_ - 減速(速く始まり、ゆっくり止まる)。登場向き
  • in_out_ - 前半加速・後半減速
カーブ使いどころ
Linear等速(変化なし)
Quad最も緩やかな加減速
Cubic標準的な加減速。迷ったらまずこれ
QuartCubicより急峻
Sineサイン波由来のごく緩やかな緩急
Circ端で急激に立ち上がる円弧カーブ
Expo指数的な非常に強い緩急
Back一度行き過ぎてから戻る(0-1の外へはみ出す)
Elasticバネのように振動しながら収まる(0-1の外へはみ出す)
Bounce床で弾むようなバウンド

BackとElasticは戻り値が0-1の範囲を超えることがある点に注意してください(それがはみ出し表現の 本体です)。

以下の関数はmt.ease.cubic_bezierを除き、すべて引数t(number、進行度、クランプなし)を1つ取りnumberを返します。cubic_bezierのシグネチャは表に併記しています。

関数特性戻り値
mt.ease.linear(t)入力した進行度をそのまま返す、等速のイージングです。入力したtと同じ値
mt.ease.in_quad(t)ゆっくり始まり、徐々に加速する2次関数のイージングです。t²で計算した進行度
mt.ease.out_quad(t)速く始まり、徐々に減速する2次関数のイージングです。1 - (1 - t)²で計算した進行度
mt.ease.in_out_quad(t)前半で加速し、後半で減速する2次関数のイージングです。t = 0.5を中心にin_quadとout_quadを対称に組み合わせた進行度
mt.ease.in_cubic(t)ゆっくり始まり、徐々に加速する3次関数のイージングです。t³で計算した進行度
mt.ease.out_cubic(t)速く始まり、徐々に減速する3次関数のイージングです。1 - (1 - t)³で計算した進行度
mt.ease.in_out_cubic(t)前半で加速し、後半で減速する3次関数のイージングです。t = 0.5を中心にin_cubicとout_cubicを対称に組み合わせた進行度
mt.ease.in_quart(t)ゆっくり始まり、Cubicより急峻に加速する4次関数のイージングです。t⁴で計算した進行度
mt.ease.out_quart(t)速く始まり、Cubicより急峻に減速する4次関数のイージングです。1 - (1 - t)⁴で計算した進行度
mt.ease.in_out_quart(t)前半で加速し、後半で減速する4次関数のイージングです。t = 0.5を中心にin_quartとout_quartを対称に組み合わせた進行度
mt.ease.in_sine(t)サイン波由来の、ごく緩やかに加速するイージングです。1 - cos(t × π / 2)で計算した進行度
mt.ease.out_sine(t)サイン波由来の、ごく緩やかに減速するイージングです。sin(t × π / 2)で計算した進行度
mt.ease.in_out_sine(t)サイン波由来の、前半で加速し後半で減速するイージングです。t = 0.5を中心にin_sineとout_sineを対称に組み合わせた進行度
mt.ease.in_circ(t)円弧を使い、終端へ向かって急激に加速するイージングです。1 - √(1 - t²)で計算した進行度
mt.ease.out_circ(t)円弧を使い、開始直後に急激に進んでから減速するイージングです。√(1 - (1 - t)²)で計算した進行度
mt.ease.in_out_circ(t)円弧を使い、前半で加速し後半で減速するイージングです。t = 0.5を中心にin_circとout_circを対称に組み合わせた進行度
mt.ease.in_expo(t)指数関数を使い、終端へ向かって非常に強く加速するイージングです。t <= 0では0、それ以外では2^(10t - 10)で計算した進行度
mt.ease.out_expo(t)指数関数を使い、開始直後に非常に強く進んでから減速するイージングです。t >= 1では1、それ以外では1 - 2^(-10t)で計算した進行度
mt.ease.in_out_expo(t)指数関数を使い、前半で非常に強く加速し、後半で非常に強く減速するイージングです。t = 0.5を中心にin_expoとout_expoを対称に組み合わせた進行度
mt.ease.in_back(t)開始直後に負方向へ少し戻ってから、終端へ加速するイージングです。開始付近で0未満へ行き過ぎる進行度
mt.ease.out_back(t)終端を少し越えてから戻りながら減速するイージングです。終端付近で1を超えて行き過ぎる進行度
mt.ease.in_out_back(t)開始付近と終端付近の両方で行き過ぎるイージングです。t = 0.5を中心にin_backとout_backを対称に組み合わせた進行度
mt.ease.in_elastic(t)振動しながら振幅を広げ、終端へ加速するイージングです。0-1の範囲外へ振動する進行度。t <= 0とt >= 1ではtをそのまま返します
mt.ease.out_elastic(t)終端の周囲を振動しながら減速して収束するイージングです。0-1の範囲外へ振動する進行度。t <= 0とt >= 1ではtをそのまま返します
mt.ease.in_out_elastic(t)前半で振動しながら加速し、後半で振動しながら減速して収束するイージングです。t = 0.5を中心にin_elasticとout_elasticを対称に組み合わせた進行度
mt.ease.in_bounce(t)開始側で弾んでから終端へ向かうイージングです。out_bounceを時間反転した進行度
mt.ease.out_bounce(t)床で複数回弾むように減速して終端へ到達するイージングです。区間ごとの2次関数でバウンドを表現した進行度
mt.ease.in_out_bounce(t)開始側と終端側の両方で弾むイージングです。t = 0.5を中心にin_bounceとout_bounceを対称に組み合わせた進行度
mt.ease.cubic_bezier(x1, y1, x2, y2, t)CSSのcubic-bezier() timing-functionと互換の3次Bézierカーブを評価します。 上記の定義済みカーブで足りないときに、任意の緩急を数値で指定できます。指定したBézierカーブ上の進行度

circ系の3関数は平方根を含むため、通常はtを0-1に制限して使用します。

mt.ease.cubic_bezierの引数 ​

引数型単位省略時内容
x1 / y1number-指定必須第1制御点
x2 / y2number-指定必須第2制御点
tnumber-指定必須進行度。t <= 0では0、t >= 1では1へ固定されます

CSS互換の単調な時間曲線として使用する場合は、x1とx2を0-1にします。

使用例 ​

lua
-- CSSの ease-in-out と同じカーブ
local eased = mt.ease.cubic_bezier(0.42, 0.0, 0.58, 1.0, progress)

12. 再組版・行単位のグループ化 ​

mt.layout.reflow(ctx, gap?, config?) ​

APIレベル: 2+

横書きではgeometry.canvas_origin_*、縦書きでは geometry.vertical_origin_*を使い、隣接する自然原点の差からシェーピング・kerning・tracking・ margins由来の間隔を保持したまま、現在のscale * stretchを送りへ反映します。個別rotationと pivotも原点整列へ含まれます。可視インク輪郭間の距離を均一化する関数ではありません。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト
gapnumbercanvas幅比または高さ比0.0隣接する送りへ追加する余白。正値は進行方向の間隔を広げます
configtable-nil再組版する方向・対象・固定位置の設定

config ​

フィールド型単位省略時内容
modestring-ctx.global.verticalから決定再組版する方向。"horizontal"または"vertical"
targetstable-全文字再組版する1始まりの文字index配列。対象間に飛ばした文字があれば、その文字の送りは計算へ含みますが座標は変更しません
anchorinteger-各行/列の先頭文字現在の変形済み組版原点を固定し、その両側を並べる文字index

targetsを省略すると、各line_indexを独立した行/列として全文字を再組版し、それぞれの 先頭文字を固定します。config.anchorを指定した場合は、その所属行だけ指定文字を固定します。

戻り値 ​

戻り値はありません。

変更内容 ​

対象文字のoffset_xとoffset_yを書き換えます。サイズ・回転・pivotのアニメーションを 設定した後、そのフレームの最終レイアウト処理として呼び出してください。

制約・エラー ​

  • modeには"horizontal"または"vertical"を指定します。
  • targetsのindexは有効範囲内で厳密な昇順に並べ、重複させないでください。
  • targetsに含める文字はすべて同じline_indexに属する必要があります。
  • targetsを指定した場合、anchorはその配列に含まれる文字を指定します。
  • targetsを省略した場合、anchorは有効な文字indexを指定します。

使用例 ​

lua
mt.layout.reflow(ctx, 0.02, {
    targets = {3, 4, 7, 8}, -- 5, 6は送りへ含むが移動しない
    anchor = 3,
})

mt.layout.group_by_line(ctx) ​

APIレベル: 4+

シェーピング済み文字をline_indexごとにグループ化し、ホストの読み順で返します。 横書きでは行、縦書きでは列を表します。レイアウトや文字プロパティは変更しません。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト

戻り値 ​

型単位内容
table-line_indexごとのグループを組版上の行/列順に格納した配列

各グループは次のフィールドを持ちます。

フィールド型単位内容
line_indexinteger-グループに対応する行/列のindex
item_countinteger個グループ内の文字数
itemstable-読み順に並んだ文字の配列

使用例 ​

lua
local columns = mt.layout.group_by_line(ctx)
for columnOrder, column in ipairs(columns) do
    for indexInColumn, character in ipairs(column.items) do
        local start = (columnOrder - 1) * 0.2 + (indexInColumn - 1) * 0.05
        character.opacity = mt.saturate((ctx.time - start) / 0.4)
    end
end

13. Canvas上の位置・距離・支点 ​

mt.layout.place_2d(ctx, item, canvasX, canvasY) ​

APIレベル: 2+

文字またはパーツのアンカーを、3D・camera・projection・Deform適用前のcanvas正規化位置へ 正確に配置します。global、所有文字、対象自身のoffset / pivot / rotation / scale / stretchを、Native描画と同じ階層・同じ非正方形canvasの画素座標で合成して逆算します。

  • 文字アンカー: 自然インク境界中心geometry.bounds_center_x/y
  • パーツアンカー: パーツローカル自然中心(描画パスのローカル原点)
  • 図形アンカー: 図形の位置(パスの原点。offsetしなければcanvas中心)。Globalは図形に届かないので、図形自身のoffset / pivot / rotation / scale / stretchだけが関わります

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト
itemtable-指定必須対象の文字またはパーツ
canvasX / canvasYnumbercanvas正規化位置指定必須配置先の座標

戻り値(多値) ​

型単位内容
numbercanvas正規化変位設定したoffsetX
numbercanvas正規化変位設定したoffsetY

変更内容 ​

対象のoffset_xとoffset_yを直接更新します。

制約・エラー ​

変換階層内のscale * stretchが0の場合は逆変換できないため、エラーになります。

使用例 ​

lua
mt.layout.place_2d(ctx, ctx.chars[1], 0.8, 0.8)
mt.layout.place_2d(ctx, ctx.parts[1], 0.5, 0.5)

mt.layout.get_canvas_position_2d(ctx, item) ​

APIレベル: 3+

文字またはパーツのアンカーの、現在の 3D 変換前の Canvas 座標 (canvasX, canvasY)(0.0〜1.0 の正規化 Y-up 座標系)を取得します。引数 item に文字(ctx.chars[i])またはパーツ(ctx.parts[j])のいずれを渡しても自動的に判定されます。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト
itemtable-指定必須対象の文字またはパーツ

戻り値(多値) ​

型単位内容
numbercanvas正規化位置アンカーのcanvasX
numbercanvas正規化位置アンカーのcanvasY

使用例 ​

lua
-- 文字(Character)の Canvas 位置を取得
local charX, charY = mt.layout.get_canvas_position_2d(ctx, ctx.chars[1])

-- パーツ(Part)の Canvas 位置を取得(自動判定)
local partX, partY = mt.layout.get_canvas_position_2d(ctx, ctx.parts[1])

mt.layout.match_pose(ctx, destination, source, options?) ​

APIレベル: 9+

sourceの現在の姿勢を同じ種類のdestinationへ同期します。Character同士、または同じCharacterが 所有するPart同士に使用できます。OnLayout専用です。適用順はsize、rotation、depth、opacity、positionです。

option型既定値内容
positionbooleantrue3D適用前のcanvas位置を同期
position_delta_x / position_delta_ynumber0.0sourceローカルX/Y軸に沿う変形前em単位の変位
rotationbooleantrue2D回転を同期
rotation_offsetnumber0.0同期後の回転へ加える度数
sizestring"copy""none" / "copy" / "match_bounds"
size_scale_x / size_scale_ynumber1.0同期後の各軸倍率。正数のみ
depthbooleantruez / yaw / pitchを同期
z_offsetnumber0.0同期後のZへ加えるcanvas比変位
yaw_offset / pitch_offsetnumber0.0同期後に加える角度(度)
opacitybooleanfalseopacityを同期
opacity_scalenumber1.0同期後のopacity倍率。0以上

match_boundsは自然boundsの幅・高さの比をstretchへ反映します。sourceのink boundsが0の軸では 論理文字セルを使います。横書きのXは水平送り、縦書きのYは垂直送りを優先し、送りも0の場合と 交差軸は1emです。Partは送りを持たないため1emを使います。destinationのboundsが0の軸では その軸の実効scaleを維持し、他の軸と姿勢の同期を継続します。destinationのpivotは変更しません。

position deltaのX/Yはどちらも変形前の1emを1.0とし、画面固定のX/Y方向ではありません。CharacterではGlobalとsource Character、Partでは Global、所有Character、source Partのrotation・scale・stretchを通してから同期位置へ加えます。 したがってsourceを回転・拡縮するとdeltaの方向と長さも追従します。rotation_offsetとsize_scaleは destination側の補正なのでdelta変換には含まれません。

lua
mt.layout.match_pose(ctx, ctx.chars[4], ctx.chars[1], {
    size = "match_bounds",
    size_scale_x = 1.15,
    size_scale_y = 1.2,
    position_delta_y = -0.75,
})

mt.layout.canvas_to_offset_2d(ctx, item, canvasX, canvasY) ​

APIレベル: 3+

文字またはパーツを指定した 3D 変換前の Canvas 座標 (canvasX, canvasY) に配置するために必要な offset_x, offset_y を計算して返却します(プロパティ自体の書き換えは行いません)。引数 item に文字またはパーツを渡すことで自動判定されます。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト
itemtable-指定必須対象の文字またはパーツ
canvasX / canvasYnumbercanvas正規化位置指定必須配置先の座標

戻り値(多値) ​

型単位内容
numbercanvas正規化変位必要なoffsetX
numbercanvas正規化変位必要なoffsetY

対象のフィールドは変更しません。

制約・エラー ​

逆変換する親階層のscale * stretchが0の場合はエラーになります。

使用例 ​

lua
-- 文字を Target Canvas 座標 (0.5, 0.8) に配置するための offset を逆算
local cox, coy = mt.layout.canvas_to_offset_2d(ctx, ctx.chars[1], 0.5, 0.8)

-- パーツを Target Canvas 座標 (0.2, 0.3) に配置するための offset を逆算(自動判定)
local pox, poy = mt.layout.canvas_to_offset_2d(ctx, ctx.parts[1], 0.2, 0.3)

mt.layout.radial_distance(ctx, canvasX, canvasY, centerX?, centerY?) ​

APIレベル: 3+

放射状エフェクトの中心から、指定した Canvas 座標までの距離を返します。centerX / centerY を省略した場合は画面中央 (0.5, 0.5) が中心になります。

引数 ​

引数型単位省略時内容
ctxtable-指定必須canvas情報を持つコンテキスト
canvasX / canvasYnumbercanvas正規化位置指定必須距離を測る座標
centerX / centerYnumbercanvas正規化位置0.5効果の中心

戻り値 ​

型単位内容
numbercanvas高さ比アスペクト比を補正した中心からの距離

IMPORTANT

アスペクト比が補正されます。 Canvas の正規化座標は縦横で 1.0 の実寸が異なるため、単純に sqrt(dx² + dy²) で距離を求めると、16:9 のような横長プロジェクトでは同心円のつもりが楕円に潰れます。この関数は横方向を ctx.canvas.aspect_ratio 倍して補正するので、返る距離は常に真円基準です。

使用例 ​

lua
-- 中心から広がる波紋。文字ごとの距離に応じて峰が通過する
for index = 1, ctx.char_count do
    local character = ctx.chars[index]
    local geometry = character.geometry
    local radius = mt.layout.radial_distance(ctx, geometry.bounds_center_x, geometry.bounds_center_y)
    local crest = mt.falloff(radius - waveFront, 0.2)
    character.offset_y = character.offset_y + crest * 0.08
end

mt.layout.pivot_at_2d(ctx, item, anchor) ​

APIレベル: 4+

文字またはパーツを自動判定し、意味的な2D位置へpivotを設定します。変更前後のローカル2D行列差を offset_x/yへ補正するため、現在のrotation、scale、stretchによる3D適用前の姿勢は移動しません。 Globalは対象外です。yaw、pitch、z、カメラ、投影後の見た目は維持対象に含みません。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト
itemtable-指定必須対象の文字またはパーツ
anchorstring-指定必須設定する意味的な2D位置名

戻り値 ​

戻り値はありません。

変更内容 ​

対象のpivot_xとpivot_yを設定し、姿勢が移動しないようoffset_xとoffset_yを補正します。

anchor ​

文字とパーツに共通するanchorは次のとおりです。

  • "center": ink boundsの中心
  • "top" / "bottom": ink boundsの水平中央と上端/下端の交点
  • "left" / "right": ink boundsの左端/右端と垂直中央の交点
  • "top_left" / "top_right" / "bottom_left" / "bottom_right": ink boundsの各角

文字ではさらに次のanchorを指定できます。

  • "baseline_left" / "baseline" / "baseline_right": ink boundsの左端/中央/右端と横組みベースラインの交点
  • "typesetting_origin": 文字セル左端と横組みベースラインの交点
  • "vertical_start" / "vertical_center" / "vertical_end": 縦組みの列中心軸と文字セルの始端/中央/終端の交点

既存のpivot値はbounds内の0〜1比率ではありません。0.5を自然中心とし、Xはcanvas幅比、 Yはcanvas高さ比の変位です。この関数がbounds寸法、文字の組版原点、文字/パーツで異なる 自然中心を既存pivot単位へ変換します。

使用例 ​

lua
mt.layout.pivot_at_2d(ctx, character, "top")
character.rotation = math.sin(ctx.time * 3.0) * 8.0

14. 2D変換後の境界 ​

mt.layout.measure_bounds_2d(ctx, targets?, targetType?, space?) ​

space(level 12+)は既定"canvas"。"before_global_rotation"はGlobalの位置+ピボットを中心とする回転だけを除いて計測します。scale・stretch・個別変形・組版は保持し、結果はCanvas正規化Y-up座標です。この空間で描いた装飾には、同じ中心のGlobal回転を再適用します。ctxやInspectorの値は変更しません。

APIレベル: 2+

指定対象の自然境界矩形をglobal→文字→パーツの完全な2D階層で変換し、その全頂点を囲む canvas軸平行境界を返します。文字を指定した場合は所有パーツの自然境界を合成し、パーツを持たない 文字は文字の自然境界を使います。対象フィールドを書いた後に呼び出してください。

この境界は3D・camera・projection・Deform適用前です。strokeとshadowの張り出し、および 自然境界矩形内に余白を持つ輪郭のpath-tight境界は含みません。この段階と定義に対しては近似ではなく、 rotation・pivot・負のstretch・親文字変形・global変形をすべて反映します。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト
targetstable | nil-全件1始まりの文字またはパーツindex配列。nilなら対象種別の全要素
targetTypestring-"character"対象の種類。"character"または"part"
spacestring-"canvas""canvas"または"before_global_rotation"

戻り値(いずれか) ​

型単位内容
table-有効な対象全体を囲む境界
nil-有効な対象がない場合

境界tableは次のフィールドを持ちます。座標系はすべてY-upです。

フィールド型単位内容
left / rightnumbercanvas正規化位置左端と右端
bottom / topnumbercanvas正規化位置下端と上端
center_x / center_ynumbercanvas正規化位置境界の中心
width / heightnumbercanvas正規化変位境界の幅と高さ

制約・エラー ​

targetsを省略すると全件を指定できます。targetTypeが"character"なら 全文字、"part"なら全パートを対象にします。空table {} は全件指定ではなく、従来どおり 対象なしとしてnilを返します。

全件文字指定にはパートを持たない文字も含まれ、その文字の自然境界を使用します。全件パート 指定にはctx.partsに存在するパートだけが含まれます。不可視状態、opacity、write-onは 対象選択へ影響せず、指定対象の幾何境界を計測します。

使用例 ​

lua
local bounds = mt.layout.measure_bounds_2d(ctx, {1, 2, 3})
if bounds then
    mt.layout.place_2d(ctx, ctx.chars[4], bounds.center_x, bounds.top + 0.05)
end

local allCharacterBounds = mt.layout.measure_bounds_2d(ctx)
local allPartBounds = mt.layout.measure_bounds_2d(ctx, nil, "part")

15. パス上への整列 ​

mt.layout.queue_on_path(ctx, path, options?) ​

APIレベル: 3+

mt.path.arc_lengthで作ったパス上に、文字(またはパーツ)を読み順のまま並べ、各要素が 占める距離比(0-1)を返します。

間隔はホストが実際に組版した原点の間隔から求めます(mt.layout.reflowと同じ方式)。 そのためtracking・文字ごとのmargins・カーニングといったパラメータ設定が、そのまま パス上の字送りに反映されます。options.gapはそれに上乗せする追加間隔なので、gapが 0ならホストの字送りどおりに並びます。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutのコンテキスト
pathtable-指定必須mt.path.arc_lengthの戻り値
optionstable-nil配置方法の設定
options.alignstring-"end"文字列を置く位置。"end"、"start"、"center"を指定します
options.gapnumbercanvas幅比0.0ホストの字送りへ上乗せする追加間隔
options.modestring-"horizontal"ホストの組版方向。"horizontal"または"vertical"
options.target_typestring-"character"対象の種類。"character"または"part"
options.targetstable-全要素読み順に並べた対象index配列

戻り値 ​

型単位内容
table0-1ctx.charsまたはctx.partsと同じindexで、各要素が占めるパス上の距離比を取得できるslots配列

slotsはアニメーションの進行度ではなく、パス上の位置を表します。

進行方向と読み順 ​

スロットは進行方向に沿った距離の昇順で割り当てられます。基準は画面の左右ではなく パスの進行方向です。targetsを省略した場合はindexの昇順に割り当てるため、パスが 左から右へ進むならそのまま画面上の読み順になります。

IMPORTANT

右から左へ進むパスでは、距離の昇順が x の減少方向になります。 そのためtargetsを 省略すると文字1が最も右、文字Nが最も左に置かれ、画面上では文字列が逆転して見えます。 左から右に読める配置にしたい場合は、targetsを読み順の逆で渡してください。

lua
-- 右から左へ進むパスで、画面上の読み順を保つ
local targets = {}
for index = ctx.char_count, 1, -1 do
    targets[#targets + 1] = index
end
local slots = mt.layout.queue_on_path(ctx, path, { targets = targets })

これはトレードオフであり、逆向きパスでは次の2つを同時には満たせません。どちらを取るかは 用途によって選んでください。

targets画面上の並び隊列の先頭
省略(index昇順)逆転(右→左に読む)文字1
読み順の逆正しい(左→右に読む)最後の文字

alignも同様に進行方向基準です。"end"はパスの終端に文字列の末尾を置くため、 右から左へ進むパスでは末尾が画面の左側に来ます。

パスの向きalign = "end"で末尾が来る位置
左→右画面右側
右→左画面左側

使用例 ​

lua
-- 用途1: パスに沿ってテキストを並べる(静止)
local path = mt.path.arc_length(kPathPoints, ctx.canvas.aspect_ratio)
local slots = mt.layout.queue_on_path(ctx, path, { gap = 0.004 })
for index = 1, ctx.char_count do
    local x, y, heading = path:at_distance(slots[index])
    ctx.chars[index].rotation = heading
    mt.layout.place_2d(ctx, ctx.chars[index], x, y)
end
lua
-- 用途2: パスを走って自分のスロットで停止する(隊列がブレーキ)
local path = mt.path.arc_length(kPathPoints, ctx.canvas.aspect_ratio)
local slots = mt.layout.queue_on_path(ctx, path, { align = "end" })
local progress = mt.ease.out_cubic(mt.saturate(ctx.time / 3.2))
for index = 1, ctx.char_count do
    -- math.minが隊列の停止そのもの: 先頭は終端まで、後続は自分の位置で止まる
    local x, y, heading = path:at_distance(math.min(progress, slots[index]))
    ctx.chars[index].rotation = heading
    mt.layout.place_2d(ctx, ctx.chars[index], x, y)
end

NOTE

文字列の総長がパス全長を超える場合、距離比が0と1にクランプされ、文字同士が重なります。 長いテキストを短いパスに載せる場合は、path:length()で収まるか確認してください。

16. モーションパス ​

制御点に沿って「流れ込むように登場する」「弧を描いて着地する」といった動きを表現する 曲線評価APIです。

座標系は決め打ちされていません。点は単なる { x, y } テーブルで、呼び出し側が 渡した座標系(offsetの正規化座標、canvas px、文字ローカル座標など)をそのまま受け取り、 同じ座標系の値を返します。

NOTE

戻り値を offset_x / offset_y に直接代入するときは、点も offset の単位 (中立値 0.5 のcanvas正規化変位)で置いてください。 下記の例は着地点を { x = 0.5, y = 0.5 }(変位ゼロ)にしているため、character.offset_x = x がそのまま 自然位置への着地になります。canvas 絶対座標や 0 始まりの局所座標を渡したまま offset に代入すると、意図しない位置に飛びます。

いずれの関数も戻り値は x, y, tangentX, tangentY の4つです。tangentX / tangentY は 正規化されていない生の微分値(進行速度も含む)で、進行方向の角度が欲しい場合は math.deg(math.atan(tangentY, tangentX))、単位ベクトルが欲しい場合は local length = math.sqrt(tangentX^2 + tangentY^2) で割ってください。

mt.path.bezier(p0, p1, p2, p3, t) ​

APIレベル: 1+

4点で定義される3次Bézier曲線上の座標と接線を返します。

引数 ​

引数型単位省略時内容
p0table座標指定必須始点{ x, y }
p1table座標指定必須始点側の制御点{ x, y }
p2table座標指定必須終点側の制御点{ x, y }
p3table座標指定必須終点{ x, y }
tnumber0-1指定必須曲線上の位置。範囲外はクランプされず、そのまま外挿されます

戻り値(多値) ​

型単位内容
number入力座標に準拠曲線上のx
number入力座標に準拠曲線上のy
number入力座標に準拠接線のtangentX
number入力座標に準拠接線のtangentY

使用例 ​

lua
-- 文字が弧を描いて自分の自然な位置へ着地する
local p0 = { x = 0.5, y = 0.2 }
local p1 = { x = 0.3, y = 0.6 }
local p2 = { x = 0.5, y = 0.5 }
local p3 = { x = 0.5, y = 0.5 }
local progress = mt.saturate(mt.stagger(ctx.time, index, 0.05, 0.6))
local x, y = mt.path.bezier(p0, p1, p2, p3, mt.ease.out_cubic(progress))
character.offset_x = x
character.offset_y = y

mt.path.catmull_rom(points, t) ​

APIレベル: 1+

任意個数の制御点を通るCatmull-Romスプライン上の座標と接線を返します。Bézierと違い、 リストに並べた点すべてを厳密に通過する曲線になります。

引数 ​

引数型単位省略時内容
pointstable座標指定必須1始まりの通過点配列。{ x, y }を2個以上並べます
tnumber0-1指定必須曲線全体を通した進行度。0-1にクランプされます

戻り値(多値) ​

型単位内容
number入力座標に準拠曲線上のx
number入力座標に準拠曲線上のy
number入力座標に準拠接線のtangentX
number入力座標に準拠接線のtangentY

制約・エラー ​

pointsには2個以上の点が必要です。

使用例 ​

lua
-- あらかじめ決めた3点を通る軌道に沿って文字を流し込む
local waypoints = {
    { x = 0.1, y = 0.8 },
    { x = 0.5, y = 0.3 },
    { x = 0.9, y = 0.8 },
}
local progress = mt.saturate(ctx.time / 1.5)
local x, y = mt.path.catmull_rom(waypoints, progress)
character.offset_x = x
character.offset_y = y

mt.path.arc_length(points, aspectRatio?, options?) ​

APIレベル: 3+

制御点から弧長パラメータ化されたパスを構築します。上記2関数は曲線パラメータtで 評価しますが、tの等間隔は距離の等間隔ではありません。曲線が曲がっている所ではサンプルが 詰まるため、「距離で間隔を取る」用途(隊列、パス上の字送り、等速移動)では必ず累積長テーブルが 必要になります。この関数がそれを1度だけ構築し、距離での参照を提供します。

aspectRatioにctx.canvas.aspect_ratioを渡すと、x方向の差分に掛けて距離の意味を縦横で 揃えます。省略すると正規化単位そのままで測るため、非正方canvasでは間隔が伸び縮みします。

引数 ​

引数型単位省略時内容
pointstable座標指定必須1始まりの制御点配列。canvas正規化座標で指定するとmt.layout.place_2dやmt.layout.queue_on_pathと組み合わせられます
aspectRationumber-1.0X方向の距離へ掛けるアスペクト比。通常はctx.canvas.aspect_ratioを渡します
optionstable-nil曲線の種類を指定する設定
options.kindstring-"catmull_rom""catmull_rom"または"bezier"

戻り値 ​

型単位内容
table-距離による参照を提供するパスオブジェクト

パスオブジェクトは次のメソッドを持ちます。

メソッド戻り値単位内容
path:length()number入力座標に準拠アスペクト比を補正したパス全長
path:at_distance(distanceRatio)3つのnumber入力座標に準拠、度距離比0-1でのx、y、headingDegrees

制約・エラー ​

  • pointsには2個以上の点が必要です。
  • options.kind = "bezier"では、pointsにちょうど4個の点が必要です。
  • options.kindには"catmull_rom"または"bezier"を指定します。

NOTE

at_distanceの3番目の戻り値は度数の向きで、画面座標系(canvasのYは下向き)に変換済みです。 rotationへそのまま代入できます。mt.path.bezier / catmull_romが返す生の接線と違い、 符号を自分で反転する必要はありません。

向きは進行方向に追従します。右から左へ進むパスでは約180度になるため、rotationへ そのまま代入すると文字が上下反転します。傾きを保ったまま正立させるには180.0を加算します。

lua
-- 右から左へ進むパスで文字を正立させる
character.rotation = heading + 180.0

使用例 ​

lua
-- 距離で等間隔に配置する(tで等間隔にすると曲がりで詰まる)
local path = mt.path.arc_length(kWaypoints, ctx.canvas.aspect_ratio)
for index = 1, ctx.char_count do
    local ratio = mt.distribute(index, ctx.char_count)
    local x, y, heading = path:at_distance(ratio)
    ctx.chars[index].rotation = heading
    mt.layout.place_2d(ctx, ctx.chars[index], x, y)
end

17. パスの作成・編集 ​

mt.svg_path(source, optionsOrSourceUnitsPerEm?) ​

APIレベル: 5+

SVGの d 属性と同じ文字列を、再利用可能な読み取り専用パステンプレートへ変換します。 簡易SVG互換として、絶対・相対の M / L / H / V / Q / T / C / S / Z と 連続する座標組を扱います。楕円弧 A / a は未対応です。

引数 ​

引数型単位省略時内容
sourcestring-指定必須SVGのパスデータ
optionsOrSourceUnitsPerEmnumber / table-nil元データの1emあたりの単位数、または{ view_box, em_scale }

戻り値 ​

型単位内容
MtDrawingPath-path:assign(template)へ渡せる読み取り専用のパステンプレート

正規化の指定 ​

数値を指定すると、その値を元データの1emあたりの単位数として1000単位へ正規化します (例: 24単位を1emとして扱う場合は mt.svg_path(source, 24))。

view_box = { minX, minY, width, height } を指定すると、viewBox中央を原点へ移し、縦横比を 維持したまま最大辺を em_scale emへ合わせます。em_scale の既定値は 1.0 です。

制約・エラー ​

  • 数値で指定する1emあたりの単位数は、有限の正数である必要があります。
  • view_boxは4個の有限な数値を持ち、幅と高さは正数である必要があります。
  • em_scaleは有限の正数である必要があります。
  • units_per_emは設定tableでは指定できません。数値形式またはem_scaleを使用します。

使用例 ​

lua
local icon = mt.svg_path(svgPathFrom24PxIcon, {
    view_box = { 0, 0, 24, 24 },
    em_scale = 0.7,
})

function OnPath(ctx)
    for _, part in ipairs(ctx.paths:select("c1, p8-10, !p9")) do
        part.path:assign(icon)
    end
end

IMPORTANT

em_scale は描画サイズ(1emの何倍か)です。em_scale = 0.5 なら半分の大きさになります。 多くのフォントで実際の字面は1emより小さいため、既定の 1.0 ではアイコンが隣の文字へ 食い込むことがあります。その場合は em_scale を下げるか、OnLayout で字送りを広げます。

注意事項 ​

静的なSVG文字列は関数の外側で mt.svg_path に変換して local 変数へ保持すると、 毎フレームの再解析を避けられます。


mt.drawing_path() ​

APIレベル: 9+

空の可変MtDrawingPathを生成します。top levelと全hookで呼び出せます。座標はY-downの part-local座標で、1000単位が1emです。既存の構築メソッドで形状を作り、 ctx.glyphs:declare({ path = path })などへ渡せます。

lua
local diamond = mt.drawing_path()
diamond:move_to(0, -500)
diamond:line_to(500, 0)
diamond:line_to(0, 500)
diamond:line_to(-500, 0)
diamond:close()

描画パス編集API ​

APIレベル: 5+

ctx.pathsで取得したパーツのpathは、次のメソッドで編集できます。

メソッド内容
path:clear()パス内の全コマンドを削除
path:assign(template)mt.svg_pathで作成したテンプレートで置換
path:set_svg(source)SVGのパスデータを解析して置換
path:move_to(x, y)サブパスの始点を追加
path:line_to(x, y)直線を追加
path:quad_to(cx, cy, x, y)2次Bézier曲線を追加
path:cubic_to(cx1, cy1, cx2, cy2, x, y)3次Bézier曲線を追加
path:close()現在のサブパスを閉じる
path:bounds()曲線極値を含むtight boundsを取得
path:map_points(callback)トポロジーを維持して全pointを変形

座標系 ​

パス座標はパーツ中心を原点とするY-downの正規化ローカル座標で、1000単位が1 emです。 API境界で実際のフォントサイズへ自動変換されるため、Canvas解像度には依存しません。

変更の適用 ​

ctx.pathsはフレームごとに再構築されるため、pathの変更は毎フレーム適用してください。 適用しなかったパーツは元のグリフ輪郭に戻ります。


path:clear() ​

APIレベル: 5+

パス内のすべてのコマンドを削除します。

戻り値 ​

戻り値はありません。

変更内容 ​

対象のパスを空にし、座標の正規化設定を初期値へ戻します。


path:assign(template) ​

APIレベル: 5+

パスをmt.svg_pathで作成したテンプレートの内容へ置き換えます。

引数 ​

引数型単位省略時内容
templateMtDrawingPath-指定必須コピー元のパステンプレート

戻り値 ​

戻り値はありません。

変更内容 ​

対象のパスデータと座標の正規化設定を、テンプレートの内容へ置き換えます。


path:set_svg(source) ​

APIレベル: 5+

SVGのパスデータを解析し、対象のパスを置き換えます。

引数 ​

引数型単位省略時内容
sourcestring-指定必須SVGのd属性と同じ形式のパスデータ

戻り値 ​

戻り値はありません。

変更内容 ​

対象のパスを指定したSVGパスへ置き換え、座標の正規化設定を初期値へ戻します。


path:move_to(x, y) ​

APIレベル: 5+

指定した座標を始点とする新しいサブパスを追加します。

引数 ​

引数型単位省略時内容
x / ynumberパスローカル座標指定必須サブパスの始点

戻り値 ​

戻り値はありません。

変更内容 ​

対象のパスへmoveコマンドを追加します。

制約・エラー ​

座標は有限の数値である必要があります。


path:line_to(x, y) ​

APIレベル: 5+

現在位置から指定した座標までの直線を追加します。

引数 ​

引数型単位省略時内容
x / ynumberパスローカル座標指定必須直線の終点

戻り値 ​

戻り値はありません。

変更内容 ​

対象のパスへlineコマンドを追加します。

制約・エラー ​

座標は有限の数値である必要があります。


path:quad_to(cx, cy, x, y) ​

APIレベル: 5+

現在位置から指定した終点までの2次Bézier曲線を追加します。

引数 ​

引数型単位省略時内容
cx / cynumberパスローカル座標指定必須制御点
x / ynumberパスローカル座標指定必須曲線の終点

戻り値 ​

戻り値はありません。

変更内容 ​

対象のパスへquadratic Bézierコマンドを追加します。

制約・エラー ​

座標は有限の数値である必要があります。


path:cubic_to(cx1, cy1, cx2, cy2, x, y) ​

APIレベル: 5+

現在位置から指定した終点までの3次Bézier曲線を追加します。

引数 ​

引数型単位省略時内容
cx1 / cy1numberパスローカル座標指定必須現在位置側の制御点
cx2 / cy2numberパスローカル座標指定必須終点側の制御点
x / ynumberパスローカル座標指定必須曲線の終点

戻り値 ​

戻り値はありません。

変更内容 ​

対象のパスへcubic Bézierコマンドを追加します。

制約・エラー ​

座標は有限の数値である必要があります。


path:close() ​

APIレベル: 5+

現在のサブパスを始点へ接続して閉じます。

戻り値 ​

戻り値はありません。

変更内容 ​

対象のパスへcloseコマンドを追加します。


path:bounds() ​

APIレベル: 9+

曲線極値を含むtight boundsをminimumX, minimumY, maximumX, maximumYの4値で返します。 空パスではnilを1つ返します。値はパスと同じY-down、1000単位=1emです。パスを参照できる 任意の場所で、読み取り専用テンプレートと可変パスの両方に利用できます。


path:map_points(callback) ​

APIレベル: 9+

callback(x, y, point)が返す2座標で、アンカー点と制御点をcommand順に置き換えます。 command種別・数、contour、close状態は変わりません。全callback成功後にだけ反映されます。 standaloneの可変パスでは保持している任意の場所、ctx.pathsのtargetではOnPath中に利用できます。

pointは再利用される読み取り専用viewで、index、command_index、contour_index、 role(anchor / control1 / control2)、command(move / line / quad / cubic)を持ちます。 1パス4096 points、1 script実行16384 pointsが上限です。同じreceiverへのcallback中の再入・変更、 有限でない戻り値はエラーになり、パスは変更されません。

lua
path:map_points(function(x, y, point)
    return x, y + math.sin(point.index * 1.7 + ctx.progress * math.pi * 2) * 25
end)

18. UTF-8テキスト処理 ​

mt.text.slice(text, startChar, endChar?) ​

APIレベル: 1+

UTF-8コードポイント境界で文字列をスライスします(Lua標準のバイト単位のstring.subと 異なり、個々のUTF-8コードポイントの途中では切りません)。書記素クラスタ単位ではないため、 結合文字やZWJで連結された絵文字を見た目上の1文字の途中で分割することがあります。 ctx.chars[index].textはシェイピング後のクラスタであり、この関数のindexとは同一概念では ありません。

引数 ​

引数型単位省略時内容
textstring-指定必須対象の文字列
startCharinteger-指定必須切り出し開始コードポイントindex。1始まりで、この位置を含みます
endCharinteger-末尾切り出し終了コードポイントindex。1始まりで、この位置を含みます

戻り値 ​

型単位内容
string-指定範囲を切り出した文字列。範囲が空または無効な場合は空文字列

mt.text.classify(text) ​

APIレベル: 4+

テキストクラスタの先頭Unicodeコードポイントを、アニメーションで扱いやすい文字種名へ分類します。

引数 ​

引数型単位省略時内容
textstring-指定必須分類するテキストクラスタ

戻り値 ​

型単位内容
string-"kanji"、"hiragana"、"katakana"、"punctuation"、"latin"、"digit"、"space"、"other"のいずれか

使用例 ​

lua
for _, character in ipairs(ctx.chars) do
    if mt.text.classify(character.text) == "kanji" then
        character.scale = 1.2
    end
end

注意事項 ​

書記素クラスタ全体の言語判定ではなく先頭コードポイントによる軽量分類です。空文字列、絵文字、 結合記号など、定義済み範囲に該当しないものは"other"になります。

19. 文字・パーツ指定 ​

mt.target.chars(ctx, specification, options?) ​

APIレベル: 13+

指定文字列を文字番号に解決します。文法は本体の文字・パーツ対象設定と同じなので、スクリプトの入力でも同じ書き方を提供できます。

  • トークンはカンマまたは空白で区切ります。
  • c3は文字3、p2はグローバルパーツ2、数字だけの指定はこの関数では文字を表します。
  • a-bは両端を含む範囲です。c1-c3・p2-p5・2-4のいずれも書けます。片側が数字だけのときはもう一方の種別に揃い、逆順の範囲は入れ替えられ、両端の種別が異なる範囲は無視されます。
  • 先頭の!は除外です。除外は書く順序にかかわらず、すべての指定より優先されます。
  • テキストに存在しない番号・不正なトークン・0は無視されます。

パーツが1つでも選ばれた文字が列挙されるため、p5はパーツ5を持つ文字を返します。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutまたはOnPathのコンテキスト
specificationstring-指定必須指定文字列
optionstable-nil{ empty = "none" | "all" }。何も選ばない文字列の扱い。"none"(既定)は何も選ばず、"all"はすべての文字を選びます。"all"でも除外は有効です

戻り値 ​

型単位内容
integer[]-昇順の文字番号(ctx.charsのindex)。ipairsでそのまま回せます

例 ​

lua
function OnLayout(ctx)
    for _, characterNumber in ipairs(mt.target.chars(ctx, "1-3, 6, !c2")) do
        ctx.chars[characterNumber].scale = 1.2
    end
end

mt.target.parts(ctx, specification, options?) ​

APIレベル: 13+

指定文字列をグローバルパーツ番号に解決します。文法はmt.target.charsと同じで、数字だけの指定がパーツを表す点だけが異なります。c3のような文字の指定は、その文字のすべてのパーツを選びます。

引数 ​

引数型単位省略時内容
ctxtable-指定必須OnLayoutまたはOnPathのコンテキスト
specificationstring-指定必須指定文字列
optionstable-nil{ empty = "none" | "all" }。何も選ばない文字列の扱い。"none"(既定)は何も選ばず、"all"はすべてのパーツを選びます。"all"でも除外は有効です

戻り値 ​

型単位内容
integer[]-昇順のグローバルパーツ番号(ctx.partsのindex)。ipairsでそのまま回せます

例 ​

lua
function OnLayout(ctx)
    for _, partNumber in ipairs(mt.target.parts(ctx, "c1 p9")) do
        ctx.parts[partNumber].opacity = 0.5
    end
end

20. クリップ時間 ​

mt.timeline.progress(ctx, fallbackDuration?) ​

APIレベル: 1+

現在の進行度(0から1)を取得します。

引数 ​

引数型単位省略時内容
ctxtable-指定必須コンテキスト
fallbackDurationnumber秒4.0タイムラインを取得できない場合にループさせる仮想クリップ長

戻り値 ​

型単位内容
number0-1現在の進行度

制約・エラー ​

タイムラインを取得できない場合、fallbackDurationには正数を指定します。


mt.timeline.duration(ctx, fallbackDuration?) ​

APIレベル: 6+

ホストから取得した正のクリップ長を秒で返します。ホストタイムラインを利用できない場合、 または取得した秒数が有限の正数でない場合は、指定したフォールバック時間を返します。

引数 ​

引数型単位省略時内容
ctxtable-指定必須コンテキスト
fallbackDurationnumber秒4.0タイムラインを取得できない場合の仮想クリップ長

戻り値 ​

型単位内容
number秒ホストのクリップ長、またはフォールバック時間

制約・エラー ​

明示するfallbackDurationは有限の正数である必要があります。window_ctxが返す派生contextを 渡した場合は、その時間窓のdurationを返します。

lua
local clipDuration =
    mt.timeline.duration(ctx, kFallbackClipLength)

mt.timeline.remaining(ctx, fallbackDuration?) ​

APIレベル: 1+

クリップ終端までの残り実秒を返します。アウトロ(退場アニメーション)を終端アンカーの 実時間で書くための基礎部品です(ctx.timelineの設計ルール参照)。

引数 ​

引数型単位省略時内容
ctxtable-指定必須コンテキスト
fallbackDurationnumber秒4.0タイムラインを取得できない場合にループさせる仮想クリップ長

戻り値 ​

型単位内容
number秒クリップ終端までの残り時間

使用例 ​

lua
-- クリップ長にかかわらず、最後の0.5秒でフェードアウト
local fade = mt.clamp(mt.timeline.remaining(ctx) / 0.5, 0.0, 1.0)

mt.timeline.intro_outro_seconds(ctx, introSeconds, outroSeconds, fallbackDuration?) ​

APIレベル: 1+

イントロ(クリップ先頭アンカー)とアウトロ(クリップ終端アンカー)の進行度を、 指定した実秒数で進む固定速度で返します。クリップの尺を変えてもトランジションの 速度は変わりません。クリップが introSeconds + outroSeconds より短い場合のみ、 両区間を比例圧縮してクリップ内に収めます(自動早送り)。

引数 ​

引数型単位省略時内容
ctxtable-指定必須コンテキスト
introSecondsnumber秒指定必須イントロの長さ。負値は0として扱います
outroSecondsnumber秒指定必須アウトロの長さ。負値は0として扱います
fallbackDurationnumber秒4.0タイムラインを取得できない場合の仮想クリップ長

戻り値(多値) ​

型単位内容
number0-1introProgress。イントロの進行度
number0-1outroProgress。アウトロの進行度

使用例 ​

lua
local intro, outro = mt.timeline.intro_outro_seconds(ctx, 0.8, 0.5)
character.offset_y = 0.5 + (1.0 - mt.ease.out_cubic(intro)) * 0.2
character.scale = character.scale * (1.0 - mt.ease.in_cubic(outro))

mt.timeline.window_progress(ctx, start, duration) ​

APIレベル: 6+

コンテキスト内の指定時間窓を0-1の線形進行度へ変換します。startより前は正確に0.0、 start + duration以後は正確に1.0を返します。区間内では (ctx.time - start) / durationを返します。

引数 ​

引数型単位省略時内容
ctxtable-指定必須時間を読み取るコンテキスト
startnumber秒指定必須コンテキスト内での開始時間
durationnumber秒指定必須時間窓の長さ

戻り値 ​

型単位内容
number0-1開始前と終了後をクランプした時間窓内の線形進行度

制約・エラー ​

  • ctx.timeは数値である必要があります。
  • startは有限の数値である必要があります。
  • durationは有限の正数である必要があります。

使用例 ​

lua
local appear =
    mt.timeline.window_progress(ctx, 0.5, 0.8)
local disappear =
    mt.timeline.window_progress(ctx, 4.0, 0.5)

character.opacity = appear * (1.0 - disappear)

注意事項 ​

進行度だけが必要な場合に使用します。時間やframeもローカル化して時間依存APIへ渡す場合は、 mt.timeline.window_ctxを使用します。


mt.timeline.window_ctx(ctx, start, duration) ​

APIレベル: 4+

元のctxから、指定時間窓の派生ctxを生成します。startは元ctx内の開始秒、durationは正の 時間窓長です。派生ctxのtimeはctx.time - startを0〜durationへクランプした値となり、 frame、timeline.duration_*、timeline.progressも同じローカル時間基準へ変換されます。 canvas、global、chars、partsなど、それ以外の値は元ctxから引き継ぎます。

引数 ​

引数型単位省略時内容
ctxtable-指定必須元のコンテキスト
startnumber秒指定必須元のコンテキスト内での開始時間
durationnumber秒指定必須時間窓の長さ

戻り値 ​

型単位内容
table-時間関係を指定窓へ再マッピングした派生コンテキスト

制約・エラー ​

  • ctx.timeは数値である必要があります。
  • startは有限の数値である必要があります。
  • durationは有限の正数である必要があります。

使用例 ​

lua
local characterCtx =
    mt.timeline.window_ctx(ctx, (index - 1) * 0.08, 0.5)

local bounce = mt.bounce_y({ t = characterCtx.time })
local opacity = mt.ease.out_cubic(characterCtx.timeline.progress)

注意事項 ​

元ctxや共有された文字・パーツを複製するAPIではありません。時間関係だけを差し替えた 浅い派生コンテキストです。


mt.timeline.chain(ctx, initialValue, segments, options?) ​

APIレベル: 4+

時間区間ごとの純粋関数を順番に評価し、完了した区間の最終戻り値を次区間へ渡します。 現在時刻より前の evaluate はその区間の終端コンテキストで評価され、現在の区間だけが 区間ローカルの ctx で評価されます。戻り値は number、color、座標や変形をまとめたtableなど 任意のLua値にできます。

引数 ​

引数型単位省略時内容
ctxtable-指定必須元のコンテキスト
initialValue任意-指定必須最初の区間へ渡す初期値
segmentstable-指定必須アニメーション区間または保持区間の配列
optionstable-nilタイムラインを取得できない場合の設定
options.fallback_durationnumber秒4.0仮想クリップ長

戻り値 ​

型単位内容
任意-現在時刻まで評価した最後の区間の値

使用例 ​

lua
local result = mt.timeline.chain(ctx, initialValue, {
    {
        duration = 1.0,
        evaluate = function(segmentCtx, previousValue)
            return enterAnimation(segmentCtx, previousValue)
        end,
    },
    { hold = 0.5 },
    {
        duration = 1.2,
        evaluate = function(segmentCtx, previousValue)
            return bounceAnimation(segmentCtx, previousValue)
        end,
    },
})

区間コンテキスト ​

segmentCtxは呼び出し元のctxからcanvas、global、chars、partsなどを引き継ぎ、時間関係だけを 現在区間へ置き換えたコンテキストです。mt.timeline.progressなど、ctxを読み取る既存の Level 3 APIへ通常のctxと同じように渡せます。

フィールド型単位内容
segmentCtx.timenumber秒区間開始からの時間
segmentCtx.framenumberframe区間開始からのフレーム数
segmentCtx.fpsnumberfps呼び出し元と同じフレームレート
segmentCtx.timeline.duration_secondsnumber秒区間の論理duration
segmentCtx.timeline.duration_framesnumberframe区間の論理durationをフレーム換算した値
segmentCtx.timeline.progressnumber0-1区間内の進行度

区間の形式 ​

各区間は次のいずれかの形式です。

区間指定動作
固定長アニメーション{ duration = 秒数, evaluate = 関数 }evaluate(segmentCtx, previousValue) の戻り値を使用
固定長保持{ hold = 秒数 }関数を呼ばず、直前の値を保持
可変長アニメーション{ duration = "remaining", evaluate = 関数 }固定区間を除いた残りのクリップ尺を使用
可変長保持{ hold = "remaining" }残りのクリップ尺で直前の値を保持

"remaining"は1つのchain内で1区間だけ指定できます。その後ろに固定長のアウトロを置くと、 可変区間だけがクリップ尺の変更を吸収し、アウトロは常にクリップ終端で完了します。

lua
local state = mt.timeline.chain(ctx, initialState, {
    { duration = 1.0, evaluate = evaluateIntro },
    { duration = 1.2, evaluate = evaluateBounce },
    { duration = "remaining", evaluate = evaluateIdle },
    { duration = 0.6, evaluate = evaluateOutro },
}, {
    fallback_duration = 6.0,
})

固定区間の合計がクリップ尺を超える場合は、すべての固定区間を比例圧縮します。 segmentCtx.timeとsegmentCtx.timelineは宣言したdurationへ再マッピングされるため、 短いクリップでも各アニメーションは終端状態まで到達します。タイムライン取得不可時は options.fallback_duration(既定 4.0 秒)を仮想クリップ長としてループします。

制約・エラー ​

  • ctx.timeは数値、segmentsとoptionsはtableである必要があります。
  • 各区間はdurationまたはholdのどちらか一方だけを指定します。
  • duration区間にはevaluate関数が必要で、hold区間には指定できません。
  • 区間長には有限の0以上の数値または"remaining"を指定します。
  • "remaining"を指定できる区間は1つだけです。
  • options.fallback_durationは有限の正数である必要があります。

IMPORTANT

evaluateは過去区間の終端値を得るため同じフレーム内で再評価されます。ctxやcharacterを 直接変更せず、引数から計算した値を返す純粋関数として記述し、最終結果だけを適用してください。 mt.bounce_groundのようにitemを直接変更するAPIではなく、値を返すmt.bounce_yなどを segmentCtx.timeと組み合わせて使用します。

21. 非推奨の互換API ​

mt.storage 非推奨 ​

APIレベル: 1+

mt.storageは既存スクリプトとの互換性のために残されています。 新規スクリプトでは、関数の外側で宣言したlocal変数に不変値を保持してください。

型内容
table読み取り専用の互換用ストレージ

mt.polar_offset(angleDegrees, radius) 非推奨 ​

APIレベル: 3+

角度系のY方向を使う旧形式の極座標変換です。

引数 ​

引数型単位省略時内容
angleDegreesnumber度指定必須方向。0度は右で、正方向は時計回りです
radiusnumber変位指定必須その方向への距離

戻り値(多値) ​

型単位内容
numberradiusに準拠offsetX
numberradiusに準拠screenOffsetY。画面基準で下が正です

WARNING

非推奨です。mt.polar_offset_2d を使用してください。 引数は mt.polar_offset_2d と同じですが、戻り値が角度系(Y は下が正)のため、offset_y へ渡す際に符号の反転が必要でした。反転を忘れると上下だけが逆に動くという取り違えが起き やすいため、位置系で返す mt.polar_offset_2d に置き換えています。動作は変更していないので 既存のスクリプトはそのまま動作します。

使用例 ​

lua
-- 旧: 呼び出し側で反転が必要
local dx, dy = mt.polar_offset(angle, radius)
character.offset_y = 0.5 - dy

-- 新: そのまま加算できる
local dx, dy = mt.polar_offset_2d(angle, radius)
character.offset_y = 0.5 + dy

mt.layout.retypeset(ctx, gap?, config?) 非推奨 ​

APIレベル: 1+

CAUTION

API Level 1互換関数です。新規コードではmt.layout.reflowを使用してください。

文字ごとの個別のscaleやstretchを考慮し、geometry.advance_x/yを使って簡易的に 字送りを再計算します。可視インク境界間の隙間を均一にする関数ではありません。 文字ごとのサイズアニメーションを適用した後、そのフレームの最終再組版処理として呼び出します。 rotation、個別pivot、tracking、margins、変形後の輪郭は送り計算に含みません。

引数 ​

引数型単位省略時内容
ctxtable-指定必須コンテキスト
gapnumbercanvas幅比または高さ比0.0advance間へ追加する余白
configtable-nil再整列の設定
config.alignstring-"baseline"横書き時の交差軸整列。"baseline"、"top"、"center"、"bottom"
config.modestring-"horizontal""horizontal"または"vertical"
config.targetstable-全文字再整列する1始まりの文字index配列。対象外の文字は変更しません
config.anchorinteger-targetsの最小index送り軸の現在位置を固定する文字index
config.baselinestring-"anchor"基準線を現在の姿から取る"anchor"、または自然な姿から取る"natural"

config.baseline = "anchor"では、アンカー文字のscaleがフレームごとに変わると基準線ごと 行全体が上下します。"natural"は交差軸を自然位置に固定するため、時間変化するscaleと 併用する場合に適しています。"anchor"はscaleとoffset適用後の現在の姿、"natural"は scale 1・offsetなしのBaseレイアウト時の姿を基準にします。送り軸のアンカー位置はどちらでも 現在位置のままです。config.alignは縦書きの簡易整列では使用しません。

戻り値 ​

戻り値はありません。

変更内容 ​

対象文字のoffset_xとoffset_yを直接書き換えます。

WARNING

targets で一部の文字だけを対象にした場合、gap は対象範囲を対象外の隣接文字に 衝突させることがあります。 gap は対象範囲内の文字間隔に呼び出しのたびに加算され、 対象範囲全体の幅を押し広げます。この関数は targets に含まれない文字の座標を一切 変更しない(=対象外の文字の位置を考慮して自動的に間を空けたりしない)ため、対象範囲の 端(先頭または末尾)が対象外の文字にもともと隣接していた場合、gap を足すたびに その対象外の文字と重なる方向へ範囲が伸びていきます。全文字を対象にする場合や、 対象範囲の前後に元から十分な余白がある場合は問題になりませんが、一部の文字だけを 対象にして、かつその境界が別の文字と隣接している場合は gap を 0 にするか、 対象範囲の外側にも手動で余白(tracking / margins)を確保してください。

使用例 ​

lua
-- インデックス 3〜6 の文字のみを整列し、インデックス 3 の文字位置を基準に固定して左右に整列
mt.layout.retypeset(ctx, 0.02, {
    targets = {3, 4, 5, 6},
    anchor = 3,
    align = "baseline"
})

mt.layout.canvas_to_offset(resolvedGlobal, canvasWidth, canvasHeight, naturalCenterX, naturalCenterY, canvasX, canvasY) 非推奨 ​

APIレベル: 1+

CAUTION

API Level 1互換関数です。globalの2D変形しか逆算しません。新規コードでは mt.layout.place_2dを使用してください。

文字・パーツの自然中心を、2Dのglobal変形までを考慮したcanvas上の目標位置へ移す offsetを求めるときに使います。offset_x / offset_y は「自身の自然な位置からの変位量」であり ctx.global(position / rotation / scale / stretch / pivot)による全体変形の前の座標系にあるため、目標のcanvas座標を そのまま offset_x = canvasX のように代入しても、ctx.global が初期値のときしか意図した 画面位置になりません。全体を回転・移動・拡大している場合、その変形の分だけ実際の位置が ずれます。この関数は ctx.global の2D変形を打ち消した上で、目標のcanvas位置に対応する offset_x / offset_y を計算します。

引数 ​

引数型単位省略時内容
resolvedGlobaltable-指定必須OnPreLayoutで確定済みのctx.global
canvasWidth / canvasHeightnumberpx指定必須ctx.canvas.widthとctx.canvas.height
naturalCenterX / naturalCenterYnumbercanvas正規化位置指定必須対象の自然中心。文字ではgeometry.bounds_center_x/y、パーツではgeometry.canvas_center_x/y
canvasX / canvasYnumbercanvas正規化位置指定必須配置先の座標

戻り値(多値) ​

型単位内容
numbercanvas正規化変位offsetX
numbercanvas正規化変位offsetY

制約・エラー ​

この関数が反転するのはposition_x/y、rotation、scale、stretch_x/y、 pivot_x/yだけです。文字・パーツの個別rotation/pivot、所有文字からパーツへの階層変形、 global/個別の3D値、camera、projection、Deformは反転しません。幅・高さおよび global.scale * stretch_x/yは非ゼロでなければなりません。

使用例 ​

lua
-- 2D ctx.global.rotation / position_x などを OnPreLayout で変更していても、
-- 個別/3D/Deform変形がなければ自然中心は canvas 上の (0.8, 0.3) に来る
local geometry = character.geometry
character.offset_x, character.offset_y = mt.layout.canvas_to_offset(
    ctx.global, ctx.canvas.width, ctx.canvas.height,
    geometry.bounds_center_x, geometry.bounds_center_y,
    0.8, 0.3
)

注意事項 ​

パーツの場合、パーツ自身の変形(part.offset_x/y 等)は 所有文字の解決済み変形の 内側に重ねて適用されるため、この関数は「文字の変形を無視して canvas 上の固定位置に 置く」ことはできません(文字自体が動いていれば、パーツも一緒に動きます)。パーツを 文字の変形とは独立に canvas 上の固定位置へ置きたい場合は、まずその文字の offset_x/y / rotation / scale 等を確認し、パーツ側の変位量にその逆変形を 別途適用する必要があります。


mt.layout.set_canvas_position(item, canvasX, canvasY, ctx?) 非推奨 ​

APIレベル: 1+

CAUTION

API Level 1互換関数です。パーツの所有文字階層と対象自身の変形を逆算しません。 新規コードではmt.layout.place_2dを使用してください。

文字オブジェクト(ctx.chars[i])またはパーツオブジェクト(ctx.parts[i])へ、指定した canvas目標位置(canvasX, canvasY)に対応するoffset_x/yを書き込むヘルパーです。

文字にはgeometry.bounds_center_x/y、パーツにはgeometry.canvas_center_x/yを自然中心として 使います。第4引数にctxを渡すとcanvas_to_offsetと同じ2D global変形だけを反転します。 パーツの所有文字変形、3D、camera、projection、Deformは反転しないため、これらが有効な場面の 最終画面位置を保証する関数ではありません。ctxを省略した場合はglobalがidentityのときだけ 自然中心が目標canvas位置と一致します。

引数 ​

引数型単位省略時内容
itemtable-指定必須対象の文字またはパーツ
canvasX / canvasYnumbercanvas正規化位置指定必須配置先の座標
ctxtable-nil指定するとctx.globalの2D変形だけを逆算します

戻り値(多値) ​

型単位内容
numbercanvas正規化変位設定したoffsetX
numbercanvas正規化変位設定したoffsetY

変更内容 ​

対象のoffset_xとoffset_yを直接更新します。

使用例 ​

lua
-- 文字の自然中心を2D画面右上 (0.8, 0.8) へ
mt.layout.set_canvas_position(ctx.chars[1], 0.8, 0.8, ctx)

-- 親文字とglobalがidentityなら、パーツの自然中心を画面中央へ
mt.layout.set_canvas_position(ctx.parts[1], 0.5, 0.5)

mt.layout.group_bounds(ctx, targets, targetType?) 非推奨 ​

APIレベル: 1+

CAUTION

API Level 1互換関数です。rotation、pivot、親文字、globalを除外した近似値です。 新規コードではmt.layout.measure_bounds_2dを使用してください。

指定した文字またはパーツの、変形途中の近似軸平行境界を返します。

自然インク境界へ各要素のoffset_x/y、scale、stretch_x/yだけを適用します。 要素のrotation/pivot、パーツの所有文字変形、ctx.global、3D、camera、projection、Deformは 考慮しません。したがって、回転なし・階層/global変形なしの2Dレイアウトにおける補助計算には 使えますが、最終描画境界、物理境界、衝突判定を保証しません。公開APIには最終投影済みパス境界を 取得する関数はありません。対象要素のoffset/scale/stretchを書いた後に呼び出してください。

引数 ​

引数型単位省略時内容
ctxtable-指定必須レイアウトコンテキスト
targetstable-指定必須1始まりの対象index配列
targetTypestring-"character""character"または"part"

戻り値(いずれか) ​

型単位内容
table-近似境界
nil-有効な対象がない場合

境界tableは次のフィールドを持ちます。

フィールド型単位内容
left / right / bottom / topnumbercanvas正規化位置上記の変形段階における近似境界
center_x / center_ynumbercanvas正規化位置グループの中心
width / heightnumbercanvas正規化変位グループ全体の幅と高さ

使用例 ​

lua
-- インデックス 1〜3 の親文字グループ全体の境界を取得
local bounds = mt.layout.group_bounds(ctx, {1, 2, 3})
if bounds then
    -- グループ全体の中心座標や幅・高さを利用して背景プレートやルビを配置
    print(bounds.center_x, bounds.center_y, bounds.width, bounds.height)
end

mt.timeline.intro_outro(progress, introFraction, outroFraction) 非推奨 ​

APIレベル: 1+

全体進行度から、最初(イントロ)と最後(アウトロ)の区間それぞれの進行度を個別に抽出して返します。

WARNING

非推奨: 割合ベースのトランジションはクリップの尺に比例して伸び縮みするため、 尺を伸ばすとフェードがスローモーション化します。固定速度で進む mt.timeline.intro_outro_seconds を使ってください (ctx.timelineの設計ルール参照)。

引数 ​

引数型単位省略時内容
progressnumber0-1指定必須全体進行度。通常はmt.timeline.progressから取得します
introFractionnumber0-1指定必須イントロとして扱う全体尺の割合
outroFractionnumber0-1指定必須アウトロとして扱う全体尺の割合

戻り値(多値) ​

型単位内容
number0-1introProgress。イントロの進行度
number0-1outroProgress。アウトロの進行度