LUA SCRIPTING API
APIリファレンス
Mug TypographyのLuaスクリプトから利用できるコールバック、ctxオブジェクト、座標系、mt.*ユーティリティの完全な仕様です。
オフラインでも参照できます
同じAPI仕様書を、配布ZIPの scripting-simulator/docs/ にも同梱しています。
Mug Typography のスクリプティングは、プラグインの Script Text に書いた Lua 5.4 スクリプトで テキストレイアウトと文字・パーツのアニメーションを制御する機能です。開発環境として、VSCode 拡張 「Mug Typography Scripting Simulator」(MT Sim) と、インストール不要でブラウザから使える オンラインシミュレーターを利用できます。 どちらもホストアプリを起動せずにスクリプトをプレビュー・デバッグできます。
1. 基本モデル
スクリプトには最大3つのコールバック関数を定義します。どれも省略可能で、定義しなかった コールバックは単にスキップされます。
フレーム評価パス(毎フレーム)
毎フレーム
└─ OnPreLayout(ctx)
レイアウト・全体・カメラの基礎値を変更、図形・カスタムグリフを宣言
↓
文字・パーツのレイアウト生成
↓
OnLayout(ctx)
生成された文字・パーツ・図形を個別に調整
↓
OnPath(ctx)
選択したパーツ・図形の輪郭を調整
↓
描画重要なのは、各コールバックで実行されるタイミングと操作できる対象が異なることです。 目的に合う段階のコールバックだけを定義します。
OnPreLayoutは毎フレームのレイアウト生成前に実行されます。テキスト、フォント、字送り、全体設定、カメラなど、文字・パーツの生成条件を変更し、図形やカスタムグリフを宣言しますOnLayoutは文字・パーツの生成後に実行されます。生成された各要素や図形の位置、回転、色などを調整しますOnPathは個別調整後、描画前に実行されます。選択したパーツや図形の輪郭を置換・再構築します
後段のコールバックでは、前段で確定した値を参照できます。ただし、処理済みの段階へ戻って 値を書き換えることはできません。たとえば OnLayout から ctx.global や ctx.camera は 参照できますが、変更はできません。
変更はフレーム内でのみ有効
ctx は毎フレーム、ホストのInspector値から作り直された状態 でコールバックに渡されます。 コールバックで書き込んだ値はそのフレームの描画にだけ使われ、次のフレームではまたInspector値 から再スタートします。Inspectorやキーフレームへ書き戻されることもありません。
たとえば ctx.global.rotation = ctx.global.rotation + 1.0 は「毎フレーム1度ずつ回り続ける」 のではなく、「常にInspector値+1度」になります。Inspectorの回転を基準に回転を進める場合は、 ctx.global.rotation = ctx.global.rotation + ctx.time * 20.0 のように、ctx.timeから求めた フレーム独立な差分を現在値へ加えます。ctx.global.rotation = ctx.time * 20.0と直接代入する書き方は、 Inspectorの回転を意図的に完全上書きする場合だけ使用します。
2. フレーム独立性の要件(ステートレス実行)
ホストはフレームを時系列順に評価するとは限りません。スクラブ、逆再生、キャッシュ、並列レンダーの どの場合でも同じ結果になる必要があります。各フレームの結果は現在の入力値だけから決まり、 前フレームの結果やフレームの評価順序に依存してはいけません。本書では、この性質を フレーム独立性 と呼びます。
- グローバル変数や関数の外側で宣言した
local変数を書き換える場合は、同一フレーム内のコールバック間で値を渡す用途に限り、毎フレーム現在の入力値から上書きする。前フレームの値を読み継いだり累積したりしない ctxやctx.chars[index]などの参照をコールバック終了後まで保持しない- 文字数、パーツ数、特定フォントの形状を固定値として仮定しない
- 逐次シミュレーションではなく、
ctx.timeからそのフレームの値を直接求める - 文字・パーツの走査は必ず
ctx.char_count/ctx.part_countを使う
スクリプトメタデータ
スクリプトファイルの先頭に、Luaのコメントとして @<name> <value> を記述すると、必要なAPI、 MT Simの動作、初期設定、Script Inputsを宣言できます。メタデータはコールバック内で実行される Lua APIではありませんが、@api_level・@input・@time_independentはホストプラグインも解釈します。
スクリプトの認識と実行設定
| 記述 | 内容 |
|---|---|
@MugTypography | ファイルの1行目から始まる連続した -- 単一行コメント内(MT Simでは先頭から5行以内)に置くと、Mug Typography用スクリプトとして認識されます。入力補完・シミュレーター連携・ホストでの @input 認識に必要で、配布サンプルにも必ず1行目に含まれます。@mt または @mug も使用できます |
@duration <秒数> | シミュレーターの初期再生時間を設定します。例: @duration 5.0 |
@required 3d | シミュレーター起動時に3D投影設定(Enable 3D projection)を有効にします。3dprojection も使用できます |
推奨初期設定
@recommend <設定> は、スクリプトの演出に特定の初期条件が必要な場合だけ使用します。 指定は必要最低限にしてください。テキスト、位置、背景などをむやみに指定すると、表示結果が スクリプトによるものか、Inspectorの初期設定によるものか分かりにくくなります。 任意の設定で成立するスクリプトでは使用しません。
| 記述 | 内容 |
|---|---|
@recommend bg <指定> | 背景の初期値。#RRGGBB / #RRGGBBAA で単色、checkerboard / checker でチェッカー背景、solid でチェッカーを明示的に解除します。色とモードを同じ行にも書けます。例: @recommend bg checkerboard #ffffff |
@recommend fill <色> | グローバル塗り色の初期値。#RRGGBB / #RRGGBBAA で指定します。例: @recommend fill #d8d4f2 |
@recommend gradient <色> | Gradient End Colorの初期値。グラデーションがnoneでも、スクリプト用の第2色として使用できます。例: @recommend gradient #ff4f9a |
@recommend pos <X> <Y> | グローバル文字位置の初期値。Xは大きいほど右、Yは大きいほど上です。例: 中央は @recommend pos 0.5 0.5、画面下部は @recommend pos 0.5 0.18 |
@recommend text "<文字列>" | Textの初期値。"..." または '...' で囲みます。\n は改行、\" \' \\ は各文字そのものになります。例: @recommend text 'ゆれる\nもじ'。"" にするとTextを空にして始めます(本文を使わない全画面の背景向け) |
@recommend vertical <boolean> | 文字方向の初期値。trueで縦書き、falseで横書き。読み込み時に適用し、その後のInspector変更を尊重します |
@recommend lang <言語コード> | 対応言語のフォントを自動選択します。例: @recommend lang ja。text から言語を推定できる場合は省略でき、明示した値は自動判定より優先されます |
シミュレーターの Reset ボタンを押した場合も、これらの推奨初期設定が適用されます。 VS Code拡張機能とオンラインシミュレーターでは、bg / fill / gradientのHEX値に 色見本が表示されます。色見本を選択すると、標準のカラーピッカーから値を変更できます。
Script Inputs
Script InputsはAPI Level 8以降で利用できます。 @inputは、InspectorのScript Inputsに表示するslot、表示名、任意の初期値を宣言します。 構文は次のとおりです。
@input <type> <index> "<label>" [default=<value>]-- @input number 1 "Amplitude" default=15.0
-- @input number 2 "Speed" default=1.0
-- @input color 1 "Primary Color" default={1.0, 0.4, 0.2, 1.0}
-- @input text 1 "Caption" default="Hello"
-- @input boolean 1 "Enable Glow" default=true| type | index | Luaからの参照 | default省略時 |
|---|---|---|---|
number | 1〜14 | ctx.inputs.numbers[index] | 0.0 |
color | 1〜8 | ctx.inputs.colors[index] | {1.0, 1.0, 1.0, 1.0} |
text | 1〜4 | ctx.inputs.texts[index] | 空文字列 |
boolean | 1〜8 | ctx.inputs.booleans[index] | false |
booleanはAPI Level 10以降で利用できます。defaultはtrueまたはfalseだけを受け付けます。
- typeはASCIIの大文字・小文字を区別しません。slotの表示順は宣言順ではなく、Number、Color、Text、Booleanのindex順です
- labelは1〜64 UTF-8 bytesで、
\"と\\だけをescapeできます - Numberのdefaultは
-1000000.0〜1000000.0の有限数、Colorは各channelが0.0〜1.0のRGBA 4要素、TextはNULを含まない4096 UTF-8 bytes以下の単一行文字列です - 同じtype/indexの重複、未知type、範囲外index、不正なquote・escape・default・余分なtokenはメタデータエラーです。エラー時は直前の有効なInspector表示を維持し、
Script StatusにInput line <行番号>: <内容>を表示します(Luaのcompile・実行は妨げません) - 宣言されたslotだけがInspectorに表示されます。宣言がなければ
Script Inputsグループ全体が隠れます。Luaでは未宣言slotを含む固定長配列を常に読み取れます - Script Text変更時、新規slotまたは実効defaultが変わったslotだけに初期値を適用します。labelだけの変更では値とキーフレームを維持します
- キーフレームがあるslotへdefaultを上書きしません。プロジェクト読込み時は保存済みの値とキーフレームを維持し、metadataのdefaultを再適用しません
時間非依存の宣言
-- @time_independent(値なし)を宣言すると、Inspector値が同じフレーム間で描画結果を再利用し、このスクリプトをホストへの時間依存通知から除外します。
-- @time_independent は先頭の連続する -- コメント内に置いてください(空行・字下げ・本文・ブロックコメントより前)。省略時は従来どおり時間依存です。これは作者の契約で、自動解析は行いません。ctx.time、ctx.frame、タイムライン情報、呼び出し回数や外部状態などに結果が依存する場合は宣言しないでください。Inspector値(@input のキーフレームを含む)、スクリプト本文、描画サイズの変更は引き続き再描画の対象です。Pulseなど他の時間依存エフェクトは通知・再描画の対象のままです。シミュレーターは宣言を読み取りますが、プレビューのフレーム評価は継続します。
サンプルブラウザの表示情報
Web版シミュレーターのサンプルブラウザに表示する情報です。省略した場合、タイトルにはファイル名が 使われ、作者・バージョン・APIレベルは表示されません。
| 記述 | 内容 |
|---|---|
@title <表示名> | カードに表示するタイトル。例: @title Callback Flow Basics |
@author <作者名> | 作者名。例: @author Mug |
@version <バージョン> | スクリプトのバージョン。例: @version 1.0 |
@api_level <数値> | スクリプトが必要とするAPIレベル。例: @api_level 6。新しいAPIレベルを宣言したスクリプトは、未対応のプラグインでは読み込まれません |
@animation_id | 同梱サンプルの固定ID(所属ジャンルの英大文字3文字+3桁の連番、例: FAD002)。ブラウザに表示し、IDで検索できます。ご自身のスクリプトには書かなくて構いません |
@description | ブロックコメント内の複数行の説明文。@description 直後の改行は無視されます |
@description.<locale> | サンプル説明の翻訳(例: @description.ja、@description.en)。表示言語の翻訳がなければ@descriptionを使用。検索は全言語の説明を対象にします |
記述例
-- @MugTypography
-- @duration 5
-- @title Callback Flow Basics
-- @author Mug
-- @version 1.0
-- @api_level 8
-- @input number 1 "Amplitude" default=15.0
--[[ @description
Reference: callback execution timing and the frame-independent
scripting contract.
]]記述位置と解析範囲
@MugTypography および @duration / @required / @recommend / @input / @title / @author / @version / @time_independent / @api_level は、 ファイルの1行目から始まる連続した -- 単一行コメントの範囲内に記述してください。 @description のブロックコメントや、コメントではない行(空行・字下げした行を含む)に達した時点で解析範囲は 終了します。そのため、単一行のメタデータは@descriptionより前に書いてください。 複数の@recommend行にも、1行へ複数設定を書いた形式にも対応します。生成コードでは@MugTypographyを1行目、 その他のメタデータ・説明文をその直後に置いてください。
3. コールバック
| コールバック | 呼ばれるタイミング | 主な用途 |
|---|---|---|
OnPreLayout(ctx) | レイアウト生成前(毎フレーム) | 文字・パーツの生成条件と全体設定の変更、図形・カスタムグリフの宣言 |
OnLayout(ctx) | レイアウト生成後(毎フレーム) | 生成された文字・パーツ・図形の個別調整 |
OnPath(ctx) | OnLayout 後(毎フレーム) | 選択したパーツ・図形の輪郭の置換・再構築 |
OnPreLayout / OnLayout で参照・変更できるフィールドは、 ctx リファレンスを参照してください。OnPath のフィールドは§3.3で説明します。
3.1 OnPreLayout(ctx)
| 項目 | 内容 |
|---|---|
| シグネチャ | function OnPreLayout(ctx) |
| 引数 | ctx: table。レイアウト生成前のコンテキスト |
| 戻り値 | なし。値を返しても無視される |
| 実行タイミング | 毎フレーム、文字・パーツのレイアウト生成前 |
| 主な変更対象 | ctx.global / ctx.camera / ctx.shapes:declare / ctx.shape_cameras:declare / ctx.glyphs:declare |
| エラー時 | ホストでは後続コールバックを実行せず、そのフレームを描画しない(MT Simでは元の値でプレビューを継続) |
ホストパラメーターから作られた全体設定の作業コピーを受け取り、レイアウト生成前の値を変更します。
TIP
スケール調整の設計ルール: テキストの長さや文字数に合わせて全体のサイズを調整する(画面外へのはみ出しを防ぐなど)ときは、OnLayout の中で各文字の character.scale を縮めるのではなく、OnPreLayout で ctx.global.scale をあらかじめ調整してください。そうすることで、タイプライター演出のように文字が1文字ずつ増えていく途中でも、文字数に合わせて全体サイズがガタつくのを防げます。
時間軸(実秒数 vs 進行度)の設計ルールは ctx.timeline を参照してください。
3.2 OnLayout(ctx)
| 項目 | 内容 |
|---|---|
| シグネチャ | function OnLayout(ctx) |
| 引数 | ctx: table。レイアウト生成後のコンテキスト |
| 戻り値 | なし。値を返しても無視される |
| 実行タイミング | 毎フレーム、文字・パーツのレイアウト生成後 |
| 主な変更対象 | ctx.chars[index] / ctx.parts[index] / ctx.shapes[index] / ctx.shape_cameras[index] / ctx.bounding_box / ctx.output |
| エラー時 | ホストでは OnPath を実行せず、そのフレームを描画しない(MT Simでは未変更のレイアウトでプレビューを継続) |
確定した全体設定から生成された文字・パーツ・図形を調整します。文字数とパーツ数はこの時点で確定しています。
3.3 OnPath(ctx)
| 項目 | 内容 |
|---|---|
| シグネチャ | function OnPath(ctx) |
| 引数 | ctx: table。パス編集用コンテキスト |
| 戻り値 | なし。値を返しても無視される |
| 実行タイミング | 毎フレーム、OnLayout の後、変形・投影・描画の前 |
| 主な変更対象 | ctx.paths から取得したパーツ・図形の path |
| エラー時 | ホストではそのフレームを描画しない(MT Simでは元のグリフ輪郭でプレビューを継続) |
ctx.paths の part / character / select / shape を使って対象パーツを取得し、その path を編集します。 取得方法と編集APIの詳細は、ctx リファレンスを 参照してください。
3.4 完全なスクリプト例
-- @MugTypography
-- @api_level 8
-- Base phase: values that determine layout and global inheritance.
function OnPreLayout(ctx)
ctx.global.tracking = mt.wave(ctx.time, 0.25, 0.0) * 0.05
ctx.global.rotation = mt.wave(ctx.time, 0.1, 0.0) * 5.0
end
-- Layout phase: adjust only the generated characters and parts.
function OnLayout(ctx)
for index = 1, ctx.char_count do
local character = ctx.chars[index]
local progress = mt.stagger(ctx.time, index, 0.06, 0.35)
character.offset_y = 0.5 + (1.0 - mt.ease.out_cubic(progress)) * 0.15
character.rotation = character.rotation + mt.wave(ctx.time, 0.5, index * 0.25) * 3.0
end
for index = 1, ctx.part_count do
local part = ctx.parts[index]
part.scale = part.scale * (1.0 + mt.random(42, index) * 0.05)
end
endより実践的な例は、配布物に同梱されている samples/ を参照してください。 samples/reference/ は基本モデルと各APIをジャンル別に学べる短いサンプル、 samples/showcase/ は完成されたアニメーション集です。
4. 型と座標系
4.1 座標・単位の定義
公開 number フィールドは、次のいずれかの単位系に属します。
X 成分は canvas 幅、Y 成分は canvas 高さを 1 とします。Y は上方向が正です(§4.3)。
canvas 正規化座標(位置)
canvas 上の位置を表します。値 0.5 は当該軸における canvas 中央です。
| フィールド | 定義 |
|---|---|
ctx.global.position_x / position_y | 全体の位置。書き込み可(OnPreLayout) |
ctx.global.pivot_x / pivot_y | global.position を基準とする全体変形の支点の変位。書き込み可(OnPreLayout) |
geometry の canvas 座標(bounds_center_* 等) | 変形前レイアウトにおける読み取り専用の位置。文字・パーツごとに異なります |
canvas 正規化変位(中立値 0.5)
レイアウトが決めた自然位置に対する変位を表します。絶対位置ではありません。中立値は 0.5 であり、 描画時の変位量は次式で解釈されます。
変位量(canvas 比) = value - 0.5変位量の基準は canvas 幅または高さであり、文字サイズや geometry.advance_* ではありません。
| フィールド | 定義 |
|---|---|
文字・パーツの offset_x / offset_y | 自然位置からの平行移動。0.5 のとき変位量は 0 であり、レイアウトが決めた位置(変形前中心は geometry.bounds_center_*)に留まります。0.5 より大きいと右/上へ平行移動します。2D canvas目標位置への配置にはmt.layout.place_2dを使います |
global.pivot_x / global.pivot_y | 回転・スケールの支点の、global.position からの変位。0.5 のとき支点は global.position に一致します |
文字・パーツの pivot_x / pivot_y | 回転・スケールの支点の、自然中心からの変位。0.5 のとき支点は自然中心(文字は geometry.bounds_center、パーツは自然位置)に一致します |
位置と変位の対応:
| 種別 | 対象 | 値の意味 | 中立 / 中央 |
|---|---|---|---|
| 位置 | global.position_*、geometry の canvas 座標 | canvas に対する座標 | 0.5 = canvas 中央 |
| 変位 | global.pivot_*、文字・パーツの offset_* / pivot_* | global.position、自然位置、自然中心のいずれかを基準とする差分 | 0.5 = 差分ゼロ |
その他の単位系
| 単位系 | フィールド | 定義 |
|---|---|---|
| em | tracking、margins、stroke.width、stroke.gap、shadow.distance | フォントサイズに対する比率。1.0 = 1 em。ストロークは描画時に fontSize を掛ける |
| fontSize 百分率 | bounding_box.width / margin_* / corner_radius / fill_offset_* / stroke_offset_* | 100.0 = fontSize と同じ長さ。px 換算は value * fontSizePx / 100 |
| 倍率 | scale、stretch_*、zoom | 1.0 が等倍 |
| 0-1 | opacity、color の各成分、write_on_start / write_on_end、bounding_box.fill_opacity 等 | 閉区間または進行度として解釈される値 |
| degree | rotation、yaw、pitch、各種 angle | 角度。符号は §4.3 |
| 遠近強度 | camera.perspective | 単位なし。内部で distancePx = f(perspective) * canvas.height に写像(大きいほどカメラが近い) |
| px | canvas.width / height | ピクセル |
NOTE
shadow.distance は stroke.width と同じ em 単位で、パーツ自身の空間で測ります。 パーツの拡縮(global・文字・パーツの scale と stretch_*)、回転、遠近のどれがあっても、 シャドウは文字から常に同じ距離に見えます。shadow.angle で決めた方向は canvas 上で固定されます。
4.2 color
{ r = 1.0, g = 0.5, b = 0.0, a = 1.0 }r / g / b / a は number で、範囲は 0-1 です。 4つすべてを同時に指定する必要はなく、変更したい成分だけを書いたテーブル(例: { a = 0.5 })を代入できます。省略したキーは元の色の値がそのまま保たれます。 r / g / b / a 以外のキーを含めるとエラーになります。
4.3 座標
位置・offset・pivot の単位定義は §4.1
X は canvas 幅、Y は canvas 高さを基準にします
global.position、文字・パーツのoffset/pivot、geometry では、Y は上方向が正です(Lua値のYを増やすと画面上方向へ移動します)3Dの奥行き
zは奥方向が正です(値が大きくなるほどカメラから遠ざかり、画面奥に配置されます。負の値で手前に近づきます)global.pivotと文字・パーツのoffset/pivotは canvas 正規化変位です(§4.1)。geometry の canvas 座標とglobal.positionは canvas 正規化位置ですgeometry の canvas 位置は canvas 左下が
0,0、中心が0.5,0.5geometry の local 位置と advance は変位量なので中心オフセットを持たず、Y-up で表されます
形状を描く座標はY-down、配置座標・移動量・文字メトリクスはY-upです
rotation、yaw、pitch、angle はすべて degree です
- 2D回転(
rotation): 正(+)が時計回り(右回り)、負(-)が反時計回り(左回り)です(90で上を向いていたものが右を向きます)。 - 3Dオブジェクト回転(
yaw,pitch): Individual/Global ともに、個別ピボットを中心とした回転です。yaw: 正(+)でオブジェクトの右端が手前(-Z)へ、左端が奥(+Z)へ回転します。pitch: 正(+)でオブジェクトの上端が手前(-Z)へ、下端が奥(+Z)へ回転します。
- カメラの旋回(
yaw,pitch): 注視点の周りをカメラが公転(Orbit)します。yaw: 正(+)でカメラが注視点の周りを右に回り込みます(画面上のオブジェクトは左に回転して見えるようになります)。pitch: 正(+)でカメラが注視点の周りを上に回り込みます(見下ろすアングルになります)。
- グラデーション角度(
angle):0度で左から右(Xの正方向)に進み、角度が増える(正)と時計回りに回転します。 - シャドウ角度(
angle):0度で右方向(Xの正方向)に伸び、角度が増える(正)と時計回りに回転します(90度で真下方向)。
- 2D回転(
WARNING
2Dの角度系は「スクリーン感覚(時計回りが正、90度 = 真下)」で統一されており、 座標系(Y-up)とは向きの感覚が逆です。 offset_y は上が正なのに対し、rotation / gradient.angle / shadow.angle は正で時計回りに回り、シャドウ角 90 は真下を 指します。
座標系から符号を導くと逆になります。 Y-up なら通常は反時計回りが正で、数学的慣習も Fusion の Transform ノードもそちらです。本エフェクトだけが例外なので、どちらから持ち込んだ 角度も符号を反転する必要があります。Transform と組み合わせて同じ向きに回すときも、 どちらか一方を反転してください。
符号は時計の文字盤で確認してください。 rotation = 90 で上を向いていたものが 右を向きます(12時 → 3時)。文字盤と画面の感覚がずれる下半分に注意してください。 下に垂れたものは正の値で左へ振れます(6時から7時・8時へ進むため)。
角度から向きベクトルを作って offset_y に渡すときは、mt.polar_offset_2d を使ってください。 入力の角度は角度系(90 度 = 画面下向き)のまま、戻り値は位置系(Y は上が正)で返るので、 offset_x / offset_y の両方へそのまま加算できます。
local dx, dy = mt.polar_offset_2d(angle, radius)
character.offset_x = character.offset_x + dx
character.offset_y = character.offset_y + dyTIP
円形・放射状エフェクトの距離には mt.layout.radial_distanceを使ってください。 Canvasのアスペクト比は関数内で補正されるため、X座標を手動で変換する必要はありません。
local distance = mt.layout.radial_distance(
ctx,
geometry.bounds_center_x,
geometry.bounds_center_y
)斜め方向への符号付き距離や内積を求める場合は、X方向の差分に ctx.canvas.aspect_ratio を掛けてから計算します。非正方形ピクセルの物理表示比を考慮する場合は、 ctx.canvas.pixel_aspect_ratio も掛けます。
pivot は基準点からの変位
ctx.global.pivot_x/yはglobal.positionからの変位です。0.5, 0.5のとき支点はglobal.positionと一致します- 文字・パーツの
pivot_x/yは自身の基準点からの変位です。0.5, 0.5のとき、文字は 自然なバウンディングボックス中心(geometry.bounds_center相当)、パーツは自然位置 (geometry.canvas_center相当)を中心に回転・スケールします - したがって文字・パーツの pivot に
geometryの canvas 座標をそのまま代入してはいけません。 「自身の中心から右へ10%ずらした点を中心に回す」ならpivot_x = 0.5 + 0.1です - 文字の辺を支点にするときは、自然中心からの半サイズ分だけ変位させます (
bounds_width/bounds_heightは canvas 軸比で、pivot の変位と同じ単位系です):- 下辺:
pivot_y = 0.5 - geometry.bounds_height * 0.5 - 上辺:
pivot_y = 0.5 + geometry.bounds_height * 0.5 - 左辺:
pivot_x = 0.5 - geometry.bounds_width * 0.5 - 右辺:
pivot_x = 0.5 + geometry.bounds_width * 0.5
- 下辺:
4.4 代入のルール
書き込み可能フィールドの現在値には、Inspector設定と前段のコールバックで確定した値が入っています。 完全上書きが演出の意図でない限り、その現在値を基準にアニメーションを合成してください。
- 位置、オフセット、ピボット、回転、奥行きには、アニメーションで求めた差分を加算します
- Scale、Stretch、Opacityには、アニメーションで求めた係数を乗算します
- FillやStrokeの色など、作品固有のスタイルへ置き換えること自体が目的なら直接代入できます
- 複数の計算で元の値が必要な場合は、最初の書き込み前にローカル変数へ保存します
local inspectorRotation = character.rotation
local inspectorScale = character.scale
character.rotation = inspectorRotation + math.sin(ctx.time) * 10.0
character.offset_y = character.offset_y + math.sin(ctx.time * 2.0) * 0.05
character.scale = inspectorScale * (1.0 + math.sin(ctx.time) * 0.1)
character.opacity = character.opacity * fade
-- Inspector設定を置き換えることが意図である場合だけ直接代入する
character.rotation = ctx.time * 20.0次の操作はエラーになります。
- 書き込み不可フィールドへの代入
- 未知フィールドの追加
- 型の不一致(numberの場所へstringなど)
ctx.chars/ctx.partsなど読み取り専用コンテナの置換・要素数変更- 列挙値フィールドへの不正な文字列
5. 継承の仕組み
use / opacity / fill.transparent の役割
| 設定 | 描画への影響 |
|---|---|
fill.use / stroke.use / shadow.use | trueなら対象の文字・パーツに設定された個別値を使い、falseなら上位の設定を引き継ぎます。表示・非表示は切り替えません |
opacity(global / character / part) | 継承後に決まった塗り・線・影などの不透明度へ乗算します。0で透明、1で元の不透明度です |
global.fill.transparent | 塗りだけを透明にします。ストロークやシャドウには影響しません |
描画に使う色と不透明度は、次の順で決まります。
- 色の決定:
fill.useがtrueなら文字・パーツに設定された個別色を使い、falseならグラデーション(有効時)またはGlobalの塗り色を使います - 不透明度の適用: 決定した色の不透明度に
global.opacity × character.opacity × part.opacityを掛けます
use = false の場合、文字・パーツの個別色を変更しても描画には使われません。 opacityだけを変更した場合、使用する色やグラデーションは変えずに不透明度だけが変わります。
描画に使われる値は次の順で決まります。
OnPreLayout で確定した Global
↓
文字: 各グループの use が true なら文字の個別値、false なら Global 値
↓
パーツ: 各グループの use が true ならパーツの個別値、false なら文字の段階で選ばれた値gradient.color_space が none 以外のときは、この順序でGlobal値が選ばれた (文字・パーツどちらの fill.use も false の)部分だけがグラデーションで塗られ、 個別色が有効な文字・パーツは、その個別色の単色で塗られます。
パーツの stroke / shadow はホスト側にパラメーターグループが存在しない(常に未使用/既定値から 始まる)点を除けば、fill と同じ順序で使用する値が選ばれます。
OnLayout に渡される文字・パーツには、上位の設定を反映する前の個別設定値が入っています。 Luaからは各グループの use も変更できるため、個別値を書き換えて同じコールバック内で 有効にできます。
local character = ctx.chars[index]
character.fill.use = true
character.fill.color = mt.color.from_hsv(index / ctx.char_count, 0.8, 1.0)transform系フィールド(offset / scale / rotation など)には use_* がなく、常に描画へ反映されます。 スクリプトによる変更はそのフレーム内だけで完結し、ホストのInspectorやキーフレームへ書き戻される ことはありません。
6. 実行環境・エラー・制限
6.1 エラー時のフレーム処理
ホストではコールバック内のどこかでエラーが起きると、そのフレームは描画されません。失敗までに行われた変更の ロールバックは保証されませんが、未完了の結果が描画に使われることはありません。
MT Simではデバッグを続けやすくするため、エラーをOutputパネルへ表示し、スクリプト適用前の値へフォールバックして プレビューを続けます。この点はホストのフレーム中止動作と異なります。
| 失敗箇所 | 結果 |
|---|---|
| スクリプトロード | ホストでは描画しない。MT Simではエラーを表示し、直前の正常なスクリプトを維持する |
OnPreLayout | ホストでは後続コールバックを実行せず描画しない。MT Simでは元の値でプレビューする |
OnLayout | ホストではOnPathを実行せず描画しない。MT Simでは未変更のレイアウトをプレビューする |
OnPath | ホストでは描画しない。MT Simでは元のグリフ輪郭をプレビューする |
6.2 利用可能な標準ライブラリ
Lua標準ライブラリは、安全なサブセットに限定されています。
- 利用可能: 基本関数の安全なもの、
math、string、table、utf8 - 利用不可:
os、io、package、require、dofile、loadfile、load、debug、collectgarbage、rawget、rawset、getmetatable、setmetatable
ファイル、ネットワーク、プロセスへのアクセスはできません。
6.3 実行制限
- 1コールバック呼び出しあたり 5,000,000 命令
- メモリ上限 128MiB(ホスト実行時)
上限を超えたコールバックは失敗として扱われ、§6.1 の動作になります。
6.4 print(...) とフレームダンプ
Lua標準の print(...) は、MT SimのOutputパネル(ログ)へ診断情報を出力するために使えます。
フレームダンプ機能
シミュレータツールバーの 虫アイコン(フレームダンプ)ボタン をクリックすると、タイムラインの選択範囲(未指定時は全フレーム)を順次評価し、シーンの前提情報(解像度・文字数・フォント等)と各フレームの print(...) 出力・エラーを一括してログへダンプします。
=== SIMULATOR CONTEXT ===: 解像度、FPS、文字数、パーツ数、フォント、配置設定などのシーン前提値=== FRAME LOGS ===: 各フレームの[<フレーム番号>] <出力内容>(出力がないフレームは省略)=== DUMP COMPLETE ===: 評価結果サマリー- タイムラインのイン/アウトハンドルを動かして範囲を絞り込むことで、特定の区間だけを素早く検証できます。
6.5 エラーの確認
ホストではスクリプトのエラー内容を確認できません。まずMT Simでスクリプトを実行し、 Outputパネルに表示されるエラーメッセージとスタックトレースを確認して修正してください。
対象APIレベル: 15
ctxは、Mug Typographyが各コールバックへ渡すコンテキストです。現在時刻、Canvas情報、 全体設定、生成された文字・パーツなど、そのフレームの処理に必要な情報が含まれます。
利用できるフィールドと書き込み権限はコールバックによって異なります。本書では、最初に コールバックごとの利用可否を一覧にしたあと、ctxのフィールドを順に説明します。 コールバックの実行順序と用途は コールバックの概要を参照してください。
1. ctxのフィールド一覧
ctx直下のフィールド自体は読み取り専用で、別の値へ置き換えることはできません。 ただし、ctx.globalやctx.chars[index]などの内部には、コールバックに応じて変更できる フィールドがあります。○はそのコールバックで参照できることを表します。
| フィールド | 型 | OnPreLayout | OnLayout | OnPath | 内容 |
|---|---|---|---|---|---|
ctx.time | number | ○ | ○ | ○ | クリップ先頭を0とする現在時刻(秒、§1.1) |
ctx.frame | number | ○ | ○ | ○ | クリップ先頭を0とするフレーム番号。サブフレームを含む場合があります(§1.1) |
ctx.fps | number | ○ | ○ | ○ | フレームレート(§1.1) |
ctx.canvas | table | ○ | ○ | ○ | Canvasとプロジェクトの画素情報(§1.2) |
ctx.fonts | string[] | ○ | ○ | ○ | global.font_nameへ設定できるフォント名の1始まり配列(§1.3) |
ctx.timeline | table | ○ | ○ | ○ | クリップの時間範囲と現在進行度(§1.4) |
ctx.font | table | - | ○ | ○ | 使用中フォントのメトリクス(寸法情報、§1.5) |
ctx.text | string | ○ | ○ | - | 廃止予定のテキスト参照(§1.6) |
ctx.char_count | integer | - | ○ | ○ | 有効な本文の文字数。図形は数えません(§1.6) |
ctx.part_count | integer | - | ○ | ○ | 有効な本文のパーツ数。図形は数えません(§1.6) |
ctx.shape_count | integer | - | ○ | ○ | 宣言された図形の数(§1.17) |
ctx.meta | table | ○ | ○ | ○ | APIバージョンと機能情報(§1.7) |
ctx.inputs | table | ○ | ○ | ○ | Inspectorで設定したスクリプト入力(§1.16) |
ctx.global | table | ○ | ○ | ○ | 全体設定。OnPreLayoutで変更でき、以降は読み取り専用です(§1.8) |
ctx.camera | table | ○ | ○ | ○ | カメラ設定。OnPreLayoutで変更でき、以降は読み取り専用です(§1.9) |
ctx.chars | table[] | - | ○ | ○ | 生成された本文の文字の1始まり配列(§1.10) |
ctx.parts | table[] | - | ○ | ○ | 生成された本文のパーツの1始まり配列(§1.11) |
ctx.bounding_box | table | - | ○ | ○ | バウンディングボックスの描画設定(§1.12) |
ctx.output | table | - | ○ | ○ | 出力フィルタと描画順の設定(§1.13) |
ctx.paths | table | - | - | ○ | パーツのパスを取得・編集するためのコンテキスト(§1.14) |
ctx.glyphs | table | ○ | - | - | カスタムグリフを宣言するためのコンテキスト(§1.15) |
ctx.shapes | table | ○ | ○ | ○ | 図形を宣言し、番号で参照するためのコンテキスト(§1.17) |
ctx.shape_cameras | table | ○ | ○ | - | 図形を映すカメラを宣言し、番号で動かすためのコンテキスト(§1.17) |
1.1 ctx.time / ctx.frame / ctx.fps
現在の評価位置をクリップ先頭基準で表します。ctx.timeは秒、ctx.frameはフレーム単位です。 ctx.frameにはサブフレームが含まれる場合があるため、整数とは限りません。ctx.fpsは 1秒あたりのフレーム数です。
1.2 ctx.canvas
Canvasとプロジェクトの画素情報です。すべて読み取り専用です。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
width / height | number | px | Canvasの幅と高さ |
aspect_ratio | number | - | Canvasの幅を高さで割った値(width / height) |
pixel_aspect_ratio | number | - | ホストプロジェクトのピクセルアスペクト比 |
1.3 ctx.fonts
ホストが認識しているインストール済みフォントの名前を格納した、読み取り専用の1始まり配列です。 内容はホストUIのFontリストと同じで、OnPreLayoutでは要素をctx.global.font_nameへ 設定できます。
配列の要素や要素数は変更できません。
1.4 ctx.timeline
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
available | boolean | - | 有限なクリップ範囲を取得できたか |
start_frame / end_frame | number | frame | 範囲の始端/終端(クリップローカル。始端は常に0) |
duration_frames | number | frame | end_frame - start_frame |
duration_seconds | number | second | 秒に換算した長さ |
progress | number | 0-1 | 0-1にクランプされた現在位置 |
クリップ範囲
クリップ範囲は、トリムや前後の引き伸ばしを含むタイムライン上の実範囲です。 ctx.time / ctx.frame / ctx.timelineには、クリップ先頭を0とした同じ時間軸の値が 渡されます。フィルタとして映像クリップに適用した場合も、そのクリップの範囲に追従します。
availableがfalseのときは他の値が0になるため、フォールバックを用意してください。
NOTE
ジェネレータ運用での前方引き伸ばしの制限: ジェネレータクリップ(入力未接続)の前方を タイムライン上で引き伸ばした場合、その区間はホストが先頭フレームの静止画として扱うため、 スクリプト時間は引き伸ばし境界まで進みません(イントロが先頭姿で静止して見えます)。 尺を変えたい場合は引き伸ばしではなくジェネレータクリップ自体の長さを変更してください。 フィルタ運用にはこの制限はありません。
時間軸の設計ルール(アンカー × 速度)
アニメーションの時間設計は「①どこに固定するか(アンカー)」と「②どの速さで進めるか(速度)」の 2軸で決めます。**速度の既定は実秒(ctx.time ベース)**で、クリップ長に比例させる progress を 使ってよいのは後述の「全体スパン型」だけです。
| パターン | アンカー | 書き方 |
|---|---|---|
| イントロ(登場) | クリップ先頭 | ctx.time をそのまま使う(実秒)。イントロ+アウトロ一括なら mt.timeline.intro_outro_seconds(§10.9) |
| アウトロ(退場) | クリップ終端 | mt.timeline.remaining(ctx)(終端までの残り実秒。§10.9) |
| タイプライター・stagger・ばね等 | クリップ先頭 | ctx.time(実秒。1文字あたり○秒など物理速度で指定) |
| 全体スパン型(尺いっぱいのドリフト・スイープ・リビール) | クリップ全体 | progress(尺が伸びたら動きも伸びるのが期待動作) |
トランジションを progress の割合で書くと、尺を伸ばしたときにフェードやタイピングが スローモーション化して破綻します。アウトロも本質は「終端に揃えること」であって速度を尺に 比例させることではないため、終端アンカーの実秒で書きます。
-- NG: typing speed changes when the clip length changes
local visible = math.floor(mt.timeline.progress(ctx) * ctx.char_count)
-- OK: constant 0.08s per character regardless of clip length
local visible = math.floor(ctx.time / 0.08)
-- OK: outro fade over the last 0.5s, anchored to the clip end
local fade = mt.clamp(mt.timeline.remaining(ctx) / 0.5, 0.0, 1.0)
-- OK: 0.8s intro + 0.5s outro at fixed real-time speed
-- (compressed automatically only when the clip is shorter)
local intro, outro = mt.timeline.intro_outro_seconds(ctx, 0.8, 0.5)1.5 ctx.font - 使用中フォントの寸法情報
レイアウト生成後に確定した、使用中フォントのメトリクス(寸法情報)です。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
em_size | number | canvas 高さ比 | 変形前の1emの大きさ |
ascent | number | canvas 高さ比 | ベースラインから上方向のアセント |
descent | number | canvas 高さ比 | ベースラインから下方向のディセント(正値。下向きの量として表す) |
line_height | number | canvas 高さ比 | 行の高さ |
units_per_em | number | フォント設計単位 | フォントの em 正方形の設計単位数 |
NOTE
画面上の最終サイズは scale 系フィールドの積で予測できます(2Dプリセット限定)。 フォントサイズはホストが内部で canvas.height に対する固定比率として計算しているため、 canvas解像度が変わっても同じ比率を保ちます。この基準サイズに character.scale × character.stretch_x/y・part.scale・ctx.global.scale × ctx.global.stretch_x/y を 掛け合わせたものが、2Dプリセットでは実際の画面上サイズと一致します(すべて乗算で 合成される変形だからです)。
3Dプリセットではこの積は近似にしかなりません。 カメラ投影が奥行き(z、 yaw/pitchによる見かけの奥行き変化、カメラの perspective / zoom を含む)に応じた 遠近除算を行うため、画面上サイズは奥行きに対して非線形に変化し、傾いた文字は 頂点ごとに歪みが生じて単一の倍率では表せません。ctx.fontとcharacter.geometry は投影前の値であり、投影後の画面上サイズはOnLayoutから取得できません。
1.6 ctx.text / ctx.char_count / ctx.part_count
ctx.textは廃止予定です。現在のテキストを参照するときはctx.global.textを使い、 書き換えるときはOnPreLayoutでctx.global.textへ代入してください。
ctx.char_countとctx.part_countは、それぞれレイアウト生成後の有効な本文の文字数とパーツ数を 表します。図形(§1.17)は数えず、ctx.shape_countで数えます。テキストやフォントを変更すると、シェイプ結果に応じて値も変わります。
1.7 ctx.meta
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
ctx.meta.api_level | integer | - | Lua API互換レベル |
ctx.meta.plugin_version | string | - | 実行中のプラグインバージョン(表示用) |
ctx.meta.capabilities | table | - | 現在利用できる機能の情報。読み取り専用 |
ctx.meta.capabilities.has_3d | boolean | - | 3D Projectionが現在のプリセットで有効か |
ctx.meta.limits | table | - | このインスタンスに適用される上限値。読み取り専用 |
ctx.meta.limits.max_characters | integer | - | このインスタンスで扱える最大文字数 |
ctx.meta.limits.max_parts | integer | - | このインスタンスで扱える最大パーツ数 |
ctx.meta.limits.max_shapes | integer | - | このインスタンスで扱える最大図形数。図形は文字・パーツの上限を使わないため、全プリセット共通です |
ctx.meta.instance_seed | integer | - | このインスタンス固有の安定した乱数シード(0以上2^31-1以下)。同一インスタンスでは生存期間中ずっと同じ値、別インスタンスでは別の値になります |
機能の判定
機能の有無はctx.meta.api_level >= 必要レベルとcapabilitiesで判定します。 has_3dがfalseでもCameraおよびyaw / pitch / zへの代入はエラーになりませんが、 描画には反映されません。
instance_seedの用途
instance_seedをmt.randomのseedに使うと、同じスクリプトでもインスタンスごとに 異なる乱数列になります。
1.8 ctx.global
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
text | string | - | UTF-8テキスト。変更すると再シェイプし、文字・パーツ数を再生成します |
font_name | string | - | フォントファミリー名(ctx.fontsのいずれか)。変更すると使用フォントを変更して再シェイプします |
tracking | number | em | 各文字の後方送りに加算する文字送り。1.0は1 emです |
line_spacing | number | 倍率 | 行/縦書き列の送り |
vertical | boolean | - | trueで縦書きにし、シェイプと配置方向を変更します |
single_part_glyph | boolean | - | trueでフォントグリフを1パーツ化し、半透明の輪郭交差部分が濃くなることと内部の縁取りを防ぎます。カスタムグリフ・カラー絵文字は対象外です。OnPreLayoutで変更するとレイアウトを再生成します。毎フレームInspectorの値から初期化されます(APIレベル15)。 |
h_align | string | - | 水平アラインメント。left / center / right |
v_align | string | - | 垂直アラインメント。top / center / bottom / baseline |
margins | number[] | em | 各文字の後方送り。trackingと同じ単位です |
emoji | table | - | 絵文字の配置とフォントの設定(下表) |
position_x / position_y | number | canvas正規化座標 | 全体位置。0.5が中央で、Xは右、Yは上が正です |
rotation | number | degree | 2D全体回転。正(+)で右回り(時計回り)、負(-)で左回り(反時計回り)です |
yaw / pitch | number | degree | 3D全体姿勢。3Dプリセットのみ描画に反映されます。yawは正(+)で右端が手前へ、pitchは正(+)で上端が手前へ回転します |
scale | number | 倍率 | 全体均等スケール。書き込み時に最小0.0001へクランプされます |
stretch_x / stretch_y | number | 倍率 | 全体非均等スケール。scaleと異なり正の下限はなく、0や負値も受理されます |
pivot_x / pivot_y | number | canvas正規化変位 | 全体変形のピボット。0.5で変位量0になり、大きいほどglobal.positionから右/上へ移動します |
opacity | number | 0-1 | 全体の不透明度。既定値は1.0です。範囲外の値はホストが描画直前に0-1へクランプします。塗り・グラデーション・ストローク・シャドウ・バウンディングボックスすべてに、色が決まった後のアルファとして乗算されます(fill.useの判定には関与しません。use / opacity / fill.transparent の役割を参照してください)。ホスト側にキーフレームパラメータは存在せず、スクリプトからのみ書き込めます |
fill | table | - | 全体塗り設定(下表) |
gradient | table | - | グラデーション設定(下表) |
stroke | table | - | 全体ストローク設定(下表) |
shadow | table | - | 全体シャドウ設定(下表) |
texture | table | - | 全体テクスチャ設定(下表) |
blur | table | - | 全体の文字そのもののぼかし設定(下表) |
Inspectorの本文に入力した \n・<br>・<br/>・<br /> は、OnPreLayout より前に実際の改行文字(LF)へ変換されます。CRLFもLFになります。\\n と \<br> は文字としての \n と <br> になります。ctx.textも同じ解釈済みテキストを参照します。
OnPreLayoutで代入したテキストは改行表記を再解釈しません。Luaでは "A\nB" または複数行文字列で実際の改行を作り、文字としての \n は "A\\nB" と書いてください。カスタムグリフの宣言・挿入後に文字配列を生成し、改行自体は ctx.chars に含めません。
ctx.global.margins
インデックスと計算
marginsは、レイアウト順の文字番号をキーとする1始まりの配列です。この番号は、 あとでctx.charsに付くindexと同じです。margins[i]はi番目の文字の後ろの送りへ、 trackingと合わせてem単位で加算されます。
(margins[i] + tracking) * designUnitsPerEm配列形式
キーは1以上の整数、値は数値にしてください。非整数キー、文字列キー、0以下のキー、数値以外の値はエラーになります。 途中の番号を省略しても構いません。省略した番号は0(余白なし)として扱われるため、margins[2]だけの代入や { [2] = 0.5 }のようなテーブルも有効で、margins[1]は0になります。
OnPreLayoutのctx.global.marginsはctx.meta.limits.max_characters個の要素を持ちます。そのため #ctx.global.marginsは文字数ではありません。この上限を超える番号はどの文字にも届かないため、エラーにならず 無視されます。
文字数
OnPreLayoutではctx.char_countが未定義です。utf8.len(ctx.global.text)で得られるのは UTF-8コードポイント数であり、結合文字、合字、書記素クラスタなどにより、シェイプ後の 文字数と一致しない場合があります。正確な個数が必要な処理はOnLayoutで行ってください。
サブオブジェクトのマージ
ctx.global.shadow = { enabled = true, distance = 0.8 }のようにテーブル全体を代入すると、 フィールドごとにマージされます。省略したフィールドは現在値を維持します。
ctx.global.fill
NOTE
color型
colorはr(赤)、g(緑)、b(青)、a(アルファ)を持つテーブルです。 各フィールドは0-1のnumberで、a = 0は完全な透明、a = 1は完全な不透明を表します。
フィールドへ直接代入できるほか、テーブル全体を代入するときは変更するフィールドだけを 記載できます。省略したフィールドは現在値を維持します。
ctx.global.fill.color.r = 1.0
ctx.global.fill.color = { a = 0.5 }r / g / b / a以外のフィールドや、number以外の値はエラーになります。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
color | color | RGBA 0-1 | 全体の塗り色。グラデーションの始端色も兼ねます |
transparent | boolean | - | trueにすると、ストロークや効果を残して塗りを非表示にします |
chars[index].fill.useがfalseの文字にはfill.colorが使われます。 パーツまで含めた継承順は「継承の仕組み」を 参照してください。
ctx.global.gradient
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
color_space | string | - | グラデーション/Crayonモード。値は下記の列挙値です |
end_color | color | RGBA 0-1 | グラデーション終端色 |
midpoint | number | 0-1 | 色補間の中点 |
angle | number | degree | グラデーション方向。0度で左から右に進み、正(+)で右回り(時計回り)に回転 |
start_position / end_position | number | 変形後の全体範囲に対する相対位置 | グラデーション区間。標準は0.0〜1.0です。詳しくはグラデーションの範囲と向きを参照してください |
gradient.color_space の値:
noneokhsvokhsloklablinear_rgboklch_short- API Level 11。OKLCHの短い色相経路。oklch_long- API Level 11。OKLCHの長い色相経路。crayon
ctx.global.texture
塗りに重ねるマテリアル(質感)です。p1〜p4 はマテリアル共通の汎用コントロールで、意味は選んだ type によって変わります。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
use | boolean | - | 継承したテクスチャの代わりに自身のテクスチャを使うか。ctx.global では無視され、ctx.chars[i] / ctx.parts[i] でのみ意味を持ちます |
type | string | - | マテリアルの種類。値は下記の列挙値です |
p1 | number | 素材による | 第1コントロール |
p2 | number | 素材による | 第2コントロール |
p3 | number | 素材による | 第3コントロール |
p4 | number | 素材による | 第4コントロール |
p5 | number | 素材による | 第5コントロール。halftone・halftone_diamond・colored_pencil・prism_foil・iridescent・metallic だけが読みます。halftone 系では Fade の向きを度で表し(0 で下へ向かって濃くなる)、colored_pencil では光が来る画面上の方向を度で表します(0 が右、90 が下)。prism_foil ではタイルの並ぶ向きを度で表します(0 でパーツの x 軸方向)。iridescent では膜厚のムラを 0〜1 で表します(0 で一様な膜)。metallic ではヘアラインの角度を度で表します(0 でパーツの x 軸方向)。ほかの素材は無視します。初期値は 0(API レベル 14) |
color | color | RGBA 0-1 | マテリアルが塗りの上に加えるものの色。stained_glass では鉛線、glitter では金属片、stripe では縞、halftone では点、prism_foil では箔(白で銀)、それ以外では光の色です。白の場合、光はマテリアルのまま、鉛線は白になります(iridescent は無視します) |
texture.type の値と、p1〜p4 の意味:
type | p1 | p2 | p3 | p4 |
|---|---|---|---|---|
none | - | - | - | - |
water_droplet | 厚み | 丸み | 光沢 | 光の角度 |
air_cushion | 膨らみ | 圧着幅 | 皺 | 光の角度 |
glitter | フレークサイズ | 光る粒の割合 | 粒の量 | 光の角度 |
iridescent | 膜厚 | 色相幅 | 強度 | 光の角度 |
faceted | 面の数 | 面取りの深さ | 磨き | 光の角度 |
stained_glass | ガラス片の大きさ | 鉛線の太さ | 色相幅 | Glow |
metallic | 磨き | 起伏 | 反射コントラスト | 光の角度 |
metallic_2 | 磨き | 起伏 | 露出 | 光の角度 |
stripe | 縞の密度(本数) | 縞の太さ | 縞の濃さ | 縞の向き(度) |
colored_pencil | 白い線の密度 | 白い線の長さ | 光の強さ | 線の向き(度) |
halftone・halftone_diamond | 点の密度(個数) | 点の大きさ | 減衰の強さ | 格子の向き(度) |
prism_foil | タイルの大きさ | 虹色の量 | 箔の濃さ | 光の角度(画面上の度) |
Flake Amount は全体の粒の量です。0 で粒とグローなし、1 で最大密度になります。色相幅は従来の Hue Range 1.0 相当で固定です。
光る粒には白寄りの芯と柔らかなグローが付きます。グローは文字の輪郭内に描かれ、Highlight Ratio で光る粒とともに増減します。
p1〜p4 はいずれも汎用スロットで、範囲も単位もマテリアルが決めます。多くは 0〜1 ですが、たとえば光の角度は度で読まれます。マテリアルは受け取った値を自身が扱える範囲へ丸めてから使うため(角度のように一周するものは繰り返し、上限があるものは端で止まります)、範囲外の値を書いても保存値やキーフレームは書き換えられません。
テクスチャは全体・文字・パートの3段で継承されます。ctx.chars[i].texture / ctx.parts[i].texture に use = true を設定すると、その要素だけ別のマテリアルに差し替えられます。文字やパート側はホストのパラメータを持たないスクリプト専用の値のため、スクリプトが設定しない限り常に未使用として読み取られます。
ctx.global.blur
文字そのもの(塗り・グラデーション・テクスチャ・ストローク・クレヨン)をまとめてぼかします。シャドウはこの設定ではぼけません。シャドウには専用の shadow.blur_x / blur_y があります。バウンディングボックスはぼけません。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
use | boolean | - | 継承した値の代わりに、この要素自身のぼかしを使うかどうか。use を持たない ctx.global では無視され、ctx.chars[i] / ctx.parts[i] でのみ意味を持ちます |
amount_x | number | em | 水平方向のぼかし(ガウスのσ)。1.0 = 1 em。0 で水平方向の縁はぼけません。書き込み時は 0〜10 に丸められます |
amount_y | number | em | 垂直方向のぼかし。単位と範囲は amount_x と同じです |
glow | number | - | グローの強さ。ぼかした文字を明るく持ち上げて発光させ、色が飽和した芯は白に近づきます。0 でグローなし。文字がぼけていないときは効果がありません。書き込み時は 0〜10 に丸められます |
ぼかしはパーツ自身の空間で、canvasの軸方向に測るため、shadow.distance と同じくパーツの拡縮・stretch・遠近に追従します。ぼかしは、全体・文字・パーツの3段で継承されます。ctx.chars[i].blur / ctx.parts[i].blur で use = true にすると、その要素だけ自身のぼかしを使います。文字とパーツの値はスクリプト専用(ホスト側パラメータの裏付けなし)のため、スクリプトが設定するまでは常に未使用で、継承する値と同じ値として読み取られます。シャドウのぼかしはシャドウ色と同じ shadow.use に従うため、1つのパーツのぼかしだけを上書きするには継承した色を書き戻します。その色は mt.shadow.resolve(ctx, target, { level = "character" }) が返します。
ctx.global.stroke
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
width | number | em(1.0 = フォントサイズ 1 em。描画時に fontSize を掛ける) | ストロークの太さ |
gap | number | em(1.0 = フォントサイズ 1 em) | 塗りとストロークの間隔 |
color | color | RGBA 0-1 | ストローク色 |
outer_width | number | em(1.0 = フォントサイズ 1 em) | Inner Strokeの外側に隣接するOuter Strokeの太さ。width > 0のときだけ有効 |
outer_color | color | RGBA 0-1 | Outer Strokeの色 |
order | string | - | 塗りとストロークの重なり順。fill_over_stroke / stroke_over_fill / fill_over_stroke_per_character |
join | string | - | ストローク角の接続方式。miter_clip / round / bevel / miter_round / miter_bevel |
miter_limit | number | 倍率 | 鋭いmiter角の最大長 |
fill_over_stroke_per_characterはfill_over_strokeと同じ重なり(塗りがストロークの上)を、 文字ごとに完結させて描画します。描画順で同じ文字番号が連続する範囲ごとに全パスを終えてから 次の範囲へ進むため、各文字が自分のストロークを自分の塗りで隠した状態で完成します。 文字を重ねたとき、後続の文字のストロークが先行する文字の塗りの上に乗ることがありません。 文字番号による並べ替えは行わないため、描画順がA A B Aなら3つの範囲になります。 Gapがある場合、その消去はその範囲の内側だけに閉じ込められ、先行文字を削りません。 3D投影が有効なフレームは、orderの指定に関わらず常にこの文字単位描画になります。 Crayonは従来どおり通常描画の後にまとめて描かれるため、この設定の対象外です。
シミュレータのCanvasプレビューはorderの合成を再現しません。 選択・保存・スクリプトからの読み書きは動作しますが、 重なりの最終的な見え方はプラグイン本体の描画結果で確認してください。
chars[index].stroke.useがfalseの文字には、上記の全体ストローク設定が使われます。 パーツまで含めた継承順は「継承の仕組み」を 参照してください。
ctx.global.shadow
NOTE
このシャドウは、文字・パーツと同じ形状を distance/angle の位置へオフセットしたコピーで、 blur_x/blur_y でぼかせます(どちらも既定値は 0 で、輪郭が鮮明なままです)。サイズは 本体と常に等倍のため、distance = 0 でぼかしも無い場合は本体テキストの真後ろに完全一致で重なり、 見た目にはシャドウが全く見えません(縮小されて透けて見える、といった挙動にはなりません)。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
enabled | boolean | - | 全体シャドウの有効状態 |
distance | number | em | シャドウ距離。1.0 = 1 em。パーツ自身の空間で測るため、拡縮・stretch・回転・遠近があってもシャドウは文字から同じ距離に見える。angle で決めた方向は canvas 上で固定される。正で angle 方向へ遠ざかる。書き込み時の上限は10.0 |
angle | number | degree | シャドウ方向。0度で右方向、正(+)で右回り(時計回り)に回転(90度で真下方向) |
blur_x / blur_y | number | em | シャドウのぼかし(ガウスのσ)。1.0 = 1 em。書き込み時は 0〜10 に丸められます |
glow | number | - | グローの強さ。ぼかしたシャドウを明るく持ち上げて発光させ、色が飽和した芯は白に近づきます。0 でグローなし。シャドウがぼけていないときは効果がありません。書き込み時は 0〜10 に丸められます |
color | color | RGBA 0-1 | シャドウ色 |
chars[index].shadow.useがfalseの文字にはshadow.colorが使われます。 パーツまで含めた継承順は「継承の仕組み」を 参照してください。
WARNING
シャドウを有効にすると描画負荷が増え、レンダリング性能が低下します。 特に高解像度や複雑なテキストでは影響が大きくなるため、必要な場合だけ使用してください。
グラデーションが塗るのは、文字・パーツのfill.useがどちらもfalseの部分だけです。 fill.useがtrueの個別色はグラデーションより優先され、単色になります。 fill.useとopacityの段階分けは 「継承の仕組み」を参照してください。
ctx.global.emoji
ホストのText Settings内「Emoji」グループに対応します。OnPreLayoutで書き換えられ、OnLayout・OnPathでは読み取りのみです。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
offset_x / offset_y | number | em(1.0 = フォントサイズ 1 em) | フォントが置く位置からの絵文字のずらし量。Yは上が正です。文字送りは変わりません |
scale | number | 倍率 | 本文の何倍のフォントサイズで絵文字を組むか。文字送りも一緒に変わります。書き込み時に最小0.001へクランプされます |
use_custom_font | boolean | - | trueでfont_nameのフォントを使います。falseならシステムの絵文字フォント(Windows: Segoe UI Emoji、macOS: Apple Color Emoji)です |
font_name | string | - | カスタム絵文字フォント(ctx.fontsのいずれか)。use_custom_fontがfalseの間は値を保持したまま無視されます。見つからない名前はシステムの絵文字フォントになります |
use_outline | boolean | - | trueでカスタムフォントの輪郭から絵文字を描きます。use_custom_fontがtrueのときだけ効きます |
WARNING
どの値も、変えるとレイアウトを作り直します(変形中の絵文字は画像も作り直します)。 フレームごとに変化させると描画が大きく遅くなるため、固定値で使ってください。
use_outlineが効いている絵文字は通常の文字として扱われ、塗り色・グラデーション・テクスチャ・ストローク・シャドウが本文と同じように効きます。 輪郭を持たないグリフ(カラー専用のグリフなど)は、パーツを持たない文字になり何も描かれません。
シミュレータは絵文字を簡易表示します。絵文字のシーケンスを1文字1パーツにまとめ、offset_x / offset_y / scaleで配置し、ブラウザの絵文字フォントで描きます。 カスタム絵文字フォントの読み込みやuse_outlineの輪郭描画は行わず、3Dプリセットでは絵文字の四角だけを表示します。最終的な見た目はプラグイン本体で確認してください。
1.9 ctx.camera
3Dプリセットのカメラです。2Dプリセットでも代入はエラーになりませんが、描画に反映されるのは 3Dプリセットだけです。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
target_x / target_y | number | canvas正規化座標 | カメラ注視点。Xは右、Yは上が正です。注視点が動くとオブジェクトは逆方向に動いて見えます |
yaw / pitch | number | degree | カメラの旋回。yawは正(+)でカメラが右に回り込み、pitchは正(+)で上に回り込む(見下ろす) |
perspective | number | - | カメラ距離/遠近感を表す強度。内部でカメラ距離distancePx = f(perspective) * canvas.heightに写像されます(fは強度から距離係数への単調写像で、大きいほどカメラが近づき遠近が強くなります)。0〜1に丸められます。カメラのどの項目も有限である必要があり、NaN・infを書くとエラーです |
zoom | number | 倍率 | 投影拡大率。書き込み時に最小0.001へクランプされます |
lens_shift_x / lens_shift_y | number | canvas比率 | 主点移動。lens_shift_xの正(+)で全体が右、lens_shift_yの正(+)で全体が上にシフト |
1.10 ctx.chars[index]
ctx.charsはLua標準どおり1始まりの配列です。テキストやフォントが変わると、 文字数と各要素のindexも変わります。
fill / stroke / shadowのuseがfalseの場合は非表示になるのではなく、 グローバル値を継承します。詳しくは 「継承の仕組み」を参照してください。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
index | integer | - | 1始まりの文字index。読み取り専用 |
text | string | - | この文字クラスタの元テキスト。読み取り専用 |
part_start / part_count | integer | - | 所有パーツの先頭グローバルindex(1始まり)と個数。読み取り専用 |
line_index | integer | - | 属する行の1始まりindex。読み取り専用 |
geometry | table | - | 変形前の配置情報(下記)。読み取り専用 |
offset_x / offset_y | number | canvas正規化変位 | 文字の移動量。0.5で変位量0になり、大きいほど右/上へ移動します |
pivot_x / pivot_y | number | canvas正規化変位 | 文字変形の支点。0.5で自然中心になり、大きいほど右/上へ移動します |
scale | number | 倍率 | 均等スケール。書き込み時に最小0.001へクランプされます |
stretch_x / stretch_y | number | 倍率 | 非均等スケール。scaleと異なり正の下限はなく、0や負値も受理されます |
rotation | number | degree | 2D回転。正(+)が時計回り(右回り)、負(-)が反時計回り(左回り)です |
z | number | canvas高さ比 | 奥行き。正(+)で奥(カメラから遠ざかる)方向、負(-)で手前(カメラに近づく)方向です。3Dプリセットのみ描画に反映されます |
yaw / pitch | number | degree | 3D個別回転。yawは正(+)で右端が手前へ、pitchは正(+)で上端が手前へ回転します。3Dプリセットのみ描画に反映されます |
opacity | number | 0-1 | この文字の不透明度。既定値は1.0で、範囲外の値はホストが描画直前にクランプします。ctx.global.opacityと乗算されます(fill.useの判定には関与しません。役割分担を参照してください) |
z_index | number | - | 図形(ctx.shapes)専用の描画順の値です。本文の文字では無視されます(書き込みは受理されますが、描画順に影響しません) |
fill | table | - | 個別塗り(下表) |
stroke | table | - | 個別ストローク(下表) |
shadow | table | - | 個別シャドウ色(下表) |
texture | table | - | 個別テクスチャ。ctx.global.texture と同じ構造に use が付きます |
blur | table | - | 文字の個別ぼかし。ctx.global.blur と同じ構造に use が付きます |
chars[index].fill
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
use | boolean | - | trueならfill.colorを使います |
color | color | RGBA 0-1 | useがtrueのときに使う個別色 |
chars[index].stroke
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
use | boolean | - | trueならInner / Outerを含む個別ストローク設定を使います |
width | number | em(1.0 = フォントサイズ 1 em) | useがtrueのとき |
gap | number | em(1.0 = フォントサイズ 1 em) | useがtrueのとき |
color | color | RGBA 0-1 | useがtrueのとき |
outer_width | number | em(1.0 = フォントサイズ 1 em) | Inner Strokeの外側に隣接するOuter Strokeの太さ。width > 0のときだけ有効 |
outer_color | color | RGBA 0-1 | Outer Strokeの色 |
chars[index].shadow
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
use | boolean | - | trueならshadow.color、blur_x、blur_y、glowを使います |
color | color | RGBA 0-1 | useがtrueのときに使う個別色 |
blur_x / blur_y | number | em | useがtrueのときに使うシャドウの個別ぼかし。設定するまでは継承した値が読み取れます。書き込み時は 0〜10 に丸められます |
glow | number | - | useがtrueのときに使うシャドウの個別グローの強さ。設定するまでは継承した値が読み取れます。書き込み時は 0〜10 に丸められます |
サブオブジェクトへのテーブル全体代入は、§1.8と同じマージ規則です。
chars[index].geometry
文字のスクリプト変形、Deform、3D投影より前のレイアウトを表します。
位置と寸法はcanvas正規化です。内部画素座標からは Xを0.5 + px/width、Yを0.5 - px/heightとして変換します。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
canvas_origin_x / canvas_origin_y | number | canvas 正規化位置 | 組版原点(横書き: セル左端 × ベースラインに相当する placement origin) |
vertical_origin_x / vertical_origin_y | number | canvas 正規化位置 | 縦組み原点(列中心軸 × セル上端) |
bounds_center_x / bounds_center_y | number | canvas 正規化位置 | 変形前の文字輪郭が占める範囲(ink bounds)の中心 |
bounds_width | number | canvas 幅比 | ink bounds の幅 / canvas 幅 |
bounds_height | number | canvas 高さ比 | ink bounds の高さ / canvas 高さ |
advance_x | number | canvas 幅比 | フォントの水平送り(px)/ canvas 幅。tracking / margins を含まない |
advance_y | number | canvas 高さ比 | フォントの垂直送り(px)/ canvas 高さ(符号反転して Y-up)。下方向送りは負。tracking / margins を含まない |
スペースなど輪郭を持たない文字は ink bounds が潰れるため、代わりにフォント定義の文字セルを 返します。組版の流れ方向(横書きならX、縦書きならY)はその文字自身の送りが幅・高さになり、 交差軸はセルの高さ(横書き)/列幅(縦書き)になります。これにより、スペースの bounds_center_y が隣の文字より半セル下にずれることはありません。
1.11 ctx.parts[index]
ctx.partsはLua標準どおり1始まりの配列です。indexは文字ごとの番号ではなく、 フレーム全体を通したパーツ番号です。テキストやフォントが変わると、パーツ数と各要素の indexも変わります。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
index | integer | - | 1始まりのグローバルパーツindex。読み取り専用 |
character_index | integer | - | 所有文字の1始まりindex。読み取り専用 |
index_in_character | integer | - | 文字内での1始まりパーツindex。読み取り専用 |
geometry | table | - | 変形前の配置情報(下表)。読み取り専用 |
offset_x / offset_y | number | canvas正規化変位 | パーツの移動量。0.5で変位量0になり、大きいほど右/上へ移動します |
pivot_x / pivot_y | number | canvas正規化変位 | パーツ変形の支点。0.5で自然位置になり、大きいほど右/上へ移動します |
scale | number | 倍率 | 均等スケール。書き込み時に最小0.001へクランプされます |
rotation | number | degree | 2D回転。正(+)が時計回り(右回り)、負(-)が反時計回り(左回り)です |
stretch_x / stretch_y | number | 倍率 | 非均等スケール。scaleと異なり正の下限はなく、0や負値も受理されます |
z | number | canvas高さ比 | 奥行き。正(+)で奥(カメラから遠ざかる)方向、負(-)で手前(カメラに近づく)方向です。3Dプリセットのみ描画に反映されます |
yaw / pitch | number | degree | パーツ個別の3D回転。パーツpivotを中心に、所有文字の回転済み空間の内側で適用されます。yawは正(+)で右端が手前へ、pitchは正(+)で上端が手前へ回転します。3Dプリセットのみ描画に反映されます |
opacity | number | 0-1 | このパーツの不透明度。既定値は1.0で、範囲外の値はホストが描画直前にクランプします。所有文字のopacity(さらにctx.global.opacity)と乗算されます(fill.useの判定には関与しません。役割分担を参照してください) |
fill | table | - | use / colorを持つ個別塗り。文字のfillと同じ構造で、useがtrueならcolorを採用します |
stroke | table | - | use / width / gap / color / outer_width / outer_colorを持つ個別ストローク。文字のstrokeと同じ構造で、useがtrueなら個別値を採用します |
shadow | table | - | use / colorを持つ個別シャドウ色。文字のshadowと同じ構造で、useがtrueならcolorを採用します |
texture | table | - | 個別テクスチャ。文字のtextureと同じ構造で、useがtrueならそのマテリアルを採用します |
blur | table | - | 文字の個別ぼかし。文字のblurと同じ構造で、useがtrueならamount_x / amount_y / glowを採用します |
文字からの継承
パーツの塗り・ストローク・シャドウは、それぞれのuseによって次のように決まります。
| パーツの設定 | use = false | use = true |
|---|---|---|
fill | 所有文字の段階で選ばれた塗りを継承します | パーツのfill.colorを使います |
stroke | 所有文字の段階で選ばれたInner / Outer設定を継承します | パーツのstroke設定を使います |
shadow | 所有文字の段階で選ばれたshadow.colorを継承します | パーツのshadow.colorを使います |
所有文字でもuse = falseの場合は、さらにctx.globalの設定まで遡ります。詳しくは 「継承の仕組み」を参照してください。
インスペクタにない個別設定
パーツのstrokeとshadowにはインスペクタ上のパラメータがなく、初期状態は 未使用/既定値です。スクリプトでuseをtrueにすると、設定した個別値が優先されます。
yaw / pitchもインスペクタにはなく、初期値は0です。所有文字の回転とは独立しており、 文字の回転空間内で追加の回転として適用されます。
parts[index].geometry
スクリプト変形、Deform、3D投影より前のレイアウトを表します。Yは上が正です。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
local_center_x / local_center_y | number | canvas 軸比の変位 | 所有文字の変形前の輪郭範囲(ink bounds)の中心を原点としたパーツ中心。中立オフセットなし(0が文字中心上)。Y成分はY-up |
canvas_center_x / canvas_center_y | number | canvas 正規化位置 | パーツ自然位置(レイアウト後の中心)の canvas 座標 |
bounds_center_x / bounds_center_y | number | canvas 正規化位置 | 変形前のパーツ輪郭が占める範囲(ink bounds)の中心 |
bounds_width / bounds_height | number | 各 canvas 軸比 | ink bounds の幅・高さ |
1.12 ctx.bounding_box
InspectorでOFFのBBをスクリプトから有効化するときは、各辺・線幅・余白・色・塗り・opacity・cap・offsetなど、演出に必要な設定を明示してください。本体はOFFのBBについて現在のInspector値を読み込まないため、これらのフィールドをスタイルの初期値として参照しないでください。
基準矩形
2Dの基準矩形はGlobal回転前の変換済みFill境界を囲み、本文と同じGlobal回転を適用します。3Dではglobal layout plane上で組み立てて投影します。 その外側へmarginを加え、fillとstrokeをそれぞれ独立したoffsetでずらして描画します。
寸法の基準
次の寸法系フィールドはfontSizeに対する百分率です (描画: value * fontSizePx / 100。100.0 = fontSizeと同じ長さです)。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
enabled | boolean | - | 枠の描画を有効にする |
draw_top / draw_bottom / draw_left / draw_right | boolean | - | 各辺のストロークを描くか |
color | color | RGBA 0-1 | 枠線色 |
width | number | fontSize 百分率 | 枠線の太さ |
fill_enabled | boolean | - | 枠内塗りを有効にする |
fill_color | color | RGBA 0-1 | 枠内塗り色(アルファに fill_opacity を乗算) |
fill_opacity | number | 0-1 | 枠内塗りの不透明度乗数 |
start_cap / end_cap | string | 下記列挙 | 開いたパス端のキャップ |
margin_x / margin_y | number | fontSize 百分率 | テキスト bounds 外側への余白(各辺に加算) |
corner_radius | number | fontSize 百分率 | 四辺すべて有効時の角丸半径(矩形の半分で上限) |
fill_offset_x / fill_offset_y | number | fontSize 百分率 | 塗り矩形の平行移動 |
stroke_offset_x / stroke_offset_y | number | fontSize 百分率 | 枠線の平行移動(塗りと独立) |
start_cap / end_cap の値: butt / square / round / round_rev / triangle / triangle_rev
1.13 ctx.output
OnLayoutで読み書きする出力フィルタ・描画順制御です。Separation系のみ読み取り専用です。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
separation_enabled | boolean | - | Separation出力が有効か。読み取り専用 |
render_mode | string | - | 現在の出力スロット。default / separation_1 / separation_2。読み取り専用 |
targets_1 / targets_2 | string | - | 各Separation出力に割り当てられたターゲット指定文字列。読み取り専用 |
write_on_mode | string | - | Write-onの単位。characterまたはpart |
write_on_start | number | 0-1 | 表示区間の始端(正規化進行度) |
write_on_end | number | 0-1 | 表示区間の終端。start = 0かつend = 1のときフィルタなし(全表示) |
reorder_parts | boolean | - | trueのときパーツの描画順・reveal順を書き順(stroke order)にします。単一パーツ文字では見た目に影響しません |
manual_order_enabled | boolean | - | trueのときmanual_order_textでreveal / 描画順を上書きします |
manual_order_text | string | - | 手動順の指定(下記構文) |
force_disable_3d_projection | boolean | - | trueのとき、そのフレームの3D投影を最終的に無効化します。既定値はfalse(API Level 7) |
2D専用スクリプト
ctx.output.force_disable_3d_projection = trueを指定すると、プリセットが3D対応でも2D描画経路を使用します。Camera、Global、Character、Partに対するインスペクタ設定とキーフレームを含め、すべての3D操作が無視されます。現在の3D値が偶然ニュートラルであることを理由に設定せず、作品を2D専用にすることが明確な場合にだけ使用してください。
function OnLayout(ctx)
-- This effect intentionally guarantees 2D output.
ctx.output.force_disable_3d_projection = true
endWrite-on
表示対象は、単位ごとの1始まりの順位が[startLimit, endLimit]に入る要素に限られます。
startLimit = floor(write_on_start * N) + 1
endLimit = ceil(write_on_end * N)Nはwrite_on_mode == "character"のとき文字数、"part"のときパーツ数です。
順位の取り方:
| mode | 既定の順位 | manual_order_enabled 時 | reorder_parts のみ |
|---|---|---|---|
character | レイアウト順の文字 index(1..N) | 文字レベルの manual reveal 順 | 文字順位はレイアウト順のまま |
part | ctx.parts[index].index(1..N) | パーツの manual reveal 順 | stroke order の reveal 順 |
manual_order_text 構文
トークンの解釈
トークンはカンマまたは空白で区切ります。無効なトークンは無視され、同じパーツを 複数回指定した場合は最初の指定だけが採用されます。
| トークン | 意味 |
|---|---|
c<n> / C<n> | 1 始まり文字 n。その文字の全パーツを、当時のパーツ順(reorder_parts が true なら stroke order、false ならレイアウト順)で展開 |
p<n> / P<n> | 1 始まりグローバルパーツ n |
<n> | プレフィックス無し。パーツ index として解釈 |
<a>-<b> | 両端を含む範囲。両端は同じ種別(文字同士またはパーツ同士)。片方だけプレフィックスがある場合は他方に種別を継承。展開は昇順 |
例: "3,1,2"(パーツ 3→1→2)、"c1-c3"(文字 1〜3)、"p2-p5"(パーツ 2〜5)。
順序への反映
指定された要素は指定順で先頭へ移動します。未指定パーツは非表示にならず、 基準順序での相対順を保って後ろへ続きます。
順序は未変形のレイアウトと指定文字列から決まり、アニメーション後の空間位置から フレームごとに再計算されません。write_on_start/endは表示範囲を決め、 manual orderは要素の順序だけを変更します。
2Dの描画順にはmanual orderがそのまま適用されます。3Dでは各パーツの奥行きを優先し、 奥行きが同じパーツをmanual order、stroke order、レイアウト順の優先順位で並べます。 Write-onのreveal順は2D/3Dとも常にmanual orderに従います。
1.14 ctx.paths
ctx.pathsは対象を遅延取得するため、取得しなかったパーツのパスはLua側へコピーされません。ctx.pathsはOnPathの呼び出しの間だけ有効です。変数に保存して、あとの呼び出しで使うとエラーになります。
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
units_per_em | number | path unit/em | パス座標のスケール。常に1000 |
part(index) | function | - | 1始まりの通しパーツ番号から1パーツを取得。存在しなければnil |
character(index) | function | - | 1始まりの文字番号が所有する全パーツを、通しパーツ番号順の配列で取得 |
select(selector) | function | - | 選択書式に一致するパーツを、通しパーツ番号順の配列で取得 |
shape(number) | function | - | 1始まりの図形番号の図形が持つパーツを、1要素の配列で取得。その番号の図形が無ければ空の配列。part・character・selectは本文だけを対象にします |
select(selector)の選択書式
cは文字番号、pは通しパーツ番号、!は除外を表します。カンマで複数の条件を 指定でき、c3-5やp8-10のような範囲にも対応します。
local parts = ctx.paths:select("c1, p8-10, !p9")同じパーツを複数回取得した場合、同一フレーム内では同じ可変オブジェクトが返されます。
取得したパーツ
| フィールド | 型 | 単位 | 内容 |
|---|---|---|---|
index | integer | - | フレーム全体の1始まり通しパーツ番号 |
character_index | integer | - | 所属文字の1始まり番号 |
index_in_character | integer | - | 所属文字内の1始まりパーツ番号 |
line_index | integer | - | 所属行の1始まり番号 |
text | string | - | 所属文字が表すテキスト |
path | path | - | 変更対象の描画パス |
pathの編集
pathはパーツの描画輪郭を表す可変オブジェクトです。元の輪郭を消去・置換したり、 直線やベジェ曲線を追加したりできます。メソッドと座標系の詳細は 描画パス編集APIを参照してください。
1.15 ctx.glyphs
APIレベル: 9+
ctx.glyphs:declare(declaration)
ctx.glyphs:declare(declaration)は、パスと文字メトリクスを持つカスタムグリフを宣言し、 ctx.global.textへ埋め込める1文字のプレースホルダー文字列を返します。 レイアウト生成前に宣言を確定する必要があるため、OnPreLayoutでのみ呼び出せます。
この宣言は2つの座標空間を扱います。形状を描くpathは既存の描画APIと同じY-down、 形状を配置するadvance_*とboundsは既存のgeometry APIと同じY-upです。 したがって、縦書きで下方向へ900 units送る場合はadvance_y = -900と指定します。
| field | type | 既定値 | 単位・内容 |
|---|---|---|---|
path | MtDrawingPath | 空パス | 初期形状。Part中心原点、Y-down、1000 units = 1 em |
advance_x | number | 0.0 | 水平送り。右が正、1000 units = 1 em |
advance_y | number | 0.0 | 垂直送り。上が正、1000 units = 1 em。縦書きの下方向送りは負 |
bounds | number[4] | pathから自動算出 | {minimumX, minimumY, maximumX, maximumY}。ベースライン原点、Y-up、1000 units = 1 em |
boundsを省略すると、Part中心のXをadvance_x / 2へ置き、pathの最下端をベースラインへ 揃えます。自動boundsは{ advance_x / 2 + pathMinimumX, 0, advance_x / 2 + pathMaximumX, pathMaximumY - pathMinimumY }です。このためmt.svg_pathで view_boxを指定して中心原点へ正規化したSVGアイコンは、寸法を重複指定せずそのまま利用できます。 pathが空の場合は{0,0,0,0}になります。advance_yは送りメトリクスであり、横書きの自動配置には使いません。
縦書きでは、横書き用のベースライン位置にかかわらず、字面中心をadvance_yが作るセルの中央へ 配置します。trackingと個別marginsはセルの後方余白なので字面中心には含めません。 advance_y = 0の場合は現在の縦書きpen位置へ字面中心を置きます。
幅も高さも0のbounds(例:{0,0,0,0})は「描画はするが測らないグリフ」として扱い、 h_align / v_alignが参照する整列ボックスから除外します。送りを持たない装飾マーカーを テキスト末尾へ追加しても、行が整列端から動きません。整列は送りではなくboundsで決まるため、 負のmarginsで送りを打ち消してもこの除外の代わりにはなりません。
boundsを明示すると、その中心をPart中心として使用します。ベースラインより下が負、上が正です。 たとえばベースラインから上へ700 units、左右へ500 units広がる図形は { -500, 0, 500, 700 }と指定します。パス座標だけは既存の描画パスAPIと同じY-downです。
local icon = mt.svg_path("M 2 2 L 22 2 L 22 22 L 2 22 Z", {
view_box = { 0, 0, 24, 24 },
em_scale = 0.8,
})
function OnPreLayout(ctx)
local marker = ctx.glyphs:declare({
path = icon,
advance_x = 1000,
advance_y = -1000,
})
ctx.global.text = "A" .. marker .. "B"
endpathは宣言時点のsnapshotです。宣言後に元のパスを変更しても、宣言済みの形状は変わりません。 pathを省略しboundsを指定すると、送り幅とboundsだけを持つ不可視文字として使用できます。同じカスタムグリフを 複数箇所へ置く場合は、返されたmarkerを複数回テキストへ埋め込みます。 advance_xとadvance_yは、trackingと個別marginsを含まない純粋なグリフ送りです。 カスタムグリフにも通常文字と同じく、その文字の後方送りへtrackingと対応するmarginsを加算します。 このためadvance_x = 0でも、横書きではtracking + margins[i]分の送りが残ります。
プレースホルダーはホストがUnicode私用領域のU+E002から宣言順に割り当てます。U+E000と U+E001は内部の改行処理用に予約されています。カスタムグリフも通常文字と同じ文字数・パーツ数の 上限を消費します。hookまたはcommitが失敗したフレームでは、そのフレームの宣言をすべて破棄します。
1.16 ctx.inputs
ctx.inputsはInspectorのScript Inputsで設定した値を全コールバックへ渡す読み取り専用objectです。 各配列は1始まりで、要素数は固定です。
| フィールド | 型 | 要素数 | 内容 |
|---|---|---|---|
numbers | number[] | 14 | 単位を持たない数値入力 |
colors | MtColor[] | 8 | RGBA色入力 |
texts | string[] | 4 | 単一行のテキスト入力 |
booleans | boolean[] | 8 | checkboxの真偽値入力 |
local amount = ctx.inputs.numbers[1]
local primary = ctx.inputs.colors[1]
local caption = ctx.inputs.texts[1]
local enabled = ctx.inputs.booleans[1]ctx.inputs、各配列、色の各channelはすべて読み取り専用です。配列外のindexはnilを返します。
1.17 ctx.shapes
ctx.shapesは、本文とは別に置く図形(背景、枠、飾りなど)を扱います。図形はctx.global.textに 含まれず、送り幅・整列・折り返しといったレイアウトの流れに入りません。ctx.chars・ctx.char_count・ ctx.parts・ctx.part_countは本文だけを数え、図形はctx.shapes[number]・ctx.shape_countで扱います。
図形はOnPreLayoutで宣言し、OnLayoutとOnPathでは1始まりの図形番号で読みます。
ctx.shapes:declare(declaration)
図形を1つ宣言し、1始まりの図形番号(宣言した順)を返します。OnPreLayoutでのみ呼び出せます。 未知のフィールドや不正な値はエラーになります。
| field | type | 既定値 | 内容 |
|---|---|---|---|
path | MtDrawingPath | 空パス | 図形の輪郭。図形の位置が原点、Y-down、1000 units = 1 em(カスタムグリフのpathと同じ座標系) |
layer | string | "back" | "back"は本文より後ろ、"front"は本文より前に描く |
parent | integer | なし | 親にする図形の番号。先に宣言した図形(このdeclareより前の戻り値)に限ります。省略すると親なしです |
camera | integer | 親のカメラ。なければなし | この図形を3Dで投影するカメラの番号。先にctx.shape_cameras:declare()で宣言したものに限ります。親のある図形は親のカメラを引き継ぎ、親と違う番号を指定するとエラーです(カメラのない親の子も指定できません)。カメラのない図形は、これまでどおりキャンバスに固定されます |
pathは宣言時点のsnapshotです。同じ層の図形は、z_indexが小さい順、同じなら宣言した順に重なります。
parentを指定した図形は、親に対する相対の位置・回転・拡大・伸縮になります。子の変形は、親の変形を受けた座標系で働きます。
offset_x/offset_yが0.5のとき、子は親の位置(親のパスの原点)に重なります。ずれ量は、親の拡大・回転・伸縮を受けます。- 子の
rotation・scale・stretch_*・pivot_*は、子自身の位置を中心に、親の座標系で働きます。親が非等方に伸縮していると、回転した子は歪んで見えます。 - 親の
opacity・fill・stroke・shadow・blur・textureは、子に引き継がれません。各図形が自分で設定します。 - 子も親になれます(祖父母まで辿ります)。親を
opacity = 0にして、子だけを見せることもできます。 - 親の拡大が
0になると、子も大きさを失い、何も描かれません。連鎖の倍率は倍精度で累積し、その図形の描画用の行列が単精度の範囲を超えるときも、その図形は何も描かれません(途中の図形が範囲を超えても、後ろの図形の倍率が戻れば、後ろの図形は描かれます)。 - 親に使えるのは図形だけで、本文の文字は親にできません。
local rectangle = mt.svg_path("M -500 -300 L 500 -300 L 500 300 L -500 300 Z")
function OnPreLayout(ctx)
local background = ctx.shapes:declare({ path = rectangle })
local frame = ctx.shapes:declare({ path = rectangle, layer = "front" })
end図形の設定
ctx.shapes[number]はOnLayoutとOnPathで参照できます。OnLayoutでは次のフィールドを、ctx.chars[index]と 同じ規則で設定できます。
| フィールド | 型 | 内容 |
|---|---|---|
index | integer | 図形番号。ctx.shapes:declareの戻り値と同じ値 |
offset_x / offset_y | number | 位置のずれ。0.5でずれなし。何も設定しない図形は、キャンバスの中央に出ます |
pivot_x / pivot_y / scale / stretch_x / stretch_y / rotation / z / yaw / pitch | number | ctx.chars[index]と同じ変形。図形は自分の位置(パスの原点)を中心に回転・拡縮し、pivot_*もそこからの変位です |
opacity | number | 不透明度の倍率(0〜1) |
parent | integer | 読み取り専用。ctx.shapes:declareで指定した親の図形番号。親がないときは0 |
camera | integer | 読み取り専用。この図形を投影するカメラの番号(親から引き継いだ番号を含む)。カメラがないときは0 |
z_index | number | 描画順の値(既定値0)。同じ層の中で、小さいものから順に描かれ(大きいものが手前)、同じ値は宣言した順です。layerの背面・前面は越えません。+inf・-infは最大・最小として並び、NaNは代入するとエラーです。親子関係とは無関係です |
fill / stroke / shadow / texture / blur | table | 個別の見た目。ctx.chars[index]と同じ項目 |
path | path | 図形の輪郭。OnLayoutのみ。宣言したパスから始まり、path:assign(p)などで直接編集する。毎フレーム、宣言したパスへ戻る |
pathは代入できません。shape.path:assign(p)のように、渡したパスをコピーして置き換えます。編集したパスだけが そのフレームで使われます。ctx.paths:shape(number)(OnPath)で、OnLayoutで編集した後のパスを、さらに編集できます。
function OnLayout(ctx)
local shape = ctx.shapes[1]
shape.path:assign(drawLights(ctx))
shape.opacity = 0.8
shape.fill.use = true
shape.fill.color = { r = 1.0, g = 0.5, b = 0.7, a = 1.0 }
endctx.shape_cameras:declare()
図形用のカメラを1つ宣言し、1始まりのカメラ番号(宣言した順)を返します。OnPreLayoutでのみ呼び出せ、上限は16個です。 図形用のカメラは、本文のカメラ(ctx.camera)とは別のカメラです。本文のカメラ、Global、本文の3D姿勢は図形に影響せず、 図形用のカメラも本文に影響しません。
ctx.shape_cameras[number]はOnLayoutで参照・設定できます。値は毎フレーム、本文のカメラの既定値から始まるので、 動かしたいフレームごとに書きます。
| フィールド | 型 | 既定値 | 内容 |
|---|---|---|---|
target_x / target_y | number | 0.5 / 0.5 | カメラの注視点(キャンバスの割合)。target_yは上向きが正 |
yaw / pitch | number | 0 | カメラの軌道角(度)。ctx.cameraと同じ向き |
perspective | number | 0.5 | 遠近感の強さ。0〜1に丸められます |
zoom | number | 1 | ズーム倍率 |
lens_shift_x / lens_shift_y | number | 0 | レンズシフト(キャンバスの割合)。lens_shift_yは上向きが正 |
数値は有限である必要があり、NaN・infを書くとエラーです。位置・姿勢・カメラの値が数として扱えなくなった図形(z = 1e308など)は、何も描かれません。
カメラを指定した図形(ctx.shapes:declare({ camera = number }))は、yaw・pitch・zを含む自分の姿勢が3Dになり、 そのカメラで投影されます。
- 各図形は自分の位置(パスの原点)を中心に回ります。親の姿勢は、子の位置と向きに掛かります。親を
pitchで倒すと、親の上方向にずらした子は奥行き方向に動きます。 - 同じ親子の木は、1つのカメラで投影されます。子が
cameraを省略すれば親のカメラを使い、親と違う番号を指定するとエラーです。 - カメラのない図形では、
yaw・pitch・zは見た目に効きません。 scaleは図形の面内(x・y)にだけ効き、奥行きには効きません。縮尺を変えた親の下で、回転した子は、せん断(斜めに歪むこと)します。回転した図形に付ける子の形を保ちたいときは、scaleを1のままにして、大きさをパスの寸法と、子のoffset(親の長さ)に直接反映してください。- 描画順は、層、
z_indexの順で決まり、同じ層・同じz_indexの中で、同じカメラの図形どうしだけ奥行きの遠い順に並びます。カメラの違う図形、カメラのない図形の位置は動かしません。 - 線幅、影、ぼかしの大きさは、図形の位置の奥行きの縮尺に従います。
function OnPreLayout(ctx)
local view = ctx.shape_cameras:declare()
local card = ctx.shapes:declare({ path = rectangle, camera = view })
end
function OnLayout(ctx)
ctx.shape_cameras[1].pitch = 20
ctx.shapes[1].yaw = ctx.time * 90
end本文と違う扱い
- レイアウトの流れ(送り幅、整列、折り返し)に入りません。
- Write On、Gradient、Bounding Box、Deform、Crayon、ビューアでの選択の対象になりません。
- Globalの変形と本文の3Dのカメラの影響を受けません。図形はキャンバスに固定され、
ctx.shape_camerasのカメラを指定した図形だけが、そのカメラで3Dに投影されます。 - 手動の順序(
manual_order_text)に図形の番号は書けません。描画順は、layer、z_index、宣言の順で決まります。本文を図形の間に挟むことはできません。 - 文字数・パーツ数の上限を使いません。図形の数の上限は、全プリセット共通で
ctx.meta.limits.max_shapesです。上限を超えた宣言はエラーです。 - Output Separationの影響は受けます。
- 制限事項: 本文のCrayon(実験的機能)の線は、
layer = "front"の図形より手前に描かれます。 mt.layout.place_2d・mt.layout.get_canvas_position_2d・mt.layout.canvas_to_offset_2dは、図形を文字と同じように受け取れます。アンカーは図形の位置です。親のある図形では、親の変形を通した位置を扱い、place_2dとcanvas_to_offset_2dは親の座標系のoffsetを返します(親の大きさが0のときはエラー)。- 本文の見た目の設定(文字色、縁取り、影、ぼかし、glow、テクスチャ)は図形にも掛かります。掛けたくない設定は、
OnLayoutでctx.shapes[number]へ設定して上書きします。
対象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。アウトロの進行度 |
この付録では、スクリプトを作成するときに迷いやすい問題と、その対処方法を説明します。
1. 個別にscaleした文字の送りを整える
1.1 どのようなときに必要か
OnLayoutで文字ごとにscaleやstretchを変更し、変更後の大きさに合わせて文字を 並べ直したいときに必要です。
1.2 起きる問題
文字の送りは、OnLayoutで個別の変形を加える前に決まります。そのため、文字ごとに scaleやstretchを変更しただけでは、次の問題が起きることがあります。
- 大きくした文字が隣の文字と重なります。
- 小さくした文字の左右に余分な間隔が残ります。
- 文字の基準位置がベースラインからずれます。
これは、文字がgeometry.bounds_centerを中心に拡大・縮小される一方で、元の送りが そのまま使われるためです。
1.3 対処方法
文字のサイズ、回転、pivotを変更したあと、OnLayoutの最後に mt.layout.reflowを呼び出してください。
function OnLayout(ctx)
for index = 1, ctx.char_count do
local character = ctx.chars[index]
character.scale = 0.8 + index * 0.05
end
-- 変形後の文字サイズに合わせて送りを整える
mt.layout.reflow(ctx)
end文字間に追加の余白が必要な場合は、第2引数に間隔を指定します。対象文字や固定する文字を 限定する場合は、configを指定します。引数の詳細は mt.layout.reflowを参照してください。
1.4 仕組み
mt.layout.reflowは、横書きと縦書きの組版原点を使い、シェーピング、kerning、tracking、 marginsによる間隔を保ったまま、現在のscale、stretch、rotation、pivotを反映して文字を 並べ直します。個々のインク輪郭の間隔を均一にする機能ではありません。
pivotが0.5でscaleだけを変更する場合、自然座標上の点Pは次式で移動します。 Cはgeometry.bounds_center、sはscale×stretch、dはoffset-0.5です。
P' = C + s × (P - C) + d
d = P'(目標) - C - s × (P - C)この式をスクリプト内で直接計算する必要はありません。mt.layout.reflowは、rotation、pivot、 縦書き、非正方形canvasを含む完全な2D文字変換を考慮して組版原点を整列します。
2. グラデーションの範囲と向きを調整する
2.1 どのようなときに必要か
start_position、end_position、angleを変更したときに、グラデーションの開始位置、 終了位置、色の向きが想定と合わない場合に確認してください。
2.2 起きる問題
start_positionとend_positionは、canvas全体を基準とする座標ではありません。 グラデーションのangleも、単純にバウンディングボックスの幅や高さだけを使って 計算されるわけではありません。
これらをcanvas座標として扱うと、テキストを移動・回転・拡大したときや、斜め方向の グラデーションを設定したときに、色の切り替わる位置が想定からずれて見えます。
2.3 対処方法
start_positionとend_positionは、変形後のテキスト全体をangle方向に見た範囲に 対する比率として指定してください。
- テキストの端から端までグラデーションを適用する場合は、
start_position = 0.0、end_position = 1.0にします。 - テキストの内側で色を切り替える場合は、
start_positionを大きくし、end_positionを小さくします。標準設定の0.2と0.8では、両端から20%内側が グラデーション区間になります。 angle = 0では左から右、angle = 90では上から下、angle = -90または270では下から上へ色が変化します。
start_position側にはfill色、end_position側にはend_colorが割り当てられます。 angleの向きは座標の定義と同じです。
2.4 基準となる範囲
グラデーションは、OnLayoutで文字やパーツへscale、rotation、offsetなどを適用した 後のテキスト全体のバウンディングボックスを基準とします。
- 2D描画時: 変形後の全文字・パーツのパスを囲むcanvas上の2Dバウンディングボックスです。
- 3D投影時: カメラ投影の影響を受けない3Dレイアウト平面上のバウンディングボックスです。 キャラクターごとに投影座標が計算されるため、カメラが動いてもグラデーションの位置は 文字に対してずれません。
2.5 基準線の計算方法
グラデーションの0.0〜1.0の基準線は、バウンディングボックスをangle方向へ投影したときの 最近端と最遠端を結ぶ線分です。斜め方向では、矩形の幅や高さではなく、指定方向へ最も 突き出た位置と、その反対側の位置が境界になります。
バウンディングボックスの中心をC、angleの方向ベクトルをD、4つの頂点をP_iとすると、 各頂点の射影値は次式で求められます。
proj_i = (P_i - C) · D射影値の最小値をminProj、最大値をmaxProjとすると、基準線の開始点bbP0と 終了点bbP1は次のようになります。
bbP0 = C + D * minProj
bbP1 = C + D * maxProjstart_positionをt_s、end_positionをt_eとすると、実際の開始点P0と終了点P1は 基準線上の次の位置になります。
P0 = bbP0 + (bbP1 - bbP0) * t_s
P1 = bbP0 + (bbP1 - bbP0) * t_e3. コールバック間で値を受け渡す
3.1 どのようなときに必要か
OnPreLayoutで上書きする前の値を、同じフレームのOnLayoutでも使いたい場合に必要です。 たとえば、ホストのScaleを文字サイズではなくアニメーションの移動量を決める係数として使う場合が 該当します。
3.2 起きる問題
OnPreLayoutでctx.global.scaleを1.0に変更すると、OnLayoutから参照できるのは 変更後の値です。上書き前のホスト値は復元できないため、その値を使った計算ができなくなります。
一方、OnPreLayoutで上書きしていない値は、OnLayoutのctx.globalからそのまま読めます。 たとえばtrackingやline_spacingは、退避せずに使う場所で直接参照してください。
3.3 対処方法
上書き前の値を関数の外側で宣言したlocal変数へ保存し、OnLayoutから参照してください。 Luaの実行環境はインスタンスごとに1つ作成され、スクリプトが再読み込みされるまで維持されるため、 同じ変数をコールバック間で参照できます。
local scaleKnob = 1.0
function OnPreLayout(ctx)
-- ホストのScaleを退避してから、文字サイズへの影響を打ち消す
scaleKnob = math.max(ctx.global.scale, 0.05)
ctx.global.scale = 1.0
end
function OnLayout(ctx)
local travel = 0.07 * scaleKnob
for index = 1, ctx.char_count do
ctx.chars[index].offset_y = ctx.chars[index].offset_y + travel
end
endこの受け渡しは、上書き前の値が必要な場合だけ使ってください。不要な値まで保存すると、 スクリプトの状態が増え、処理の流れが分かりにくくなります。
3.4 フレーム間の状態保持には使わない
関数の外側で宣言した変数は、コールバック間だけでなくフレーム間でも値を保持します。しかし、 ホストはシーク、レンダリング順序の変化、並列描画などにより、フレームを時間順に評価するとは 限りません。
前フレームの値を使った差分計算や累積を行うと、再生時とレンダリング時で結果が変わることが あります。各フレームの結果は、そのフレームのctx.timeから一意に決まるようにしてください。 関数の外側では、定数やコールバック間で同一フレーム内に受け渡す値だけを保持します。