-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathutils.ts
More file actions
273 lines (249 loc) · 7.76 KB
/
utils.ts
File metadata and controls
273 lines (249 loc) · 7.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
import type { InstalledFontData } from 'plainly-types';
/**
* @function isWin
* @description Determines if the current OS is Windows
* @returns {boolean} True if the OS is Windows, false otherwise
*/
function isWin(): boolean {
return $.os.indexOf('Win') !== -1;
}
/**
* Joins multiple path segments into a single path string.
*
* @param {...string} args - The path segments to join.
* @returns {string} The combined path string, using the appropriate
* separator for the current OS ('\\' for Windows, '/' for Mac).
*/
function pathJoin(...args: string[]): string {
const path = isWin() ? '\\' : '/';
return args.join(path);
}
/**
* @function getAllComps
* @description Get all comp items in a given After Effects project
* @param {Project} project - The After Effects project object
* @returns {Array<CompItem>} An array of CompItem objects
*/
function getAllComps(project: Project): Array<CompItem> {
const comps: CompItem[] = [];
for (let i = 1; i <= project.numItems; i++) {
const item = project.item(i);
if (item instanceof CompItem) {
comps.push(item);
}
}
return comps;
}
/**
* @function getTextLayersByComp
* @description Get all text layers in a given After Effects comp
* @param {CompItem} comp - The After Effects comp object
* @returns {Array<TextLayer>} An array of TextLayer objects
*/
function getTextLayersByComp(comp: CompItem): Array<TextLayer> {
const layers: TextLayer[] = [];
for (let i = 1; i <= comp.numLayers; i++) {
const layer = comp.layer(i);
if (layer instanceof TextLayer) {
layers.push(layer);
}
}
return layers;
}
function getFolderPath(folder: FolderItem): string {
if (folder.parentFolder === null || folder === app.project.rootFolder) {
return '';
}
// Recursively build the folder path
const parentPath = getFolderPath(folder.parentFolder);
return pathJoin(parentPath, folder.name);
}
/**
* @function getCompLayerNames
* @description Get all layer names in a given After Effects comp by ID
* @param {string} compId - The ID of the comp
* @returns {string} JSON array of layer names
*/
function getCompLayerNames(compId: string): string {
const comp = app.project.itemByID(Number(compId));
if (!comp || !(comp instanceof CompItem)) return JSON.stringify([]);
const names: string[] = [];
for (let i = 1; i <= comp.numLayers; i++) {
names.push(comp.layer(i).name);
}
return JSON.stringify(names);
}
function getInstalledFontsByPostScriptName(
postScriptName: string,
): string | undefined {
try {
const fontObjects = app.fonts.getFontsByPostScriptName(postScriptName);
if (!fontObjects || fontObjects?.length === 0) return undefined;
const fontData: InstalledFontData[] = [];
for (let i = 0; i < fontObjects.length; i++) {
const font = fontObjects[i];
fontData.push({
isSubstitute: font.isSubstitute,
fontLocation: font.location,
});
}
return JSON.stringify(fontData);
} catch {
return undefined;
}
}
function getInstalledFontsByFamilyNameAndStyleName(
familyName: string,
styleName: string,
) {
try {
const fontObjects = app.fonts.getFontsByFamilyNameAndStyleName(
familyName,
styleName,
);
if (!fontObjects || fontObjects.length === 0) return undefined;
const fontData: InstalledFontData[] = [];
for (let i = 0; i < fontObjects.length; i++) {
const font = fontObjects[i];
fontData.push({
isSubstitute: font.isSubstitute,
fontLocation: font.location,
});
}
return JSON.stringify(fontData);
} catch (error) {
return undefined;
}
}
/**
* Deselects every currently selected layer across all compositions in the active project.
*
* Iterates through all `CompItem` instances in `app.project`, aggregates their `selectedLayers`,
* and sets each layer's `selected` property to `false`.
*
* @returns {void}
*/
function unselectAllLayers(): void {
const comps = getAllComps(app.project);
let selectedLayers: Layer[] = [];
for (let i = 0; i < comps.length; i++) {
const comp = comps[i];
selectedLayers = selectedLayers.concat(comp.selectedLayers);
}
for (let i = 0; i < selectedLayers.length; i++) {
const layer = selectedLayers[i];
layer.selected = false;
}
}
/**
* Selects a layer in the active project by its numeric ID.
*
* Uses `app.project.layerByID` after parsing the provided string to base-10 integer. If a layer
* with the given ID exists, its `selected` property is set to `true`; otherwise the function exits silently.
*
* @param {string} layerId - The string representation of the layer's numeric ID (e.g. value from `Layer.id`).
* @returns {void}
* @example
* // Select a layer whose id is 1234
* selectLayer('1234');
*/
function selectLayer(layerId: string): void {
unselectAllProjectItems();
unselectAllLayers();
const layer = app.project.layerByID(parseInt(layerId, 10));
if (layer) {
// open the comp that contains the layer, so it is visible to the user in timeline
const comp = layer.containingComp;
comp.time = layer.inPoint;
const viewer = comp.openInViewer();
if (viewer?.active === false) viewer.setActive();
layer.selected = true;
}
}
/**
* Deselects all items in the project panel tree.
*
* Iterates through all items in `app.project.items` and sets each item's `selected` property to `false`.
*
* @returns {void}
*/
function unselectAllProjectItems(): void {
for (let i = 1; i <= app.project.numItems; i++) {
const item = app.project.item(i);
item.selected = false;
}
}
/**
* Selects a composition in the active project by its numeric ID.
*
* Uses `app.project.itemByID` after parsing the provided string to base-10 integer. If a composition
* with the given ID exists, it is opened in a viewer and its `selected` property is set to `true`;
* otherwise the function exits silently.
*
* @param {string} compId - The string representation of the composition's numeric ID (e.g. value from `CompItem.id`).
* @returns {void}
* @example
* // Select a composition whose id is 5678
* selectComp('5678');
*/
function selectComp(compId: string): void {
unselectAllProjectItems();
unselectAllLayers();
const comp = app.project.itemByID(parseInt(compId, 10));
if (comp instanceof CompItem) {
const viewer = comp.openInViewer();
comp.selected = true;
if (viewer?.active === false) {
viewer.setActive();
}
}
}
/**
* Selects a file item in the active project by its numeric ID.
*
* Uses `app.project.itemByID` after parsing the provided string to base-10 integer. If a file
* with the given ID exists, its `selected` property is set to `true`; otherwise the function exits silently.
*
* @param {string} fileId - The string representation of the file's numeric ID (e.g. value from `FootageItem.id`).
* @returns {void}
* @example
* // Select a file whose id is 91011
* selectFile('91011');
*/
function selectFile(fileId: string): void {
unselectAllProjectItems();
unselectAllLayers();
const file = app.project.itemByID(parseInt(fileId, 10));
if (file) {
file.selected = true;
}
}
/**
* Generates a UUID (Universally Unique Identifier) string in the format 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.
*
* @returns {string} A randomly generated UUID string.
* @example
* const newUuid = uuid();
* console.log(newUuid); // Outputs something like '3f2504e0-4f89-11d3-9a0c-0305e82c3301'
*/
function uuid(): string {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
const r = (Math.random() * 16) | 0,
v = c === 'x' ? r : (r & 0x3) | 0x8;
return v.toString(16);
});
}
export {
getAllComps,
getFolderPath,
getInstalledFontsByFamilyNameAndStyleName,
getInstalledFontsByPostScriptName,
getCompLayerNames,
getTextLayersByComp,
isWin,
pathJoin,
selectLayer,
selectComp,
selectFile,
uuid,
};