After Effects Scripting: "Object is Invalid" Error with Stroke and Fill Properties
function convertTextToShapes() {
var myComp = app.project.activeItem;
if (!myComp || !(myComp instanceof CompItem)) {
alert("please select a composition.");
return null;
}
var selectedLayers = myComp.selectedLayers;
var textLayer = selectedLayers[0];
if (!(textLayer instanceof TextLayer)) {
alert("please select a text layer.");
return null;
}
app.beginUndoGroup("convert text to shapes");
try {
var originalTextLayerName = textLayer.name;
app.executeCommand(3781);
var shapeLayer = myComp.selectedLayers[0];
shapeLayer.name = originalTextLayerName + "-shapes";
// textLayer.enabled = false;
// textLayer.remove();
return shapeLayer;
} catch (e) {
alert("something went wrong." + e.toString());
return null;
} finally {
app.endUndoGroup();
}
};
var convertedShapeLayer = convertTextToShapes();
app.beginUndoGroup("add expressions to shapes");
(function addExpressions(shapeLayer) {
var contents = shapeLayer.property("Contents");
for (var i = 1; i <= contents.numProperties; i++) {
var group = contents.property(i);
if(group.matchName == "ADBE Vector Group") {
var groupContents = group.property("Contents");
var charIndex = i - 1;
groupContents.property(2).remove();
groupContents.property(2).remove();
var strokes = groupContents.addProperty("ADBE Vector Graphic - Stroke");
strokes.name = "setStrokes";
var fills = groupContents.addProperty("ADBE Vector Graphic - Fill");
fills.name = "setFills";
alert(strokes.name + " " + fills.name);
var trimPaths = groupContents.addProperty("ADBE Vector Filter - Trim");
trimPaths.name = "setTrimPaths";
strokes.property("ADBE Vector Stroke Width").setValue(1);
strokes.property("ADBE Vector Stroke Color").setValue([1, 1, 1, 1]);
fills.property("Opacity").expression =
'function getBezierX(t, p1x, p2x) {\r' +
' return 3 * Math.pow(1 - t, 2) * t * p1x + 3 * (1 - t) * Math.pow(t, 2) * p2x + Math.pow(t, 3);\r' +
'}\r' +
'\r' +
'function getBezierY(t, p1y, p2y) {\r' +
' return 3 * Math.pow(1 - t, 2) * t * p1y + 3 * (1 - t) * Math.pow(t, 2) * p2y + Math.pow(t, 3);\r' +
'}\r' +
'function cubicBezierInternal(inputTime, x1, y1, x2, y2) {\r' +
' var t = Math.max(0, Math.min(1, inputTime));\r' +
'\r' +
' if (t === 0) return 0;\r' +
' if (t === 1) return 1;\r' +
'\r' +
' var start = 0.0;\r' +
' var end = 1.0;\r' +
' var u = t;\r' +
' var iterations = 8;\r' +
' for (var i = 0; i < iterations; i++) {\r' +
' var guessX = getBezierX(u, x1, x2);\r' +
' if (guessX < t) {\r' +
' start = u;\r' +
' } else {\r' +
' end = u;\r' +
' }\r' +
' u = (start + end) / 2;\r' +
' }\r' +
' return getBezierY(u, y1, y2);\r' +
'}\r' +
'function animateWithBezier(animStartTime, animDuration, startValue, endValue, bezierParams) {\r' +
' var x1 = bezierParams[0];\r' +
' var y1 = bezierParams[1];\r' +
' var x2 = bezierParams[2];\r' +
' var y2 = bezierParams[3];\r' +
'\r' +
' var normalizedTime = (time - animStartTime) / animDuration;\r' +
'\r' +
' var easedProgress = 0;\r' +
' if (time >= animStartTime && time <= animStartTime + animDuration) {\r' +
' easedProgress = cubicBezierInternal(normalizedTime, x1, y1, x2, y2);\r' +
' } else if (time > animStartTime + animDuration) {\r' +
' easedProgress = 1;\r' +
' }\r' +
' return startValue + (endValue - startValue) * easedProgress;\r' +
'}\r' +
'\r' +
'var BEZIER_EASE = [0.25, 0.1, 0.25, 1.0];\r' +
'var BEZIER_EASE_IN = [0.42, 0, 1.0, 1.0];\r' +
'var BEZIER_EASE_OUT = [0, 0, 0.58, 1.0];\r' +
'var BEZIER_EASE_IN_OUT = [0.42, 0, 0.58, 1.0];\r' +
'var BEZIER_LINEAR = [0, 0, 1.0, 1.0];\r' +
'\r' +
'\r' +
'var animate1 = animateWithBezier(' + i / 15 + 0.5 + ', 0.5, 0, 100, [0, 0, 0, 0]);\r' +
'\r' +
'animate1\r'
;
trimPaths.property("End").expression =
'function getBezierX(t, p1x, p2x) {\r' +
' return 3 * Math.pow(1 - t, 2) * t * p1x + 3 * (1 - t) * Math.pow(t, 2) * p2x + Math.pow(t, 3);\r' +
'}\r' +
'\r' +
'function getBezierY(t, p1y, p2y) {\r' +
' return 3 * Math.pow(1 - t, 2) * t * p1y + 3 * (1 - t) * Math.pow(t, 2) * p2y + Math.pow(t, 3);\r' +
'}\r' +
'function cubicBezierInternal(inputTime, x1, y1, x2, y2) {\r' +
' var t = Math.max(0, Math.min(1, inputTime));\r' +
'\r' +
' if (t === 0) return 0;\r' +
' if (t === 1) return 1;\r' +
'\r' +
' var start = 0.0;\r' +
' var end = 1.0;\r' +
' var u = t;\r' +
' var iterations = 8;\r' +
' for (var i = 0; i < iterations; i++) {\r' +
' var guessX = getBezierX(u, x1, x2);\r' +
' if (guessX < t) {\r' +
' start = u;\r' +
' } else {\r' +
' end = u;\r' +
' }\r' +
' u = (start + end) / 2;\r' +
' }\r' +
' return getBezierY(u, y1, y2);\r' +
'}\r' +
'function animateWithBezier(animStartTime, animDuration, startValue, endValue, bezierParams) {\r' +
' var x1 = bezierParams[0];\r' +
' var y1 = bezierParams[1];\r' +
' var x2 = bezierParams[2];\r' +
' var y2 = bezierParams[3];\r' +
'\r' +
' var normalizedTime = (time - animStartTime) / animDuration;\r' +
'\r' +
' var easedProgress = 0;\r' +
' if (time >= animStartTime && time <= animStartTime + animDuration) {\r' +
' easedProgress = cubicBezierInternal(normalizedTime, x1, y1, x2, y2);\r' +
' } else if (time > animStartTime + animDuration) {\r' +
' easedProgress = 1;\r' +
' }\r' +
' return startValue + (endValue - startValue) * easedProgress;\r' +
'}\r' +
'\r' +
'var BEZIER_EASE = [0.25, 0.1, 0.25, 1.0];\r' +
'var BEZIER_EASE_IN = [0.42, 0, 1.0, 1.0];\r' +
'var BEZIER_EASE_OUT = [0, 0, 0.58, 1.0];\r' +
'var BEZIER_EASE_IN_OUT = [0.42, 0, 0.58, 1.0];\r' +
'var BEZIER_LINEAR = [0, 0, 1.0, 1.0];\r' +
'\r' +
'\r' +
'var animate1 = animateWithBezier(' + i / 15 + ', 0.5, 0, 100, [0, 0, 0, 0]);\r' +
'\r' +
'animate1\r'
;
}
}
})(convertedShapeLayer);
app.endUndoGroup();This is my first attempt at writing an After Effects script to animate text.
However, when I run it, I consistently get the error:
strokes.property("ADBE Vector Stroke Width").setValue(1);
strokes.property("ADBE Vector Stroke Color").setValue([1, 1, 1, 1]);These two lines show "Unable to execute script at line 51 Object is invalid".
Perhaps the same issue applies to fills as well, but trimPaths works fine.
I've tried changing the content within property(""). I referenced the After Effects scripting documentation to find the correct values, but no matter what I change, I still get the same error. What I don't understand most is why trimPaths works correctly while the others don't.
