対象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 |
| 非推奨の互換API | mt.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] へ制限します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
value | number | - | 指定必須 | 制限する値 |
low | number | - | 指定必須 | 下限 |
high | number | - | 指定必須 | 上限 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | - | 制限後の値 |
mt.saturate(value)
APIレベル: 1+
mt.clamp(value, 0.0, 1.0) の短縮形です。進行度やアルファ値を0-1に収めるときに使います。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
value | number | - | 指定必須 | 0-1へ制限する値 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | 0-1へ制限された値 |
mt.remap(value, in_low, in_high, out_low, out_high, clamped?)
APIレベル: 1+
値を入力区間から出力区間へ写します。「秒数を進行度に変換する」など区間の変換全般に使います。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
value | number | - | 指定必須 | 変換する値 |
in_low / in_high | number | - | 指定必須 | 入力区間 |
out_low / out_high | number | - | 指定必須 | 出力区間 |
clamped | boolean | - | false | trueなら入力位置を0-1へ制限してから変換します |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | - | 変換後の値 |
制約・エラー
| 条件 | 内容 |
|---|---|
in_low == in_high | 入力区間の幅が0になるため指定できません |
使用例
-- 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として扱い、 逆順の指定でも小さい境界から大きい境界までの区間を周回するようになりました。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
value | number | - | 指定必須 | 周回させる値 |
boundaryA | number | - | 指定必須 | 区間を決める一方の境界 |
boundaryB | number | - | 指定必須 | 区間を決めるもう一方の境界 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | - | 周回後の値 |
制約・エラー
2つの境界が等しい場合は、その境界値を返します。
2. 補間・キーフレーム
mt.lerp(from, to, t)
APIレベル: 1+
from から to への線形補間です。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
from | number | - | 指定必須 | t = 0のときの値 |
to | number | - | 指定必須 | t = 1のときの値 |
t | number | - | 指定必須 | 補間係数。クランプされないため、0-1の外を渡すと外挿されます |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 入力値と同じ | from + (to - from) * t |
mt.inverse_lerp(from, to, value)
APIレベル: 1+
mt.lerp の逆関数です。value が区間 [from, to] のどの位置にあるかを補間係数として返します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
from | number | - | 指定必須 | 係数0に対応する区間の始端 |
to | number | - | 指定必須 | 係数1に対応する区間の終端 |
value | number | - | 指定必須 | 位置を求める値 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
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°側で補間)。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
from | number | degree | 指定必須 | 開始角度 |
to | number | degree | 指定必須 | 目標角度 |
t | number | - | 指定必須 | 補間係数。クランプされません |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | degree | 補間後の角度 |
mt.smoothstep(edge0, edge1, value)
APIレベル: 1+
value が edge0 から edge1 を横切る間、0から1へ滑らかに遷移する値を返します (Hermite補間。両端で速度が0になります)。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
edge0 | number | - | 指定必須 | 結果が0になる遷移の開始位置 |
edge1 | number | - | 指定必須 | 結果が1になる遷移の終了位置 |
value | number | - | 指定必須 | 評価する値 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | 滑らかな遷移値。区間外はクランプされます |
制約・エラー
| 条件 | 内容 |
|---|---|
edge0 == edge1 | 遷移区間の幅が0になるため指定できません |
mt.keyframes(keys, time)
APIレベル: 1+
複数区間のキーフレームを評価します。ctx.timeから直接呼べるため、 落下→バウンド→静止のような多段の振り付けを clamp + inverse_lerp の手書きなしで書けます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
keys | table[] | - | 指定必須 | キーフレームの配列。各要素は{ t = <時刻>, v = <値>, ease = <省略可> }で、tを昇順に並べます |
time | number | 秒 | 指定必須 | 評価する時刻 |
各キーの v は number または { r, g, b, a } 形式の color テーブルのいずれかで、1つの keys 配列内で混在させることはできません。ease は省略可(既定は線形)で、そのキーへ到達するまでの 区間に適用されます。mt.ease.out_bounce のような名前の文字列、または function(t) ... end の 形の任意のイージング関数を渡せます。
time が最初のキーより前なら最初の値、最後のキーより後なら最後の値を返します(クランプ)。
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | color | キーの値と同じ | 区間内で補間された値 |
使用例
-- 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 = tint3. 進行度の分配
mt.distribute(index, count)
APIレベル: 1+
1始まりの index を 0-1 へ均等に割り付けます。先頭が 0、末尾が 1 になります。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
index | integer | - | 指定必須 | 1始まりのindex。ctx.chars[index]のindexなどを渡します |
count | integer | - | 指定必須 | 総数。ctx.char_countなどを渡します |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | (index - 1) / (count - 1)を0-1へ制限した値。count <= 1の場合は0 |
使用例
-- 文字位置に応じて色相を虹状に配置
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は使用できません。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
entries | integer[] | - | 指定必須 | 出力順に並べた文字・global partの符号化index |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
string | - | 入力順を表す有効なmanual order文字列。空配列では空文字列 |
使用例
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 です。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayout / OnPath の context |
options.from | integer | - | 1 | 反復を開始する文字index |
options.to | integer | - | ctx.char_count | 反復を終了する文字index(この値を含む) |
options.line | integer | - | 絞り込みなし | この line_index の文字だけを通します |
options.order | string | - | "asc" | info.progress の割り当て順。"asc" / "desc" / "center" / "random" |
options.seed | integer | - | 0 | order = "random" のときの並びを決めるseed |
戻り値
| 型 | 内容 |
|---|---|
function | index(ctx.chars上のindex)、character、info を返すイテレータ |
info の各フィールド:
| フィールド | 型 | 内容 |
|---|---|---|
progress | number | order に沿った 0-1 の正規化位置 |
n | integer | 絞り込み後の通し番号(1始まり) |
count | integer | 絞り込み後の要素数(最低1) |
first / last | boolean | 絞り込み後の先頭・末尾かどうか |
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は毎回同じテーブルを使い回します。ループの外へ持ち出す場合は値をコピーしてください。
使用例
-- 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)
endmt.each_part(ctx, options?)
APIレベル: 6+
整形済みパートを絞り込みつつ反復するイテレータを返します。mt.each_char と同じ規則に加えて、所属文字を info から直接参照でき、所属文字による絞り込みができます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayout / OnPath の context |
options.from | integer | - | 1 | 反復を開始するパートindex |
options.to | integer | - | ctx.part_count | 反復を終了するパートindex(この値を含む) |
options.from_char | integer | - | 絞り込みなし | 所属文字のindexがこの値以上のパートだけを通します |
options.to_char | integer | - | 絞り込みなし | 所属文字のindexがこの値以下のパートだけを通します |
options.line | integer | - | 絞り込みなし | この line_index のパートだけを通します |
options.order | string | - | "asc" | info.progress の割り当て順。mt.each_char と同じ |
options.seed | integer | - | 0 | order = "random" のときの並びを決めるseed |
from / to(パートindexの範囲)と from_char / to_char(所属文字indexの範囲)は別々の軸で、両方指定した場合は両方を満たすパートだけが通ります。
戻り値
| 型 | 内容 |
|---|---|
function | index(ctx.parts上のindex)、part、info を返すイテレータ |
info は mt.each_char の全フィールドに加えて次を持ちます。
| フィールド | 型 | 内容 |
|---|---|---|
char | MtCharacter | このパートが属する文字(ctx.chars の要素) |
char_index | integer | 属する文字の ctx.chars 上のindex |
index_in_char | integer | その文字の中での位置 |
info.progress は絞り込み後の集合全体を通しで 0-1 に張ります。文字の境界でリセットはしません。文字ごとに 0-1 を張りたい場合は mt.each_char と mt.each_part を入れ子にしてください。
使用例
-- 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
endmt.stagger(time, index, delay, duration)
APIレベル: 1+
index ごとに開始をずらしたアニメーション進行度(ドミノ倒し、カスケード登場、タイピング風の順次アニメーション)を返します。文字送りの定番関数です。 index i のアニメーションは delay * (i - 1) 秒遅れて始まり、duration 秒かけて 0から1へ進みます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
time | number | 秒 | 指定必須 | アニメーション開始からの経過時間 |
index | integer | - | 指定必須 | 1始まりのindex |
delay | number | 秒 | 指定必須 | 次のindexが開始するまでの遅延 |
duration | number | 秒 | 指定必須 | 各indexのアニメーション時間 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | 0-1へクランプされた進行度 |
制約・エラー
| 条件 | 内容 |
|---|---|
duration <= 0 | 0より大きい値を指定してください |
使用例
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
endmt.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を使用します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
progress | number | 0-1 | 指定必須 | 分散元の全体進行度。範囲外も許可され、戻り値が0-1へクランプされます |
position | number | 0-1 | 指定必須 | 要素の正規化位置。範囲外は0-1へクランプされます。通常はinfo.progressを渡します |
span | number | 0-1未満 | 指定必須 | 全体時間のうち、開始時刻の分散に使用する割合 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | positionに対応する要素の進行度 |
戻り値は次の式で計算されます。
mt.saturate((progress - mt.saturate(position) * span) / (1.0 - span))制約・エラー
| 条件 | 内容 |
|---|---|
progressまたはpositionが有限数ではない | エラー |
spanが有限数ではない | エラー |
span < 0またはspan >= 1 | エラー |
使用例
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)
endmt.each_char / mt.each_partのorderを変えると、ループの訪問順を変えずに 開始時間の割り当てだけを変更できます。
mt.stagger_pattern(time, index, count, pattern, delay, duration, seed?)
APIレベル: 1+
開始方向や順序(昇順・降順・中央から外側への波紋・重複なしランダム順)を指定できるスタガー進行度を返します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
time | number | 秒 | 指定必須 | 評価する時刻 |
index | integer | - | 指定必須 | 1始まりのindex |
count | integer | - | 指定必須 | 総数。ctx.char_countなどを渡します |
pattern | string | - | 指定必須 | 進行パターン。"asc" / "desc"(別名"right_to_left")/ "center" / "random" |
delay | number | 秒 | 指定必須 | 開始遅延 |
duration | number | 秒 | 指定必須 | アニメーション時間 |
seed | integer | - | 42 | pattern = "random"のときの乱数種 |
"random"は各indexへ重複しないランダム順位を割り当てます。順位は必ず1つずつ離れるため、遅延の間隔が均等になります。
APIレベル6での変更: 以前はindexごとに独立した乱数で遅延を決めていたため、数文字が偶然ほぼ同時に動き、逆に何も起きない区間ができることがありました。現在は順列を使うため、同じ
seedでも以前とは並びが変わります。
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | 0-1へクランプされた進行度 |
制約・エラー
| 条件 | 内容 |
|---|---|
duration <= 0 | 0より大きい値を指定してください |
4. 距離による影響度
mt.falloff(distance, radius)
APIレベル: 3+
中心で最大、離れるほどなだらかに弱まる影響度の重み(波の通過、光沢の走り、水面の波紋、衝撃波、局所強調)を返します。戻り値は 0〜1 です。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
distance | number | 入力座標系 | 指定必須 | 効果の中心からの距離 |
radius | number | 入力座標系 | 指定必須 | 減衰の広がり。この距離で重みが約0.37(e^-1)になります |
「波の峰」「走る光沢」「注目箇所だけ強調」など、特定の位置を中心に効果を集中させる用途の定番です。
mt.smoothstep との使い分け: smoothstep は範囲外で完全に 0 になる(切れ目ができる)のに対し、falloff は裾が無限に続くため、峰や光が通り抜けていく動きが途切れずに見えます。線形減衰(1 - d/r)のような折れ曲がりも生じません。
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | 距離に応じた影響度の重み |
使用例
-- 波の先端 waveFront が通過した文字だけを持ち上げる
local distance = characterRadius - waveFront
character.offset_y = 0.5 + mt.falloff(distance, 0.25) * 0.1NOTE
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を指定できるようになりました。 省略時の結果は以前と同じです。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
seed | integer | - | 指定必須 | 乱数系列を選ぶ値。同じ用途には同じseedを使います |
index | integer | - | 指定必須 | 系列内の位置。文字indexなどを渡します |
channel | string | - | 省略 | 用途を分離する名前。 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-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 / index | integer | - | 指定必須 | mt.randomと同じ |
low / high | number | - | 指定必須 | 出力範囲 |
channel | string | - | 省略 | 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を渡します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
seed | integer | - | 指定必須 | 順列と共通offsetを決める値 |
index | integer | - | 指定必須 | 1以上count以下の割り当て位置 |
count | integer | - | 指定必須 | 値の個数。1以上 |
low / high | number | - | 指定必須 | low < highを満たす有限の出力境界 |
channel | string | - | 省略 | 独立した割り当てを分離する名前 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 出力範囲と同じ | [low, high)内の安定した割り当て値。sort後の隣接値は(high - low) / countずつ離れます |
使用例
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
endmt.noise1(x, seed?)
APIレベル: 1+
決定論的な1次元 value noise です。x に対して滑らかに連続する「揺らぎ」を返します。 x に時間を渡せば時間方向の揺らぎ、位置を渡せば空間方向の揺らぎになります。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
x | number | - | 指定必須 | サンプル位置。整数間隔の格子点間が滑らかに補間されます |
seed | integer | - | 0 | 揺らぎのパターンを変える値 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | -1-1 | 同じ引数に対して常に同じ連続値 |
使用例
-- 文字ごとに位相の違う手ぶれ風の揺れ
character.rotation = mt.noise1(ctx.time * 0.8, index) * 4.0mt.noise2(x, y, seed?)
APIレベル: 1+
決定論的な2次元 value noise です。位置 (x, y) に対して滑らかな揺らぎを返します。 片方の軸に時間、もう片方に文字位置を渡すと「空間的に流れる」揺らぎが作れます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
x / y | number | - | 指定必須 | サンプル位置 |
seed | integer | - | 0 | 揺らぎのパターンを変える値 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | -1-1 | 同じ引数に対して常に同じ連続値 |
mt.wiggle(time, frequency, amplitude, octaves?, seed?)
APIレベル: 1+
決定論的ノイズによる有機的な揺らぎ(手ブレ、ランダムな微振動、浮遊感)を計算します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
time | number | 秒 | 指定必須 | 評価する時刻 |
frequency | number | Hz | 指定必須 | 1秒あたりの揺れの回数 |
amplitude | number | 出力値と同じ | 指定必須 | 第1オクターブの振幅。複数オクターブの合計最大値ではありません |
octaves | integer | - | 1 | 重ねるノイズのオクターブ数 |
seed | integer | - | 0 | 乱数種 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | amplitudeと同じ | 揺らぎの値 |
octaves > 1では振幅を半減しながら加算するため、理論上の絶対値上限は amplitude * (2 - 2^(1 - octaves))で、オクターブ数が増えると2 * amplitudeへ近づきます。
6. 周期・ばね
mt.cycle(t, period)
APIレベル: 1+
0から1へ繰り返すノコギリ波進行度(ループアニメーション、回転、連続タイマー、レーダー走査)を返します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 指定必須 | 評価する時刻 |
period | number | 秒 | 指定必須 | 1周期の長さ |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | 0以上1未満の進行度 |
制約・エラー
| 条件 | 内容 |
|---|---|
period <= 0 | 0より大きい値を指定してください |
mt.pingpong(t, period)
APIレベル: 1+
0→1→0を繰り返す往復進行度(振り子運動、シャトル往復)を返します。行って戻るループに使います。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 指定必須 | 評価する時刻 |
period | number | 秒 | 指定必須 | 1往復の長さ |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | 0-1の往復値 |
制約・エラー
| 条件 | 内容 |
|---|---|
period <= 0 | 0より大きい値を指定してください |
mt.wave(t, frequency, phase?)
APIレベル: 1+
正弦波による周期運動(浮遊、上下の揺れ、うねり、呼吸のような緩急)を計算します。短縮形 sin(2π × frequency × t + phase) です。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 指定必須 | 評価する時刻 |
frequency | number | Hz | 指定必須 | 1秒あたりの周期数 |
phase | number | radian | 0 | 位相オフセット。indexごとに波をずらす用途にも使えます |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | -1-1 | 波形値 |
mt.wave_square(t, frequency, phase?)
APIレベル: 1+
矩形波による周期的な二値切り替え(点滅、ストロボ、フラッシュ)を計算します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 指定必須 | 評価する時刻 |
frequency | number | Hz | 指定必須 | 1秒あたりの周期数 |
phase | number | radian | 0 | 位相オフセット |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | - | -1.0または1.0 |
mt.wave_triangle(t, frequency, phase?)
APIレベル: 1+
三角波(トライアングルウェーブ)です。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 指定必須 | 評価する時刻 |
frequency | number | Hz | 指定必須 | 1秒あたりの周期数 |
phase | number | radian | 0 | 位相オフセット |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | -1-1 | -1.0から1.0の間で直線的に往復する値 |
mt.wave_sawtooth(t, frequency, phase?)
APIレベル: 1+
のこぎり波(ソートゥースウェーブ)です。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 指定必須 | 評価する時刻 |
frequency | number | Hz | 指定必須 | 1秒あたりの周期数 |
phase | number | radian | 0 | 位相オフセット |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | -1-1 | -1.0から1.0未満へ直線的に上昇し、繰り返す値 |
mt.spring(t, frequency, damping)
APIレベル: 1+
減衰振動(バネの揺れ戻し、プルプルした弾性、ぐらつき、オーバーシュートからの収束)を計算します。t = 0で1から始まり、振動しながら0へ収束します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 指定必須 | 動き始めてからの経過時間。t <= 0では初期値を返します |
frequency | number | Hz | 指定必須 | 1秒あたりの振動回数 |
damping | number | 1/秒 | 指定必須 | 減衰の強さ。大きいほど早く収束します |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
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 へクランプされます)
使用例
-- 目標位置からのずれとして使う(t=0で最大、時間とともに収束。負の区間が行き過ぎ)
local settle = mt.spring(ctx.time - start_time, 3.0, 4.0)
character.offset_y = 0.5 + settle * 0.17. 極座標からの変位
mt.polar_offset_2d(angleDegrees, radius)
APIレベル: 5+
極座標(方向と距離)を Canvas 空間のオフセット 2 値へ変換します(放射状の飛び散り、円運動・公転、爆発演出)。散開・集結・周回といった動きを cos / sin を書かずに表現できます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
angleDegrees | number | degree | 指定必須 | 方向。座標と同じく、0度は右方向で正の値は時計回りです |
radius | number | canvas正規化変位 | 指定必須 | その方向への距離 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number, number | canvas正規化変位 | offsetX, offsetYの2値 |
入力角度はrotation / shadow.angleと同じ画面基準(90度は下)ですが、戻り値はY-upです。 offset_x / offset_yへそのまま加算できます。mt.projectile_2dも同じ規則です。
使用例
-- 文字ごとに放射状へ散らす
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 + dymt.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 とする角度なので、元の図柄が別方向を向く場合は補正角を加えます。
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形式と 引数並び形式の両方で呼び出せます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
config | table | - | 指定必須 | 時刻、衝突面、開始位置、重力または加速度、反発係数、初速、Squash & Stretchの設定 |
共通のconfig
| フィールド | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 0.0 | アニメーション開始からの経過時間 |
restitution | number | - | 0.5 | 反発係数。値が大きいほど衝突後の跳ね返りが強くなります |
start_velocity | number | canvas正規化変位/秒 | 0.0 | 軸方向の初速 |
squash / squash_strength | number | 係数 | 0.15 | 衝突速度に応じて接触軸を潰す強さ |
stretch / stretch_strength | number | 係数 | 0.02 | 移動速度に応じて進行軸を伸ばす強さ |
flexibility | number | radian/秒 | 16.0 | 衝突後に元の形へ戻る振動の速さ |
damping | number | 1/秒 | 7.0 | 衝突後の振動が収束する速さ |
同じ項目に複数の名前がある場合は、左側の名前を優先して使用します。右側は互換用の別名です。
mt.bounce_y固有のconfig
| フィールド | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ground_y | number | canvas正規化位置 | 0.0 | 衝突する床面のY座標 |
start_y | number | canvas正規化位置 | 0.0 | 開始時のY座標 |
gravity | number | canvas正規化変位/秒² | 9.81 | 床面へ向かう加速度の大きさ |
mt.bounce_x固有のconfig
| フィールド | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
wall_x / ground_x | number | canvas正規化位置 | 0.0 | 衝突する壁面のX座標。ground_xは互換用の別名です |
start_x | number | canvas正規化位置 | 0.0 | 開始時のX座標 |
acceleration / accel_x / gravity | number | canvas正規化変位/秒² | 9.81 | 壁面へ向かう加速度の大きさ。accel_xとgravityは互換用の別名です |
引数並び形式
設定tableの代わりに、各値を次の順序で渡すこともできます。
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
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
pos | number | canvas正規化位置 | 計算後の軸座標 |
y | number | canvas正規化位置 | mt.bounce_yの計算後のY座標。posと同じ値です |
x | number | canvas正規化位置 | mt.bounce_xの計算後のX座標。posと同じ値です |
velocity | number | canvas正規化変位/秒 | その時点の軸方向速度 |
stretch_x / stretch_y | number | 倍率 | Squash & Stretchを反映したX方向とY方向の伸縮率 |
offset_y | number | bounds_heightに対する比率 | mt.bounce_yで接地位置を保つための補正量 |
offset_x | number | bounds_widthに対する比率 | mt.bounce_xで接触位置を保つための補正量 |
last_impact_time | number / nil | 秒 | 直前の衝突時刻。まだ衝突していない場合はnilです |
next_impact_time | number / nil | 秒 | 次に衝突する時刻。静止済みの場合はnilです |
impact_count | integer | 回 | これまでの衝突回数 |
settled | boolean | - | バウンドが終了して静止したかどうか |
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の符号は使用されず、絶対値が加速度の大きさとして扱われます。
使用例
-- 詳細設定テーブルで 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_ymt.bounce_ground(ctx, item, groundY, config?)
APIレベル: 3+
文字またはパーツ item を指定した地面 Canvas 座標 groundY(例: 0.1)に向かってドロップし、ポヨンとバウンド・着地させる簡易便利関数です。offset_y, stretch_x, stretch_y が自動適用されます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
item | table | - | 指定必須 | 変更する文字またはパーツ |
groundY | number | canvas正規化座標 | 指定必須 | 接地先のY座標 |
config | table | - | nil | 開始位置、接地基準、物理パラメータなどの設定 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
table | - | 計算済みのバウンド状態 |
変更内容
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
item.offset_y | number | canvas正規化変位 | 計算したY方向の変位を設定します |
item.offset_x | number | canvas正規化変位 | ground_mode = "absolute"の場合に、現在のcanvas上のX位置を保つ変位を設定します |
item.stretch_x / item.stretch_y | number | 倍率 | バウンド状態のSquash & Stretchを設定します |
config
| フィールド | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | ctx.time | 評価する時刻 |
delay | number | 秒 | 0.0 | 動き始めるまでの待ち時間 |
start_mode | string | - | start_y指定時は"absolute"、それ以外は"relative" | 開始位置の基準。"relative"では現在位置からdrop_heightだけ上、"absolute"ではstart_yを使用します |
start_y | number | canvas正規化位置 | nil | start_mode = "absolute"で使用する開始位置 |
drop_height | number | canvas正規化変位 | 0.3 | start_mode = "relative"で現在位置から上へ離す距離 |
ground_mode | string | - | start_modeと同じ | 接地位置の基準。"absolute"ではgroundYをcanvas上の固定位置として扱い、"relative"では上位階層の変換に追従します |
align_to | string | - | "bottom" | 接地させる位置。"bottom" / "bounds_bottom"はink boundsの下端、"baseline"は文字の横組みベースライン、"center"はink boundsの中心です。ベースラインを持たないパーツで"baseline"を指定すると下端へフォールバックします |
gravity | number | canvas正規化変位/秒² | 4.0 | 地面へ向かう加速度の大きさ |
restitution | number | - | 0.45 | 反発係数 |
start_velocity | number | canvas正規化変位/秒 | 0.0 | Y軸方向の初速 |
squash | number | 係数 | 0.15 | 衝突速度に応じて接触軸を潰す強さ |
stretch | number | 係数 | 0.02 | 移動速度に応じて進行軸を伸ばす強さ |
flexibility | number | radian/秒 | 16.0 | 衝突後に元の形へ戻る振動の速さ |
damping | number | 1/秒 | 7.0 | 衝突後の振動が収束する速さ |
ground_mode = "absolute"では、回転・スケール適用後のcanvas上の外接矩形を使って接地位置を 求めます。
使用例
-- 画面共通の一定の高さ (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 が自動適用されます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
item | table | - | 指定必須 | 変更する文字またはパーツ |
wallX | number | canvas正規化座標 | 指定必須 | 衝突先のX座標 |
config | table | - | nil | 開始位置、衝突基準、物理パラメータなどの設定 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
table | - | 計算済みのバウンド状態 |
変更内容
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
item.offset_x | number | canvas正規化変位 | 計算したX方向の変位を設定します |
item.offset_y | number | canvas正規化変位 | config.wall_mode = "absolute"の場合に、現在のcanvas上のY位置を保つ変位を設定します |
item.stretch_x / item.stretch_y | number | 倍率 | 衝突時のSquash & Stretchを設定します |
config
| フィールド | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | ctx.time | 評価する時刻 |
delay | number | 秒 | 0.0 | 動き始めるまでの待ち時間 |
start_mode | string | - | start_x指定時は"absolute"、それ以外は"relative" | 開始位置の基準。"relative"では現在位置から壁と反対方向へtravel_distanceだけ離し、"absolute"ではstart_xを使用します |
start_x | number | canvas正規化位置 | nil | start_mode = "absolute"で使用する開始位置 |
travel_distance | number | canvas正規化変位 | 0.3 | start_mode = "relative"で現在位置から壁と反対方向へ離す距離 |
wall_mode | string | - | start_modeと同じ | 衝突位置の基準。"absolute"ではwallXをcanvas上の固定位置として扱い、"relative"では上位階層の変換に追従します |
align_to | string | - | 進行方向から決定 | 接触させる位置。左から接近する場合は"right"、右から接近する場合は"left"が既定です。"bounds_right"、"bounds_left"、"center"も指定できます |
accel / acceleration | number | canvas正規化変位/秒² | 4.0 | 壁へ向かう加速度の大きさ。accelが優先されます |
restitution | number | - | 0.45 | 反発係数 |
start_velocity | number | canvas正規化変位/秒 | 0.0 | X軸方向の初速 |
squash | number | 係数 | 0.15 | 衝突速度に応じて接触軸を潰す強さ |
stretch | number | 係数 | 0.02 | 移動速度に応じて進行軸を伸ばす強さ |
flexibility | number | radian/秒 | 16.0 | 衝突後に元の形へ戻る振動の速さ |
damping | number | 1/秒 | 7.0 | 衝突後の振動が収束する速さ |
使用例
-- 画面共通の一定の位置 (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 を内部で適用済みなので、この関数は自前のタイミングで衝突を表現したいときに使います(他の文字にぶつかる、地面以外に当たる、など)。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
config | table | - | 指定必須 | 衝突時刻と変形特性の設定 |
config
| フィールド | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 0.0 | 現在時刻。impact_time未満では無変形の値を返します |
impact_time | number | 秒 | 0.0 | 衝突時刻。mt.bounce_*のlast_impact_timeを渡せます |
squash | number | 比率 | 0.15 | 潰れ量の最大値。0.2なら最も潰れた瞬間に高さが80%になります |
stiffness | number | radian/秒 | 25.0 | 元の形へ戻る速さ |
damping | number | 1/秒 | 12.0 | 振動が収束する速さ |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | 倍率 | stretchX。X方向の伸縮率 |
number | 倍率 | stretchY。Y方向の伸縮率。stretchXとは体積を保つよう逆数の関係になります |
number | bounds_heightに対する比率 | offsetCorrection。潰れて縮んだ分だけ接地位置がずれるのを補正する値です。bounds_heightに掛けてoffset_yへ加算します |
squash の名前と意味は mt.bounce_* の squash と共通です。
使用例
-- 衝突時刻を自分で決めて潰れを適用する
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_heightTIP
衝突速度に応じて潰れ具合を変えたい場合は、squash 自体を計算してください。 速度を直接渡す引数は用意していません。速度を素直に掛ける方式では、速度が少し大きいだけで 潰れ量が下限に張り付き、それ以上速くしても絵が変わらなくなるためです。下記のように 「どの速度で最大まで潰れるか」を明示するほうが、意図した範囲に収まります。
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 が「面にぶつかって跳ねる」動きなのに対し、こちらは着地しない「投げ出される」動き(破片の飛散、爆発、放り投げ)向けです。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
config | table | - | 指定必須 | 発射からの経過時間、初速、方向、重力などの設定 |
config
| フィールド | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 0.0 | 発射からの経過時間。負値は0として扱います |
speed | number | canvas正規化変位/秒 | 0.0 | 初速 |
angle | number | 度 | 0.0 | 発射方向。0は右で、正方向は時計回りです。-90で真上になります |
gravity | number | canvas正規化変位/秒² | 4.0 | 下向きの加速度 |
spin | number | 度/秒 | 0.0 | 角速度。戻り値のrotationを同名フィールドへそのまま渡せます |
drag | number | 1/秒 | 0.0 | 空気抵抗の指数減衰率。0では減衰しません |
start_x / start_y | number | canvas正規化位置 | 0.0 | 発射位置。省略時は原点からの相対変位を返します |
引数並び形式
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 0.0 | 発射からの経過時間。負値は0として扱います |
speed | number | canvas正規化変位/秒 | 0.0 | 初速 |
angle | number | 度 | 0.0 | 発射方向 |
gravity | number | canvas正規化変位/秒² | 4.0 | 下向きの加速度 |
spin | number | 度/秒 | 0.0 | 角速度 |
drag | number | 1/秒 | 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 にそのまま加算できます。
使用例
-- 破片を扇状に飛ばし、回転させながら落下させる
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+
摩擦による指数関数的減速(慣性スライド、ブレーキ、停止アニメーション)を計算します。「勢いよく入ってスーッと止まる」動きを、到達時間ではなく初速と摩擦係数という物理量で制御できます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
t | number | 秒 | 指定必須 | 経過時間。負値は0として扱います |
speed | number | canvas正規化変位/秒 | 指定必須 | 初速 |
friction | number | 1/秒 | 0.0 | 減衰率。大きいほど早く止まります |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | canvas正規化変位 | distance。それまでに進んだ距離 |
number | canvas正規化変位/秒 | currentSpeed。その時点での速度 |
最終的な移動距離は speed / friction に収束します。逆にいえば、止まってほしい距離が決まっているなら speed = distance * friction と置けます。
mt.ease.out_expo との使い分け: イージングは「決まった時間で 0→1 を進む」進行度なのに対し、こちらは初速と摩擦が独立した物理量なので、初速だけを変えて減速の質感は揃えるといった調整ができます。
使用例
-- 左から滑り込んで摩擦で止まる
local travelled = mt.friction_decay(ctx.time - startTime, 2.0, 4.0)
character.offset_x = 0.5 - 0.5 + travelledNOTE
friction が極めて小さい(1e-4 以下)場合は等速直線運動として扱います。数式上の桁落ちを避けるためで、実用上は摩擦なしと同じ挙動です。
9. 色
color の形式は概念編の「color」を参照してください。 RGBAはcolorの格納形式です。色を計算する場合は、用途に合う色空間を選択してください。
mt.color.resolve_fill(ctx, target, options?)
APIレベル: 6+
文字またはパートに適用される塗りを解決し、基本色、塗りモード、オブジェクト不透明度を 返します。OnLayoutとOnPathで使用できます。optionsなしでは対象が描画される最終的な塗りを返し、 options.levelで継承を途中の段階までに止められます(スタイルの継承を参照)。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | 現在のOnLayout / OnPath context |
target | character | part | - | 指定必須 | ctx.charsまたはctx.partsの要素 |
options | table | - | nil | (12+) { level = "global" | "character" | "part" } |
戻り値
| 値 | 型 | 単位 | 内容 |
|---|---|---|---|
color | color | - | 継承解決後の単色、またはGlobalグラデーション/Crayonの始端となるctx.global.fill.colorのコピー |
mode | string | - | "solid" / "gradient" / "crayon" / "transparent" |
opacity | number | 0-1 | Global、所有文字、対象パートの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には影響しません。
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
endColorの生成・分解・補間
以下の関数は新しい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 を設定して値を書き戻します。
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
endNOTE
shadow.use = true のパートは、個別のシャドウ色と同じく、全体のシャドウがOFFでもシャドウを落とします。
どれも OnLayout と OnPath で使え、返される色は新しいテーブルなので、変更しても元の設定には影響しません。
すべてのresolve関数の引数:
| 引数 | 型 | 単位 | 既定値 | 説明 |
|---|---|---|---|---|
ctx | table | - | 必須 | 現在のOnLayoutまたはOnPathのコンテキスト |
target | character | part | - | 必須 | ctx.chars または ctx.parts の要素 |
options | table | - | 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 | 標準的な加減速。迷ったらまずこれ |
| Quart | Cubicより急峻 |
| Sine | サイン波由来のごく緩やかな緩急 |
| Circ | 端で急激に立ち上がる円弧カーブ |
| Expo | 指数的な非常に強い緩急 |
| Back | 一度行き過ぎてから戻る(0-1の外へはみ出す) |
| Elastic | バネのように振動しながら収まる(0-1の外へはみ出す) |
| Bounce | 床で弾むようなバウンド |
BackとElasticは戻り値が0-1の範囲を超えることがある点に注意してください(それがはみ出し表現の 本体です)。
以下の関数はmt.ease.cubic_bezierを除き、すべて引数t(number、進行度、クランプなし)を1つ取りnumberを返します。cubic_bezierのシグネチャは表に併記しています。
circ系の3関数は平方根を含むため、通常はtを0-1に制限して使用します。
mt.ease.cubic_bezierの引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
x1 / y1 | number | - | 指定必須 | 第1制御点 |
x2 / y2 | number | - | 指定必須 | 第2制御点 |
t | number | - | 指定必須 | 進行度。t <= 0では0、t >= 1では1へ固定されます |
CSS互換の単調な時間曲線として使用する場合は、x1とx2を0-1にします。
使用例
-- 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も原点整列へ含まれます。可視インク輪郭間の距離を均一化する関数ではありません。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
gap | number | canvas幅比または高さ比 | 0.0 | 隣接する送りへ追加する余白。正値は進行方向の間隔を広げます |
config | table | - | nil | 再組版する方向・対象・固定位置の設定 |
config
| フィールド | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
mode | string | - | ctx.global.verticalから決定 | 再組版する方向。"horizontal"または"vertical" |
targets | table | - | 全文字 | 再組版する1始まりの文字index配列。対象間に飛ばした文字があれば、その文字の送りは計算へ含みますが座標は変更しません |
anchor | integer | - | 各行/列の先頭文字 | 現在の変形済み組版原点を固定し、その両側を並べる文字index |
targetsを省略すると、各line_indexを独立した行/列として全文字を再組版し、それぞれの 先頭文字を固定します。config.anchorを指定した場合は、その所属行だけ指定文字を固定します。
戻り値
戻り値はありません。
変更内容
対象文字のoffset_xとoffset_yを書き換えます。サイズ・回転・pivotのアニメーションを 設定した後、そのフレームの最終レイアウト処理として呼び出してください。
制約・エラー
modeには"horizontal"または"vertical"を指定します。targetsのindexは有効範囲内で厳密な昇順に並べ、重複させないでください。targetsに含める文字はすべて同じline_indexに属する必要があります。targetsを指定した場合、anchorはその配列に含まれる文字を指定します。targetsを省略した場合、anchorは有効な文字indexを指定します。
使用例
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ごとにグループ化し、ホストの読み順で返します。 横書きでは行、縦書きでは列を表します。レイアウトや文字プロパティは変更しません。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
table | - | line_indexごとのグループを組版上の行/列順に格納した配列 |
各グループは次のフィールドを持ちます。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
line_index | integer | - | グループに対応する行/列のindex |
item_count | integer | 個 | グループ内の文字数 |
items | table | - | 読み順に並んだ文字の配列 |
使用例
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
end13. 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だけが関わります
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
item | table | - | 指定必須 | 対象の文字またはパーツ |
canvasX / canvasY | number | canvas正規化位置 | 指定必須 | 配置先の座標 |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | canvas正規化変位 | 設定したoffsetX |
number | canvas正規化変位 | 設定したoffsetY |
変更内容
対象のoffset_xとoffset_yを直接更新します。
制約・エラー
変換階層内のscale * stretchが0の場合は逆変換できないため、エラーになります。
使用例
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])のいずれを渡しても自動的に判定されます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
item | table | - | 指定必須 | 対象の文字またはパーツ |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | canvas正規化位置 | アンカーのcanvasX |
number | canvas正規化位置 | アンカーのcanvasY |
使用例
-- 文字(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 | 型 | 既定値 | 内容 |
|---|---|---|---|
position | boolean | true | 3D適用前のcanvas位置を同期 |
position_delta_x / position_delta_y | number | 0.0 | sourceローカルX/Y軸に沿う変形前em単位の変位 |
rotation | boolean | true | 2D回転を同期 |
rotation_offset | number | 0.0 | 同期後の回転へ加える度数 |
size | string | "copy" | "none" / "copy" / "match_bounds" |
size_scale_x / size_scale_y | number | 1.0 | 同期後の各軸倍率。正数のみ |
depth | boolean | true | z / yaw / pitchを同期 |
z_offset | number | 0.0 | 同期後のZへ加えるcanvas比変位 |
yaw_offset / pitch_offset | number | 0.0 | 同期後に加える角度(度) |
opacity | boolean | false | opacityを同期 |
opacity_scale | number | 1.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変換には含まれません。
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 に文字またはパーツを渡すことで自動判定されます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
item | table | - | 指定必須 | 対象の文字またはパーツ |
canvasX / canvasY | number | canvas正規化位置 | 指定必須 | 配置先の座標 |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | canvas正規化変位 | 必要なoffsetX |
number | canvas正規化変位 | 必要なoffsetY |
対象のフィールドは変更しません。
制約・エラー
逆変換する親階層のscale * stretchが0の場合はエラーになります。
使用例
-- 文字を 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) が中心になります。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | canvas情報を持つコンテキスト |
canvasX / canvasY | number | canvas正規化位置 | 指定必須 | 距離を測る座標 |
centerX / centerY | number | canvas正規化位置 | 0.5 | 効果の中心 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | canvas高さ比 | アスペクト比を補正した中心からの距離 |
IMPORTANT
アスペクト比が補正されます。 Canvas の正規化座標は縦横で 1.0 の実寸が異なるため、単純に sqrt(dx² + dy²) で距離を求めると、16:9 のような横長プロジェクトでは同心円のつもりが楕円に潰れます。この関数は横方向を ctx.canvas.aspect_ratio 倍して補正するので、返る距離は常に真円基準です。
使用例
-- 中心から広がる波紋。文字ごとの距離に応じて峰が通過する
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
endmt.layout.pivot_at_2d(ctx, item, anchor)
APIレベル: 4+
文字またはパーツを自動判定し、意味的な2D位置へpivotを設定します。変更前後のローカル2D行列差を offset_x/yへ補正するため、現在のrotation、scale、stretchによる3D適用前の姿勢は移動しません。 Globalは対象外です。yaw、pitch、z、カメラ、投影後の見た目は維持対象に含みません。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
item | table | - | 指定必須 | 対象の文字またはパーツ |
anchor | string | - | 指定必須 | 設定する意味的な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単位へ変換します。
使用例
mt.layout.pivot_at_2d(ctx, character, "top")
character.rotation = math.sin(ctx.time * 3.0) * 8.014. 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変形をすべて反映します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
targets | table | nil | - | 全件 | 1始まりの文字またはパーツindex配列。nilなら対象種別の全要素 |
targetType | string | - | "character" | 対象の種類。"character"または"part" |
space | string | - | "canvas" | "canvas"または"before_global_rotation" |
戻り値(いずれか)
| 型 | 単位 | 内容 |
|---|---|---|
table | - | 有効な対象全体を囲む境界 |
nil | - | 有効な対象がない場合 |
境界tableは次のフィールドを持ちます。座標系はすべてY-upです。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
left / right | number | canvas正規化位置 | 左端と右端 |
bottom / top | number | canvas正規化位置 | 下端と上端 |
center_x / center_y | number | canvas正規化位置 | 境界の中心 |
width / height | number | canvas正規化変位 | 境界の幅と高さ |
制約・エラー
targetsを省略すると全件を指定できます。targetTypeが"character"なら 全文字、"part"なら全パートを対象にします。空table {} は全件指定ではなく、従来どおり 対象なしとしてnilを返します。
全件文字指定にはパートを持たない文字も含まれ、その文字の自然境界を使用します。全件パート 指定にはctx.partsに存在するパートだけが含まれます。不可視状態、opacity、write-onは 対象選択へ影響せず、指定対象の幾何境界を計測します。
使用例
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ならホストの字送りどおりに並びます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutのコンテキスト |
path | table | - | 指定必須 | mt.path.arc_lengthの戻り値 |
options | table | - | nil | 配置方法の設定 |
options.align | string | - | "end" | 文字列を置く位置。"end"、"start"、"center"を指定します |
options.gap | number | canvas幅比 | 0.0 | ホストの字送りへ上乗せする追加間隔 |
options.mode | string | - | "horizontal" | ホストの組版方向。"horizontal"または"vertical" |
options.target_type | string | - | "character" | 対象の種類。"character"または"part" |
options.targets | table | - | 全要素 | 読み順に並べた対象index配列 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
table | 0-1 | ctx.charsまたはctx.partsと同じindexで、各要素が占めるパス上の距離比を取得できるslots配列 |
slotsはアニメーションの進行度ではなく、パス上の位置を表します。
進行方向と読み順
スロットは進行方向に沿った距離の昇順で割り当てられます。基準は画面の左右ではなく パスの進行方向です。targetsを省略した場合はindexの昇順に割り当てるため、パスが 左から右へ進むならそのまま画面上の読み順になります。
IMPORTANT
右から左へ進むパスでは、距離の昇順が x の減少方向になります。 そのためtargetsを 省略すると文字1が最も右、文字Nが最も左に置かれ、画面上では文字列が逆転して見えます。 左から右に読める配置にしたい場合は、targetsを読み順の逆で渡してください。
-- 右から左へ進むパスで、画面上の読み順を保つ
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"で末尾が来る位置 |
|---|---|
| 左→右 | 画面右側 |
| 右→左 | 画面左側 |
使用例
-- 用途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-- 用途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)
endNOTE
文字列の総長がパス全長を超える場合、距離比が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曲線上の座標と接線を返します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
p0 | table | 座標 | 指定必須 | 始点{ x, y } |
p1 | table | 座標 | 指定必須 | 始点側の制御点{ x, y } |
p2 | table | 座標 | 指定必須 | 終点側の制御点{ x, y } |
p3 | table | 座標 | 指定必須 | 終点{ x, y } |
t | number | 0-1 | 指定必須 | 曲線上の位置。範囲外はクランプされず、そのまま外挿されます |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | 入力座標に準拠 | 曲線上のx |
number | 入力座標に準拠 | 曲線上のy |
number | 入力座標に準拠 | 接線のtangentX |
number | 入力座標に準拠 | 接線のtangentY |
使用例
-- 文字が弧を描いて自分の自然な位置へ着地する
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 = ymt.path.catmull_rom(points, t)
APIレベル: 1+
任意個数の制御点を通るCatmull-Romスプライン上の座標と接線を返します。Bézierと違い、 リストに並べた点すべてを厳密に通過する曲線になります。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
points | table | 座標 | 指定必須 | 1始まりの通過点配列。{ x, y }を2個以上並べます |
t | number | 0-1 | 指定必須 | 曲線全体を通した進行度。0-1にクランプされます |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | 入力座標に準拠 | 曲線上のx |
number | 入力座標に準拠 | 曲線上のy |
number | 入力座標に準拠 | 接線のtangentX |
number | 入力座標に準拠 | 接線のtangentY |
制約・エラー
pointsには2個以上の点が必要です。
使用例
-- あらかじめ決めた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 = ymt.path.arc_length(points, aspectRatio?, options?)
APIレベル: 3+
制御点から弧長パラメータ化されたパスを構築します。上記2関数は曲線パラメータtで 評価しますが、tの等間隔は距離の等間隔ではありません。曲線が曲がっている所ではサンプルが 詰まるため、「距離で間隔を取る」用途(隊列、パス上の字送り、等速移動)では必ず累積長テーブルが 必要になります。この関数がそれを1度だけ構築し、距離での参照を提供します。
aspectRatioにctx.canvas.aspect_ratioを渡すと、x方向の差分に掛けて距離の意味を縦横で 揃えます。省略すると正規化単位そのままで測るため、非正方canvasでは間隔が伸び縮みします。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
points | table | 座標 | 指定必須 | 1始まりの制御点配列。canvas正規化座標で指定するとmt.layout.place_2dやmt.layout.queue_on_pathと組み合わせられます |
aspectRatio | number | - | 1.0 | X方向の距離へ掛けるアスペクト比。通常はctx.canvas.aspect_ratioを渡します |
options | table | - | nil | 曲線の種類を指定する設定 |
options.kind | string | - | "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を加算します。
-- 右から左へ進むパスで文字を正立させる
character.rotation = heading + 180.0使用例
-- 距離で等間隔に配置する(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)
end17. パスの作成・編集
mt.svg_path(source, optionsOrSourceUnitsPerEm?)
APIレベル: 5+
SVGの d 属性と同じ文字列を、再利用可能な読み取り専用パステンプレートへ変換します。 簡易SVG互換として、絶対・相対の M / L / H / V / Q / T / C / S / Z と 連続する座標組を扱います。楕円弧 A / a は未対応です。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
source | string | - | 指定必須 | SVGのパスデータ |
optionsOrSourceUnitsPerEm | number / 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を使用します。
使用例
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
endIMPORTANT
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 })などへ渡せます。
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で作成したテンプレートの内容へ置き換えます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
template | MtDrawingPath | - | 指定必須 | コピー元のパステンプレート |
戻り値
戻り値はありません。
変更内容
対象のパスデータと座標の正規化設定を、テンプレートの内容へ置き換えます。
path:set_svg(source)
APIレベル: 5+
SVGのパスデータを解析し、対象のパスを置き換えます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
source | string | - | 指定必須 | SVGのd属性と同じ形式のパスデータ |
戻り値
戻り値はありません。
変更内容
対象のパスを指定したSVGパスへ置き換え、座標の正規化設定を初期値へ戻します。
path:move_to(x, y)
APIレベル: 5+
指定した座標を始点とする新しいサブパスを追加します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
x / y | number | パスローカル座標 | 指定必須 | サブパスの始点 |
戻り値
戻り値はありません。
変更内容
対象のパスへmoveコマンドを追加します。
制約・エラー
座標は有限の数値である必要があります。
path:line_to(x, y)
APIレベル: 5+
現在位置から指定した座標までの直線を追加します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
x / y | number | パスローカル座標 | 指定必須 | 直線の終点 |
戻り値
戻り値はありません。
変更内容
対象のパスへlineコマンドを追加します。
制約・エラー
座標は有限の数値である必要があります。
path:quad_to(cx, cy, x, y)
APIレベル: 5+
現在位置から指定した終点までの2次Bézier曲線を追加します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
cx / cy | number | パスローカル座標 | 指定必須 | 制御点 |
x / y | number | パスローカル座標 | 指定必須 | 曲線の終点 |
戻り値
戻り値はありません。
変更内容
対象のパスへquadratic Bézierコマンドを追加します。
制約・エラー
座標は有限の数値である必要があります。
path:cubic_to(cx1, cy1, cx2, cy2, x, y)
APIレベル: 5+
現在位置から指定した終点までの3次Bézier曲線を追加します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
cx1 / cy1 | number | パスローカル座標 | 指定必須 | 現在位置側の制御点 |
cx2 / cy2 | number | パスローカル座標 | 指定必須 | 終点側の制御点 |
x / y | number | パスローカル座標 | 指定必須 | 曲線の終点 |
戻り値
戻り値はありません。
変更内容
対象のパスへ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中の再入・変更、 有限でない戻り値はエラーになり、パスは変更されません。
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とは同一概念では ありません。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
text | string | - | 指定必須 | 対象の文字列 |
startChar | integer | - | 指定必須 | 切り出し開始コードポイントindex。1始まりで、この位置を含みます |
endChar | integer | - | 末尾 | 切り出し終了コードポイントindex。1始まりで、この位置を含みます |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
string | - | 指定範囲を切り出した文字列。範囲が空または無効な場合は空文字列 |
mt.text.classify(text)
APIレベル: 4+
テキストクラスタの先頭Unicodeコードポイントを、アニメーションで扱いやすい文字種名へ分類します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
text | string | - | 指定必須 | 分類するテキストクラスタ |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
string | - | "kanji"、"hiragana"、"katakana"、"punctuation"、"latin"、"digit"、"space"、"other"のいずれか |
使用例
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を持つ文字を返します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutまたはOnPathのコンテキスト |
specification | string | - | 指定必須 | 指定文字列 |
options | table | - | nil | { empty = "none" | "all" }。何も選ばない文字列の扱い。"none"(既定)は何も選ばず、"all"はすべての文字を選びます。"all"でも除外は有効です |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
integer[] | - | 昇順の文字番号(ctx.charsのindex)。ipairsでそのまま回せます |
例
function OnLayout(ctx)
for _, characterNumber in ipairs(mt.target.chars(ctx, "1-3, 6, !c2")) do
ctx.chars[characterNumber].scale = 1.2
end
endmt.target.parts(ctx, specification, options?)
APIレベル: 13+
指定文字列をグローバルパーツ番号に解決します。文法はmt.target.charsと同じで、数字だけの指定がパーツを表す点だけが異なります。c3のような文字の指定は、その文字のすべてのパーツを選びます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | OnLayoutまたはOnPathのコンテキスト |
specification | string | - | 指定必須 | 指定文字列 |
options | table | - | nil | { empty = "none" | "all" }。何も選ばない文字列の扱い。"none"(既定)は何も選ばず、"all"はすべてのパーツを選びます。"all"でも除外は有効です |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
integer[] | - | 昇順のグローバルパーツ番号(ctx.partsのindex)。ipairsでそのまま回せます |
例
function OnLayout(ctx)
for _, partNumber in ipairs(mt.target.parts(ctx, "c1 p9")) do
ctx.parts[partNumber].opacity = 0.5
end
end20. クリップ時間
mt.timeline.progress(ctx, fallbackDuration?)
APIレベル: 1+
現在の進行度(0から1)を取得します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | コンテキスト |
fallbackDuration | number | 秒 | 4.0 | タイムラインを取得できない場合にループさせる仮想クリップ長 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | 現在の進行度 |
制約・エラー
タイムラインを取得できない場合、fallbackDurationには正数を指定します。
mt.timeline.duration(ctx, fallbackDuration?)
APIレベル: 6+
ホストから取得した正のクリップ長を秒で返します。ホストタイムラインを利用できない場合、 または取得した秒数が有限の正数でない場合は、指定したフォールバック時間を返します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | コンテキスト |
fallbackDuration | number | 秒 | 4.0 | タイムラインを取得できない場合の仮想クリップ長 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 秒 | ホストのクリップ長、またはフォールバック時間 |
制約・エラー
明示するfallbackDurationは有限の正数である必要があります。window_ctxが返す派生contextを 渡した場合は、その時間窓のdurationを返します。
local clipDuration =
mt.timeline.duration(ctx, kFallbackClipLength)mt.timeline.remaining(ctx, fallbackDuration?)
APIレベル: 1+
クリップ終端までの残り実秒を返します。アウトロ(退場アニメーション)を終端アンカーの 実時間で書くための基礎部品です(ctx.timelineの設計ルール参照)。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | コンテキスト |
fallbackDuration | number | 秒 | 4.0 | タイムラインを取得できない場合にループさせる仮想クリップ長 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 秒 | クリップ終端までの残り時間 |
使用例
-- クリップ長にかかわらず、最後の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 より短い場合のみ、 両区間を比例圧縮してクリップ内に収めます(自動早送り)。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | コンテキスト |
introSeconds | number | 秒 | 指定必須 | イントロの長さ。負値は0として扱います |
outroSeconds | number | 秒 | 指定必須 | アウトロの長さ。負値は0として扱います |
fallbackDuration | number | 秒 | 4.0 | タイムラインを取得できない場合の仮想クリップ長 |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | introProgress。イントロの進行度 |
number | 0-1 | outroProgress。アウトロの進行度 |
使用例
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を返します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | 時間を読み取るコンテキスト |
start | number | 秒 | 指定必須 | コンテキスト内での開始時間 |
duration | number | 秒 | 指定必須 | 時間窓の長さ |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | 開始前と終了後をクランプした時間窓内の線形進行度 |
制約・エラー
ctx.timeは数値である必要があります。startは有限の数値である必要があります。durationは有限の正数である必要があります。
使用例
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から引き継ぎます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | 元のコンテキスト |
start | number | 秒 | 指定必須 | 元のコンテキスト内での開始時間 |
duration | number | 秒 | 指定必須 | 時間窓の長さ |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
table | - | 時間関係を指定窓へ再マッピングした派生コンテキスト |
制約・エラー
ctx.timeは数値である必要があります。startは有限の数値である必要があります。durationは有限の正数である必要があります。
使用例
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値にできます。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | 元のコンテキスト |
initialValue | 任意 | - | 指定必須 | 最初の区間へ渡す初期値 |
segments | table | - | 指定必須 | アニメーション区間または保持区間の配列 |
options | table | - | nil | タイムラインを取得できない場合の設定 |
options.fallback_duration | number | 秒 | 4.0 | 仮想クリップ長 |
戻り値
| 型 | 単位 | 内容 |
|---|---|---|
| 任意 | - | 現在時刻まで評価した最後の区間の値 |
使用例
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.time | number | 秒 | 区間開始からの時間 |
segmentCtx.frame | number | frame | 区間開始からのフレーム数 |
segmentCtx.fps | number | fps | 呼び出し元と同じフレームレート |
segmentCtx.timeline.duration_seconds | number | 秒 | 区間の論理duration |
segmentCtx.timeline.duration_frames | number | frame | 区間の論理durationをフレーム換算した値 |
segmentCtx.timeline.progress | number | 0-1 | 区間内の進行度 |
区間の形式
各区間は次のいずれかの形式です。
| 区間 | 指定 | 動作 |
|---|---|---|
| 固定長アニメーション | { duration = 秒数, evaluate = 関数 } | evaluate(segmentCtx, previousValue) の戻り値を使用 |
| 固定長保持 | { hold = 秒数 } | 関数を呼ばず、直前の値を保持 |
| 可変長アニメーション | { duration = "remaining", evaluate = 関数 } | 固定区間を除いた残りのクリップ尺を使用 |
| 可変長保持 | { hold = "remaining" } | 残りのクリップ尺で直前の値を保持 |
"remaining"は1つのchain内で1区間だけ指定できます。その後ろに固定長のアウトロを置くと、 可変区間だけがクリップ尺の変更を吸収し、アウトロは常にクリップ終端で完了します。
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方向を使う旧形式の極座標変換です。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
angleDegrees | number | 度 | 指定必須 | 方向。0度は右で、正方向は時計回りです |
radius | number | 変位 | 指定必須 | その方向への距離 |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | radiusに準拠 | offsetX |
number | radiusに準拠 | screenOffsetY。画面基準で下が正です |
WARNING
非推奨です。mt.polar_offset_2d を使用してください。 引数は mt.polar_offset_2d と同じですが、戻り値が角度系(Y は下が正)のため、offset_y へ渡す際に符号の反転が必要でした。反転を忘れると上下だけが逆に動くという取り違えが起き やすいため、位置系で返す mt.polar_offset_2d に置き換えています。動作は変更していないので 既存のスクリプトはそのまま動作します。
使用例
-- 旧: 呼び出し側で反転が必要
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 + dymt.layout.retypeset(ctx, gap?, config?) 非推奨
APIレベル: 1+
CAUTION
API Level 1互換関数です。新規コードではmt.layout.reflowを使用してください。
文字ごとの個別のscaleやstretchを考慮し、geometry.advance_x/yを使って簡易的に 字送りを再計算します。可視インク境界間の隙間を均一にする関数ではありません。 文字ごとのサイズアニメーションを適用した後、そのフレームの最終再組版処理として呼び出します。 rotation、個別pivot、tracking、margins、変形後の輪郭は送り計算に含みません。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | コンテキスト |
gap | number | canvas幅比または高さ比 | 0.0 | advance間へ追加する余白 |
config | table | - | nil | 再整列の設定 |
config.align | string | - | "baseline" | 横書き時の交差軸整列。"baseline"、"top"、"center"、"bottom" |
config.mode | string | - | "horizontal" | "horizontal"または"vertical" |
config.targets | table | - | 全文字 | 再整列する1始まりの文字index配列。対象外の文字は変更しません |
config.anchor | integer | - | targetsの最小index | 送り軸の現在位置を固定する文字index |
config.baseline | string | - | "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)を確保してください。
使用例
-- インデックス 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 を計算します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
resolvedGlobal | table | - | 指定必須 | OnPreLayoutで確定済みのctx.global |
canvasWidth / canvasHeight | number | px | 指定必須 | ctx.canvas.widthとctx.canvas.height |
naturalCenterX / naturalCenterY | number | canvas正規化位置 | 指定必須 | 対象の自然中心。文字ではgeometry.bounds_center_x/y、パーツではgeometry.canvas_center_x/y |
canvasX / canvasY | number | canvas正規化位置 | 指定必須 | 配置先の座標 |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | canvas正規化変位 | offsetX |
number | canvas正規化変位 | offsetY |
制約・エラー
この関数が反転するのはposition_x/y、rotation、scale、stretch_x/y、 pivot_x/yだけです。文字・パーツの個別rotation/pivot、所有文字からパーツへの階層変形、 global/個別の3D値、camera、projection、Deformは反転しません。幅・高さおよび global.scale * stretch_x/yは非ゼロでなければなりません。
使用例
-- 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位置と一致します。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
item | table | - | 指定必須 | 対象の文字またはパーツ |
canvasX / canvasY | number | canvas正規化位置 | 指定必須 | 配置先の座標 |
ctx | table | - | nil | 指定するとctx.globalの2D変形だけを逆算します |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | canvas正規化変位 | 設定したoffsetX |
number | canvas正規化変位 | 設定したoffsetY |
変更内容
対象のoffset_xとoffset_yを直接更新します。
使用例
-- 文字の自然中心を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を書いた後に呼び出してください。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
ctx | table | - | 指定必須 | レイアウトコンテキスト |
targets | table | - | 指定必須 | 1始まりの対象index配列 |
targetType | string | - | "character" | "character"または"part" |
戻り値(いずれか)
| 型 | 単位 | 内容 |
|---|---|---|
table | - | 近似境界 |
nil | - | 有効な対象がない場合 |
境界tableは次のフィールドを持ちます。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
left / right / bottom / top | number | canvas正規化位置 | 上記の変形段階における近似境界 |
center_x / center_y | number | canvas正規化位置 | グループの中心 |
width / height | number | canvas正規化変位 | グループ全体の幅と高さ |
使用例
-- インデックス 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)
endmt.timeline.intro_outro(progress, introFraction, outroFraction) 非推奨
APIレベル: 1+
全体進行度から、最初(イントロ)と最後(アウトロ)の区間それぞれの進行度を個別に抽出して返します。
WARNING
非推奨: 割合ベースのトランジションはクリップの尺に比例して伸び縮みするため、 尺を伸ばすとフェードがスローモーション化します。固定速度で進む mt.timeline.intro_outro_seconds を使ってください (ctx.timelineの設計ルール参照)。
引数
| 引数 | 型 | 単位 | 省略時 | 内容 |
|---|---|---|---|---|
progress | number | 0-1 | 指定必須 | 全体進行度。通常はmt.timeline.progressから取得します |
introFraction | number | 0-1 | 指定必須 | イントロとして扱う全体尺の割合 |
outroFraction | number | 0-1 | 指定必須 | アウトロとして扱う全体尺の割合 |
戻り値(多値)
| 型 | 単位 | 内容 |
|---|---|---|
number | 0-1 | introProgress。イントロの進行度 |
number | 0-1 | outroProgress。アウトロの進行度 |