-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathISO_RandomizePositionWithinRange.jsx
More file actions
173 lines (128 loc) · 5 KB
/
Copy pathISO_RandomizePositionWithinRange.jsx
File metadata and controls
173 lines (128 loc) · 5 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
// ISO_RandomizePositionWithinRange.jsx
// Artist: https://www.jasonfletcher.info/
// Code generated by ChatGPT-5.5
// Date: July 16, 2026
// Description: This After Effects script will randomize the X and Y Position of the selected layers within user-defined ranges.
(function () {
app.beginUndoGroup("Randomize X/Y Position");
try {
var activeItem = app.project.activeItem;
var selectedLayers;
var dlg;
var grp;
var row;
var result;
var minX, maxX, minY, maxY;
var i;
var layer;
var pos;
var newPos;
var processed = 0;
var skipped = 0;
var currentTime;
var keyIndex;
if (!(activeItem instanceof CompItem)) {
alert("Please open and activate a composition.");
return;
}
selectedLayers = activeItem.selectedLayers;
if (selectedLayers.length === 0) {
alert("Please select one or more layers.");
return;
}
// ---------------------------------------------------------------------
// GUI
// ---------------------------------------------------------------------
dlg = new Window("dialog", "Randomize X/Y Position");
grp = dlg.add("group");
grp.orientation = "column";
grp.alignChildren = ["fill", "top"];
row = grp.add("group");
row.add("statictext", undefined, "Minimum X:");
var txtMinX = row.add("edittext", undefined, "0");
txtMinX.characters = 10;
row = grp.add("group");
row.add("statictext", undefined, "Maximum X:");
var txtMaxX = row.add("edittext", undefined, String(Math.round(activeItem.width)));
txtMaxX.characters = 10;
row = grp.add("group");
row.add("statictext", undefined, "Minimum Y:");
var txtMinY = row.add("edittext", undefined, "0");
txtMinY.characters = 10;
row = grp.add("group");
row.add("statictext", undefined, "Maximum Y:");
var txtMaxY = row.add("edittext", undefined, String(Math.round(activeItem.height)));
txtMaxY.characters = 10;
var btnGroup = dlg.add("group");
btnGroup.alignment = "center";
btnGroup.add("button", undefined, "OK", { name: "ok" });
btnGroup.add("button", undefined, "Cancel", { name: "cancel" });
result = dlg.show();
if (result !== 1) {
return;
}
minX = parseFloat(txtMinX.text);
maxX = parseFloat(txtMaxX.text);
minY = parseFloat(txtMinY.text);
maxY = parseFloat(txtMaxY.text);
if (isNaN(minX) || isNaN(maxX) || isNaN(minY) || isNaN(maxY)) {
alert("Please enter valid numeric values.");
return;
}
if (minX > maxX) {
alert("Minimum X cannot be greater than Maximum X.");
return;
}
if (minY > maxY) {
alert("Minimum Y cannot be greater than Maximum Y.");
return;
}
currentTime = activeItem.time;
// ---------------------------------------------------------------------
// Process Layers
// ---------------------------------------------------------------------
for (i = 0; i < selectedLayers.length; i++) {
layer = selectedLayers[i];
if (layer === null || layer.locked) {
skipped++;
continue;
}
pos = layer.property("Transform").property("Position");
if (pos === null || pos.expressionEnabled) {
skipped++;
continue;
}
// Get the current value (interpolated if animated)
newPos = pos.valueAtTime(currentTime, false);
// Randomize X and Y
newPos[0] = minX + Math.random() * (maxX - minX);
newPos[1] = minY + Math.random() * (maxY - minY);
if (pos.numKeys > 0) {
keyIndex = pos.nearestKeyIndex(currentTime);
// If a keyframe already exists at the current time, overwrite it.
if (Math.abs(pos.keyTime(keyIndex) - currentTime) < 0.0001) {
pos.setValueAtKey(keyIndex, newPos);
} else {
// Otherwise create a new keyframe.
pos.setValueAtTime(currentTime, newPos);
}
} else {
// No keyframes yet, so create the first one.
pos.setValueAtTime(currentTime, newPos);
}
processed++;
}
alert(
"Randomize X/Y Position Complete\n\n" +
"Layers Selected: " + selectedLayers.length + "\n" +
"Layers Updated: " + processed + "\n" +
"Layers Skipped: " + skipped + "\n\n" +
"X Range: " + minX + " to " + maxX + "\n" +
"Y Range: " + minY + " to " + maxY
);
} catch (err) {
alert("Error:\n\n" + err.toString());
} finally {
app.endUndoGroup();
}
})();