//***********Selected as Spine, version 1 //this script will take the selected group of layers and from them create an animatable spine; // each vertebra is parented to the one below it, and each vertebra above the lowermost (base) vertebra // has an expression that is linked to the base vertebra's x rotation. //***********// function mainSpine() { // make sure a comp is selected var activeItem = app.project.activeItem; if (activeItem == null || !(activeItem instanceof CompItem)){ alert("You need to select some layers first."); } else { // make sure more than one layer is selected var s = activeItem.selectedLayers; var selNum = s.length; if (selNum < 2) { alert("You need to select at least two layers first."); } else { vn = selNum; gotANum = false; cancelledOut = false; while (! gotANum) { p = prompt("Enter overlap amount (in pixels. Zero means no overlap; negative number creates spacing):", "2"); if (p == null) { cancelledOut = true; gotANum = true;//well, not really, but ... } else { if (! isNaN(p)) { vOlap = parseFloat(p); gotANum = true; } } } if (! cancelledOut) { app.beginUndoGroup("selection as spine"); vNa = "vertabra"; vShy = true; baseLayer = s[0]; // (if not 3D layer, make it one) if (!baseLayer.threeDLayer) {baseLayer.threeDLayer = true} ; // rename to 'base vertebra' vZeroName = ("base " + vNa); baseLayer.name = vZeroName; lastLayer = baseLayer; lastLayerHtOffset = lastLayer.height; //change anchor point to bottom of layer ap = lastLayer.property("Anchor Point").value; lastLayer.property("Anchor Point").setValue( [ap[0], (lastLayerHtOffset), ap[2]] ); for (i = 1; i < (vn); ++i) { /////LAYER ITEM ADJUSTMENTS///// newLayer = s[i]; newLayer.name = (vNa + "_" + i); // (if not 3D layer, make it one) if (!newLayer.threeDLayer) {newLayer.threeDLayer = true} ; /////PROPERTY ADJUSTMENTS///// //change anchor point to bottom of layer ap = newLayer.property("Anchor Point").value; newLayer.property("Anchor Point").setValue( [ap[0], (newLayer.height), ap[2]] ); p = lastLayer.property("Position").value; newLayer.property("Position").setValue([ p[0], (p[1] - lastLayerHtOffset + vOlap), p[2] ]); //add x rot expression to new layer newLayer.property("rotationX").expression = 'thisComp.layer("' + vZeroName + '").rotationX;'; lastLayer = newLayer; ///// now we have a reference to this layer to use at next iteration as last layer lastLayerHtOffset = lastLayer.height; } for (n = 0; n < (s.length-1); ++n) { childL = s[n + 1]; parentL = s[n]; childL.parent = parentL; if (vShy == true) {childL.shy = true} ; } app.endUndoGroup(); alert("The base vertebra is the first layer selected."); } } } } mainSpine();