parametric path expressions
3 parametric path expressions for After Effects TOC
circle path expression
//circle expression
var circle = content("Ellipse Path 1");
var radiusx = circle.size[0] * .5;
var radiusy = circle.size[1] * .5;
var myPosition = circle.position - radiusx;
var kappa = 0.5519;//4 * ((Math.sqrt(2) - 1) / 3)
var tanLengthx = (radiusy/2) * kappa *2;
var tanLengthy = (radiusx/2) * kappa *2;
var myPoints = [myPosition + [0,0],
myPosition + [radiusx, radiusy],
myPosition + [radiusx*2,0],
myPosition + [radiusx, -radiusy] ];
var myinTangents = [ [0, -tanLengthx],
[-tanLengthy,0],
[0, tanLengthx],
[tanLengthy,0] ];
var myoutTangents = [ [0, tanLengthx],
[tanLengthy,0],
[0,-tanLengthx],
[-tanLengthy,0] ];
myIs_closed = true;
createPath(myPoints, myinTangents, myoutTangents, myIs_closed);
square path expression
//rectangle path expression
var square = content("Rectangle Path 1");
var rectsize = square.size;
var rectpos = square.position;
var roundingBase = square.roundness;
var point1 = [-rectsize[0]/2 + rectpos[0], -rectsize[1]/2 + rectpos[1]];
var point2 = [rectsize[0]/2 + rectpos[0], -rectsize[1]/2 + rectpos[1]];
var point3 = [rectsize[0]/2 + rectpos[0], rectsize[1]/2 + rectpos[1]];
var point4 = [-rectsize[0]/2 + rectpos[0], rectsize[1]/2 + rectpos[1]];
var mypt = [point1, point2, point3, point4];
var myit = [[0,0], [0,0], [0,0], [0,0]];
var myot = [[0,0], [0,0], [0,0], [0,0]];
var mylength = mypt.length;
var myopenclose = true;
var kappa = 0.5519;//4 * ((Math.sqrt(2) - 1) / 3);
var newpt = [];
var newit = [];
var newot = [];
for(var i=0;i<mylength;i++){
rounding = Math.min(Math.min(roundingBase, rectsize[0]/2),rectsize[1]/2);
currentV = mypt[i];
currentO = myot[i] + mypt[i];
currentI = myit[i] + mypt[i];
if (currentV[0] === currentO[0] && currentV[1] === currentO[1] && currentV[0] === currentI[0] && currentV[1] === currentI[1]) {
if ((i === 0 || i === mylength - 1) && !myopenclose) {
newpt.push(currentV);
newit.push(currentI - currentV);
newot.push(currentO - currentV);
} else {
if (i === 0) {
closerV = mypt[mylength - 1];
closerO = myot[mylength - 1] + closerV;
closerI = myit[mylength - 1] + closerV;
} else {
closerV = mypt[i - 1];
closerO = myot[i - 1] + closerV;
closerI = myit[i - 1] + closerV;
}
if (closerV[0] === closerO[0] && closerV[1] === closerO[1]) {
distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2)
+ Math.pow(currentV[1] - closerV[1], 2));
newPosPerc = distance ? Math.min(distance / 2, rounding) / distance : 0;
iX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
vX = iX;
iY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
vY = iY;
} else {
distance = Math.sqrt(Math.pow(currentV[0] - (closerO[0]), 2)
+ Math.pow(currentV[1] - (closerO[1]), 2));
newPosPerc = distance ? Math.min(distance, rounding) / distance : 0;
iX = currentV[0] + ((closerO[0]) - currentV[0]) * newPosPerc;
vX = iX;
iY = currentV[1] - (currentV[1] - (closerO[1])) * newPosPerc;
vY = iY;
}
oX = vX - (vX - currentV[0]) * kappa;
oY = vY - (vY - currentV[1]) * kappa;
newpt.push([vX,vY]);
newit.push([iX,iY] - [vX,vY]);
newot.push([oX,oY] - [vX,vY]);
if (i === mylength - 1) {
closerV = mypt[0];
closerO = myot[0] + closerV;
closerI = myit[0] + closerV;
} else {
closerV = mypt[i + 1];
closerO = myot[i + 1] + closerV;
closerI = myit[i + 1] + closerV;
}
if (closerV[0] === closerI[0] && closerV[1] === closerI[1]){
distance = Math.sqrt(Math.pow(currentV[0] - closerV[0], 2)
+ Math.pow(currentV[1] - closerV[1], 2));
newPosPerc = distance ? Math.min(distance / 2, rounding) / distance : 0;
oX = currentV[0] + (closerV[0] - currentV[0]) * newPosPerc;
vX = oX;
oY = currentV[1] - (currentV[1] - closerV[1]) * newPosPerc;
vY = oY;
} else {
distance = Math.sqrt(Math.pow(currentV[0] - (closerI[0]), 2)
+ Math.pow(currentV[1] - (closerI[1]), 2));
newPosPerc = distance ? Math.min(distance , rounding) / distance: 0;
oX = currentV[0] + ((closerI[0]) - currentV[0]) * newPosPerc;
vX = oX;
oY = currentV[1] - (currentV[1] - (closerI[1])) * newPosPerc;
vY = oY;
}
iX = vX - (vX - currentV[0]) * kappa;
iY = vY - (vY - currentV[1]) * kappa;
newpt.push([vX,vY]);
newit.push([iX,iY] - [vX,vY]);
newot.push([oX,oY] - [vX,vY]);
}
} else {
newpt.push(currentV);
newit.push(currentI - currentV);
newot.push(currentO - currentV);
}
}
createPath(newpt, newit, newot, myopenclose);
polystar path expression
// polystar path expression
var polystar = content("Polystar Path 1");
var isStar = polystar.type; //star = 1, polygon = 2
var numberOfPoints = polystar.points;
var pos = polystar.position;
var offsetangle = degreesToRadians( polystar.rotation );
var or = polystar.outerRadius;
var tau = Math.PI*2;
var kappa = 0.5519;//4 * ((Math.sqrt(2) - 1) / 3);
var factor = linear(numberOfPoints,3,4,8.25,9);
var outerSeg = (tau * or) / (numberOfPoints * 2) * factor;
var outerRound = polystar.outerRoundness * .001 * outerSeg * kappa ;
var times = 1;
var angle = tau / Math.floor(numberOfPoints) ;
if(isStar == 1){
var ir = polystar.innerRadius;
var innerSeg = (tau * ir) / (numberOfPoints * 2) * factor;
var innerRound = polystar.innerRoundness * .001 * innerSeg * kappa ;
var times = 2;
angle = tau / Math.floor(numberOfPoints*2) ;
}
//pointAndTangents grouped as: point, inTangent, outTangent
var pointsAndTangents = [];
for(var i = 0; i < numberOfPoints*times; i++){
var currentAng = angle * i + offsetangle;
var currentAngle = currentAng - Math.PI *.5;
var x = or * Math.cos(currentAngle);
var y = or * Math.sin(currentAngle);
var ty = x === 0 && y === 0 ? 0 : -x / Math.sqrt(x * x + y * y);
var tx = x === 0 && y === 0 ? 0 : y / Math.sqrt(x * x + y * y);
if(i%2 && isStar == 1){
pointsAndTangents[i]= [
[ pos[0] + ir * Math.sin(currentAng), pos[1] - ir * Math.cos(currentAng)],
[ +tx * innerRound, +ty * innerRound],
[ -tx * innerRound, -ty * innerRound]];
}else{
pointsAndTangents[i]= [
[ pos[0] + or * Math.sin(currentAng), pos[1] - or * Math.cos(currentAng)],
[ +tx * outerRound, +ty * outerRound],
[ -tx * outerRound, -ty * outerRound]];
}
}
var myPoints = [];
var myinTangents = [];
var myoutTangents = [];
for(var i = 0;i<numberOfPoints*times;i++){
myPoints.push(pointsAndTangents[i][0]);
myinTangents.push(pointsAndTangents[i][1]);
myoutTangents.push(pointsAndTangents[i][2]);
}
myIs_closed = true;
createPath(myPoints, myinTangents, myoutTangents, myIs_closed);