JavaScript Layers
JavaScript 可用於多種 Layers,包括 JavaScript Utility、JavaScript Shape、JavaScript Deformer、JavaScript Emitter、JavaScript Modifier 和 JavaScript Emitter,以在 Cavalry 中設定多種 Attribute 類型。
可以透過表達式寫入的主要資料類型有:
| 名稱 | attrType | 描述 |
|---|---|---|
| Double | double | 帶有小數位的數字。例如 4.153。 |
| Double2 | double2 | 一組兩個 double。例如 Position 103.453, 487.543。 |
| Double3 | double3 | 一組三個 double。例如 Position (2.5D) 103.453, 487.543, 50.730。 |
| Int | int | 不帶小數點的整數。例如 4。 |
| Int2 | int2 | 一組兩個整數。例如 Composition Resolution 1920, 1080。 |
| Bool | bool | 具有兩種狀態的核取方塊——1 或 0(開/關)。 |
| String | string | 可包含字母數字字元和符號。 |
| Color | color | 包含 R、G、B 和 A 值的 Attribute。 |
| Point Data | pointData | 由 Distributions 產生的點。參見 Using Point data。 |
| Asset | assetId | 接受 .json、.txt 或 .csv Asset。參見 Using Assets。 |
| Layer | layerId | 接受任何 Layer。參見 Using Layer data。 |
這意味著支援 JavaScript 的 Layers 可以連接到 Cavalry 中的上述任何資料類型。
連接兩個不相容的資料類型(例如表達式返回 int,但 JavaScript 連接到 string),將觸發嘗試自動轉換資料類型,但強烈建議正確匹配輸出類型,以便更好地控制浮點精度等因素。
以上所有類型也可作為輸入,並可透過指令碼中的 Attribute 名稱引用。要新增另一個 Attribute 作為變數,請點選 UI 底部的 + 按鈕並選擇相關資料類型。然後可以從具有匹配資料類型的另一個 Attribute 建立輸入連線。預設情況下,變數名稱是字母 n 後跟數字,例如 n0、n1。但是,可以透過右鍵點選 Attribute 並選擇 Rename 來重新命名。
變數名稱區分大小寫,不能包含空格。
JavaScript 匯入一個 Context Module,其中包含幾個與 Duplicator 搭配使用的有用成員。
ctx.index- Duplicator 的 Index。ctx.count- Duplicator 的 Count。ctx.positionX/ctx.positionY- Duplicator 點的位置。ctx.layerId- 請求 JavaScript Layer 進行計算的 Layer 的 id。ctx.attributeId- 請求 JavaScript Layer 進行計算的 Attribute 的 id。
有關使用這些值的範例,請參閱 Create > Demo Scenes > JavaScript > Position to Color 預設。
複雜資料類型(color、int2、double2)是遵循以下模式的簡單 JavaScript 物件:
let color = { r: 200, g: 100, b: 50, a: 255};let someDouble2 = { x: 200.4, y: 55.6};為簡單起見,可以修改或返回輸入值。
使用此 Layer 編寫 JavaScript 表達式的主要規則是必須返回一個值。例如,以下表達式呼叫一個函式,該函式返回一個值:
function toCelsius(fahrenheit) { return (5/9) * (fahrenheit-32);}toCelsius(n0);在全域級別設定變數時,請使用 var 而非 let/const。因為 JavaScript Layers 每幀執行,使用 let/const 全域宣告將在表達式第二次執行時失敗,因為變數已存在且無法重新賦值。
Using Assets
标题为“Using Assets”的章节JavaScript 可以利用 JSON/Text/CSV Assets(CSV Asset 包括 Google Sheets 和 Microsoft Excel)。要與 JavaScript Layers 一起使用這些 Asset 類型,請點選 + 按鈕並選擇 Add Text/JSON/CSV Asset。這將建立一個新的 Attribute,它可以接收支援的 Asset 作為輸入。
- Text Assets 將作為字串載入。
- JSON Assets 將作為 JSON 物件字面量載入。
- CSV Assets 將作為 JSON 物件字面量載入。
- 頂層 Object 屬性都將與欄名匹配。
- 每欄包含:
rows- 列資料陣列(數字或字串)。min- 欄中的最小數值(如果欄為數字)。max- 欄中的最大數值(如果欄為數字)。
// 列印連接到 Attribute 'n1' 的 CSV 的所有欄名。var columns = Object.keys(n1);for (var columnName of columns) { console.log(columnName);}// 返回連接到 Attribute 'n1' 的 CSV/Google Sheet 中標題為 'Cavalry' 的欄的最大值。n1.Cavalry.max;// 如果欄標題包含空格,例如 'Cavalry Users'。n1["Cavalry Users"].min;// 返回連接到 Attribute 'n1' 的 CSV/Google Sheet 中標題為 'Cavalry Users' 的欄的所有值的總和。function setSum() { let total = 0; for (let row of n1["Cavalry Users"].rows) { total += Number(row) } return total;}setSum();// 給定一個連接到 Attribute 'n1' 的 JSON asset,輸出 "title" 鍵的值。// 將 JavaScript Utility 連接到 Text Shape 的 String。/* example.json 的內容{ "data": { "title": "My Title", "body": "This is some body text." }}*/n1.data.title請注意,作為 Asset 使用時,僅支援 Excel 檔案的第一個標籤頁。
Using Point data
标题为“Using Point data”的章节- 建立一個 JavaScript Deformer。
- 點選其 Attribute Editor UI 底部的
+按鈕,新增選擇 ‘Add Point Data’ 以新增新的 Dynamic Attribute。 - 建立一個 Duplicator。
- 右鍵點選 Distribution Attribute 並選擇
Reveal Generator。 - 刪除 Duplicator(保留 Grid Distribution)。
- 連接 gridDistribution.id→javaScriptDeformer.n1(這是在步驟 2 中新增的新 Point Data Attribute)。
- 將 JavaScript 輸入中的程式碼替換為以下之一:
console.log(n1.points[0].position.x);或;console.log(n1.points.length);
- 建立一個 Shape。
- 連接 javaScriptDeformer.id→shape.deformers。這是 JavaScript Deformer 進行計算所必需的。
將播放頭步進到下一幀以將值列印到 JavaScript Console。第一個範例將輸出第一個 pointId 的 position.x(變更 [0] 中的值以返回其他 pointId),而第二個範例將返回 Distribution 中的點數(預設 3x3 網格為 9 個)。
Using Layer data
标题为“Using Layer data”的章节連接的 Layer 的類型決定了可用的物件:
- Drawable(例如 Null、Falloff)- 將提供一個 layer 物件,包含以下 2D World Space Transform 變數:
- position(例如
n1.layer.position、n1.layer.position.x) - rotation(例如
n1.layer.rotation、n1.layer.rotation.z) - scale(例如
n1.layer.scale、n1.layer.scale.x)
- position(例如
- Shape(例如 Rectangle、Duplicator)- 將提供一個
mesh屬性(例如n1.mesh),表示 local space 中的 mesh 層級。mesh屬性是來自 Cavalry Module 的 Mesh class 的實例。
使用 Layer 動態輸入時,使用 hasInput 來確定是否連接了 Layer。例如,這可用於防止嘗試讀取不存在的 mesh 資料。
// 假設 'n1' 是一個 Layer 動態輸入。console.log(n1.hasInput);// 如果 Layer 連接到 'n1',則返回 true。JavaScript 不區分 2D 和 2.5D Layers,因此對 2D Layers 使用 rotation.z。
// Closest Point on Path 範例。// 將其貼上到 JavaScript Editor 中,然後點選 'Run Script'。// 建立一個 Null 和兩個 Shapesconst nullId = api.create("null", "Move Me!!");const ellipse1Id = api.primitive("ellipse", "Ellipse");const ellipse2Id = api.primitive("ellipse", "Path");api.setFill(ellipse2Id, false);api.setStroke(ellipse2Id, true);api.set(ellipse2Id, {"generator.radius": [350,350]});// 建立一個 JavaScript Utility。const jsUtil = api.create("javaScript");// 新增動態 Attributes 和表達式。api.addDynamic(jsUtil, "array", "layerId");api.addDynamic(jsUtil, "array", "layerId");const expression = 'function getPoint() {\n\xa0\xa0\xa0\xa0let toPt = n2.layer.position;\n\xa0\xa0\xa0\xa0let closestPoint = n1.path.findClosestPoint(toPt.x, toPt.y);\n\xa0\xa0\xa0\xa0return closestPoint.position;\n};\ngetPoint();'api.set(jsUtil, {"expression": expression});// 建立連線。api.connect(ellipse2Id, "id", jsUtil, "array.1");api.connect(nullId, "id", jsUtil, "array.2");api.connect(jsUtil, "id", ellipse1Id, "position");Output dependent calculations
标题为“Output dependent calculations”的章节JavaScript Layers 是 Cavalry 中唯一知道具體是哪個 Layer 和 Attribute 觸發計算的地方。此資訊可用於根據正在計算哪個連線來輸出不同的值。使用 ctx.layerId 和 ctx.attributeId 屬性來存取此資訊。
// 在此範例中,假設一個 JSON Asset 連接到 JavaScript Layer 的 n1 Attribute。function getText() { if (ctx.layerId == "textShape#1") { // 如果 textShape#1 向 JavaScript 請求值,返回給定的 JSON 值 return n1["colors"]["Green"]; } else if (ctx.layerId == "textShape#2") { // 如果 textShape#2 向 JavaScript 請求值,返回不同的 JSON 值 return n1["colors"]["Yellow"]; } return "None";}getText();表達式的錯誤將列印到 JavaScript Console。
透過 Cmd/Ctrl + Return 執行表達式時,需要輸出連線才能使表達式執行。