-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCreateColorCycleAnimation.jsx
384 lines (327 loc) · 17.2 KB
/
CreateColorCycleAnimation.jsx
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
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
#target photoshop
function selectFrame(frameNumber) {
var idslct = charIDToTypeID( "slct" );
var desc592 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref93 = new ActionReference();
var idanimationFrameClass = stringIDToTypeID( "animationFrameClass" );
ref93.putIndex( idanimationFrameClass, frameNumber );
desc592.putReference( idnull, ref93 );
executeAction( idslct, desc592, DialogModes.NO );
}
function hideActiveLayer() {
var doc = app.activeDocument;
// Check if there is an active layer
if (doc.activeLayer) {
doc.activeLayer.visible = false;
} else {
alert("No active layer selected.");
}
}
function showActiveLayer() {
var doc = app.activeDocument;
// Check if there is an active layer
if (doc.activeLayer) {
doc.activeLayer.visible = true;
} else {
alert("No active layer selected.");
}
}
var layerCache = {};
function selectLayerByName(layerName) {
var doc = app.activeDocument;
// Recursive function to search layers
function searchLayers(layers) {
for (var i = 0; i < layers.length; i++) {
var layer = layers[i];
// Check if the layer name matches
if (layer.name === layerName) {
layerCache[layerName] = layer;
doc.activeLayer = layer; // Set the layer as active
return true; // Found the layer
}
// If the layer is a group, search its layers
if (layer.typename === "LayerSet") {
if (searchLayers(layer.layers)) {
return true; // Found the layer in a group
}
}
}
return false; // Didn't find the layer
}
// Start the search
if (layerCache[layerName]) {
doc.activeLayer = layerCache[layerName];
} else if (!searchLayers(doc.layers)) {
alert("Layer '" + layerName + "' not found.");
}
}
function showProgressDialog(totalSteps, title, value) {
var progressWindow = new Window("palette", title, undefined, {closeButton: false});
progressWindow.orientation = "column";
progressWindow.alignChildren = "fill";
var progressBar = progressWindow.add("progressbar", undefined, 0, totalSteps);
progressBar.preferredSize.width = 300;
progressBar.value = value || 0;
progressWindow.show();
return {
close: function() {
progressWindow.close();
},
updateProgress: function(step) {
// progressBar.value = step;
// if (step >= totalSteps) {
// progressWindow.close();
// }
}
};
}
function createGradientMapLayers(numLayers) {
function getLayerName(i,j) {
var layerType = j===0 ? "fwd" : "rev";
return "cycle-precompute-" + layerType + " " + (i + 1) + " of " + numLayers;
}
var doc = app.activeDocument;
// Create a group for the gradient map layers
var colorCycleGroup = doc.layerSets.add();
colorCycleGroup.name = "colorcycle-precompute-fwd";
var colorCycleRevGroup = doc.layerSets.add();
colorCycleRevGroup.name = "colorcycle-precompute-rev";
// Create a placeholder layer inside the group
var placeholderLayer = [
colorCycleGroup.artLayers.add(),
colorCycleRevGroup.artLayers.add(),
];
for(var j=0; j<2; j++){
placeholderLayer[j].name = "placeholder";
}
var progressDialog = showProgressDialog(numLayers, "Processing Step 1...");
for (var i = 0; i < numLayers; i++) {
progressDialog.updateProgress(i);
var progress = i/numLayers;
var sliderProgress = Math.floor(progress*4096);
var greyValue = (1 - progress)*255
for (var j = 0; j < 2; j++) {
// Start of Action Descriptor to create a new Gradient Map Adjustment Layer
var idMk = charIDToTypeID( "Mk " );
var desc22 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idAdjL = charIDToTypeID( "AdjL" );
ref1.putClass( idAdjL );
desc22.putReference( idnull, ref1 );
// Descriptor for using the Gradient Map
var idUsng = charIDToTypeID( "Usng" );
var desc23 = new ActionDescriptor();
// Descriptor for the type of Adjustment Layer - Gradient Map
var idType = charIDToTypeID( "Type" );
var desc24 = new ActionDescriptor();
// Setting gradient interpolation method (you can adjust this part if needed)
var idgradientsInterpolationMethod = stringIDToTypeID( "gradientsInterpolationMethod" );
var idgradientInterpolationMethodType = stringIDToTypeID( "gradientInterpolationMethodType" );
var idInterpMethod = charIDToTypeID( "Gcls" );
desc24.putEnumerated( idgradientsInterpolationMethod, idgradientInterpolationMethodType, idInterpMethod );
// Descriptor for the Gradient (Modify this part for changing gradient colors)
var idGrad = charIDToTypeID( "Grad" );
var desc25 = new ActionDescriptor();
var idNm = charIDToTypeID( "Nm " );
desc25.putString( idNm, "Foreground to Background" );
var idGrdF = charIDToTypeID( "GrdF" );
var idGrdF = charIDToTypeID( "GrdF" );
var idCstS = charIDToTypeID( "CstS" );
desc25.putEnumerated( idGrdF, idGrdF, idCstS );
// Setting smoothness to 0
var idIntr = charIDToTypeID( "Intr" );
desc25.putDouble( idIntr, 0.000000 );
// Color Stops (Modify these for different gradient colors)
var idClrs = charIDToTypeID( "Clrs" );
var list3 = new ActionList();
// White color stop
var whiteStop = sliderProgress;
if(i===0){
whiteStop = 4096;
}
var desc28 = new ActionDescriptor();
var idClr = charIDToTypeID( "Clr " );
var desc29 = new ActionDescriptor();
var idRd = charIDToTypeID( "Rd " );
desc29.putDouble( idRd, 255.000000 );
var idGrn = charIDToTypeID( "Grn " );
desc29.putDouble( idGrn, 255.000000 );
var idBl = charIDToTypeID( "Bl " );
desc29.putDouble( idBl, 255.000000 );
var idRGBC = charIDToTypeID( "RGBC" );
desc28.putObject( idClr, idRGBC, desc29 );
var idType = charIDToTypeID( "Type" );
var idClry = charIDToTypeID( "Clry" );
var idUsrS = charIDToTypeID( "UsrS" );
desc28.putEnumerated( idType, idClry, idUsrS );
var idLctn = charIDToTypeID( "Lctn" );
desc28.putInteger( idLctn, whiteStop ); // Location of white color stop
var idMdpn = charIDToTypeID( "Mdpn" );
desc28.putInteger( idMdpn, 50 );
var idClrt = charIDToTypeID( "Clrt" );
list3.putObject( idClrt, desc28 );
// Black color stop
var blackStop = sliderProgress; // we place the black color stop at the same location as the white color stop to create a sharp transition, photoshop allows this and is the only way. the order we set the color stops is reflected in the final gradient
if(i===0){
blackStop = 0;
}
var desc26 = new ActionDescriptor();
var idClr = charIDToTypeID( "Clr " );
var desc27 = new ActionDescriptor();
var idRd = charIDToTypeID( "Rd " );
desc27.putDouble( idRd, 0 );
var idGrn = charIDToTypeID( "Grn " );
desc27.putDouble( idGrn, 0 );
var idBl = charIDToTypeID( "Bl " );
desc27.putDouble( idBl, 0 );
var idRGBC = charIDToTypeID( "RGBC" );
desc26.putObject( idClr, idRGBC, desc27 );
var idType = charIDToTypeID( "Type" );
var idClry = charIDToTypeID( "Clry" );
var idUsrS = charIDToTypeID( "UsrS" );
desc26.putEnumerated( idType, idClry, idUsrS );
var idLctn = charIDToTypeID( "Lctn" );
desc26.putInteger( idLctn, blackStop ); // Location of black color stop
var idMdpn = charIDToTypeID( "Mdpn" );
desc26.putInteger( idMdpn, 50 );
var idClrt = charIDToTypeID( "Clrt" );
list3.putObject( idClrt, desc26 );
// Grey color stop
if(i!==0){
for(var jj=0; jj<2; jj++){
var desc28b = new ActionDescriptor();
var idClrb = charIDToTypeID( "Clr " );
var desc29b = new ActionDescriptor();
var idRd = charIDToTypeID( "Rd " );
desc29b.putDouble( idRd, greyValue );
var idGrn = charIDToTypeID( "Grn " );
desc29b.putDouble( idGrn, greyValue );
var idBl = charIDToTypeID( "Bl " );
desc29b.putDouble( idBl, greyValue );
var idRGBC = charIDToTypeID( "RGBC" );
desc28b.putObject( idClrb, idRGBC, desc29b );
var idType = charIDToTypeID( "Type" );
var idClry = charIDToTypeID( "Clry" );
var idUsrS = charIDToTypeID( "UsrS" );
desc28b.putEnumerated( idType, idClry, idUsrS );
var idLctn = charIDToTypeID( "Lctn" );
desc28b.putInteger( idLctn, 4096*jj ); // Location of grey color stop
var idMdpn = charIDToTypeID( "Mdpn" );
desc28b.putInteger( idMdpn, 50 );
var idClrt = charIDToTypeID( "Clrt" );
list3.putObject( idClrt, desc28b );
}
}
//alert(i + " : " + blackStop + " : " + whiteStop)
desc25.putList( idClrs, list3 );
// Transparency Stops
var idTrns = charIDToTypeID( "Trns" );
var list4 = new ActionList();
var desc30 = new ActionDescriptor();
var idOpct = charIDToTypeID( "Opct" );
var idPrc = charIDToTypeID( "#Prc" );
desc30.putUnitDouble( idOpct, idPrc, 100.000000 );
var idLctn = charIDToTypeID( "Lctn" );
desc30.putInteger( idLctn, 0 );
var idMdpn = charIDToTypeID( "Mdpn" );
desc30.putInteger( idMdpn, 50 );
var idTrnS = charIDToTypeID( "TrnS" );
list4.putObject( idTrnS, desc30 );
var desc31 = new ActionDescriptor();
var idOpct = charIDToTypeID( "Opct" );
var idPrc = charIDToTypeID( "#Prc" );
desc31.putUnitDouble( idOpct, idPrc, 100.000000 );
var idLctn = charIDToTypeID( "Lctn" );
desc31.putInteger( idLctn, 4096 );
var idMdpn = charIDToTypeID( "Mdpn" );
desc31.putInteger( idMdpn, 50 );
var idTrnS = charIDToTypeID( "TrnS" );
list4.putObject( idTrnS, desc31 );
desc25.putList( idTrns, list4 );
// Completing the Gradient Descriptor
var idGrdn = charIDToTypeID( "Grdn" );
desc24.putObject( idGrad, idGrdn, desc25 );
var idGdMp = charIDToTypeID( "GdMp" );
desc23.putObject( idType, idGdMp, desc24 );
// Finalizing the Adjustment Layer Creation
var idAdjL = charIDToTypeID( "AdjL" );
desc22.putObject( idUsng, idAdjL, desc23 );
executeAction( idMk, desc22, DialogModes.NO );
if(j===1){
// Now, set the reverse property of the newly created Gradient Map
var idsetd = charIDToTypeID( "setd" );
var desc12557 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1131 = new ActionReference();
var idAdjL = charIDToTypeID( "AdjL" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref1131.putEnumerated( idAdjL, idOrdn, idTrgt );
desc12557.putReference( idnull, ref1131 );
var idT = charIDToTypeID( "T " );
var desc12558 = new ActionDescriptor();
var idRvrs = charIDToTypeID( "Rvrs" );
desc12558.putBoolean( idRvrs, true );
var idGdMp = charIDToTypeID( "GdMp" );
desc12557.putObject( idT, idGdMp, desc12558 );
executeAction( idsetd, desc12557, DialogModes.NO );
}
var layerName = getLayerName(i,j)
app.activeDocument.activeLayer.name = layerName;
hideActiveLayer()
// Move the created gradient map layer relative to the placeholder layer
app.activeDocument.activeLayer.move(placeholderLayer[j], ElementPlacement.PLACEBEFORE);
layerCache[layerName] = app.activeDocument.activeLayer
}
}
// Delete the placeholder layers
for(var j=0; j<2; j++){
placeholderLayer[j].remove();
}
progressDialog.close();
var progressDialog = showProgressDialog(numLayers, "Processing Step 2...");
for (var i = 0; i < numLayers; i++) {
progressDialog.updateProgress(i);
progressDialog.close();
var progressDialog = showProgressDialog(numLayers, "Processing Step 2..." + (i+1) + " of " + numLayers);
if(i>0){
var idDplc = charIDToTypeID( "Dplc" );
var desc228 = new ActionDescriptor();
var idnull = charIDToTypeID( "null" );
var ref1 = new ActionReference();
var idanimationFrameClass = stringIDToTypeID( "animationFrameClass" );
var idOrdn = charIDToTypeID( "Ordn" );
var idTrgt = charIDToTypeID( "Trgt" );
ref1.putEnumerated( idanimationFrameClass, idOrdn, idTrgt );
desc228.putReference( idnull, ref1 );
executeAction( idDplc, desc228, DialogModes.NO );
}
selectFrame(i+1);
for (var j = 0; j < 2; j++) {
selectLayerByName(getLayerName(i,j))
showActiveLayer();
if(i>0){
selectLayerByName(getLayerName(i-1,j))
hideActiveLayer();
}else{
selectLayerByName(getLayerName(numLayers-1,j))
hideActiveLayer();
}
}
}
progressDialog.close();
}
function main() {
var numberOfLayers = prompt("Enter the number of gradient map layers:", "1", "Number of Layers");
var numLayers = parseInt(numberOfLayers, 10);
if (isNaN(numLayers) || numLayers < 1 || numLayers > 1365) { //(1365 ~= 4096/3)
alert("Invalid number of layers.");
return;
}
var idmakeFrameAnimation = stringIDToTypeID( "makeFrameAnimation" );
executeAction( idmakeFrameAnimation, undefined, DialogModes.NO );
createGradientMapLayers(numLayers);
}
main();