Forum Replies Created

Page 10 of 277
  • Filip Vandueren

    May 19, 2023 at 11:08 am in reply to: Rotation + Position + Anchor Point

    There’s multiple ways to tackle this.

    But because there was the boundary issue that it should never go over the comp’s edge, I thought it might be easier to define a random Walk in orthogonal steps, and then randomizing for each step if the square would turn clockwise or anti-clockwise. So instead of starting from the randomization of rotations, I start from the positions on the grid.

    The anchorpoint would put itself in the correct corner to anticipate clockwise/counterclockwise, and the position that’s doing the rqndom jumps also compensates for the anchorpoint.

    Because mulitple properties need to look at the same random walk values, I start with putting those in exprssion controls:

    – create a 90×90 solid layer.

    – add a point Control to it named “Random Walk” with this expression:

    pos = [960,540];
    seedRandom(100,true);
    directions = [[1,0],[0,1],[-1,0],[0,-1]];
    for (t=0.5; t<=time; t+=0.5) {
    // move to a random neighbouring square.
    i = Math.floor(random(4));
    change = directions[i]*90;
    pos+=change;
    // if we go out of bounds, go the other way;
    if (pos[0]<45 || pos[0]>1875 || pos[1]<54 || pos[1]>1055) {
    pos-=change*2;
    }
    }
    pos;

    if Position gets this expression:

    effect("randomWalk")("Point").value;

    It already jumps around without leaving the comp.

    I also added an angle control named “randomTurn” with this expression:

    posterizeTime(2);
    random(1)<0.5 ? -90 : 90;

    Rotation gets this expression so it uses that random Turn:

    ease(time%0.5, 0.0, 0.5, 0, effect("randomTurn")("Angle").value);

    But it’s turning in place, then jumping, so we need to have the anchorPoint look at where it’s going. I did it like this, but there’s probably a more clever Maths-y way to do it.

    Expression fro Anchorpoint:

    thisPos = effect("randomWalk")("Point").valueAtTime(Math.floor(time*2)/2);
    nextPos = effect("randomWalk")("Point").valueAtTime(0.5+Math.floor(time*2)/2);
    turn = effect("randomTurn")("Angle").value;
    direction = ((nextPos - thisPos)/90).toString();
    switch (direction) {
    case "0,1":
    a = turn == 90 ? [0,90] : [90,90];
    break;
    case "0,-1":
    a = turn == 90 ? [90,0] : [0,0];
    break;
    case "1,0":
    a = turn == 90 ? [90,90] : [90,0];
    break;
    case "-1,0":
    a = turn == 90 ? [0,0] : [0,90];
    break;
    }
    a;

    And finally, Position needs to compensate for the moving anchorPoint

    effect("randomWalk")("Point").value + transform.anchorPoint - [45,45];

  • I can’t immediately think of a script or extension that does it specifically by comparing the existing folder structures, but something like the “declutter” script on aescripts that re-organizes the entire project could be a good alternative.

    If you can setup it’s reorganizing rules to be close to how you structure the individual projects in the first place it should come very close.

  • Filip Vandueren

    May 16, 2023 at 8:04 pm in reply to: Animate individual words font size

    Hi Marc,

    if you add a text animator on the words that need to scale, you’ll find it scales into the surrounding words.

    A trick to combat that is to have a second text animator that targets the space before and after your scaling text and animate the tracking of those space characters in tandem with the scale.

    https://imgur.com/a/TFaivC0

    I’ve attached an example comp.

    View post on imgur.com

  • Filip Vandueren

    May 16, 2023 at 9:26 am in reply to: Multiple corner radii for rounded corners

    Already had an idea for a remix: negative values give a chamfer instead of rounding:

    https://imgur.com/a/nO51Q10

    function multiRound(aPath, roundings) {
    // multiple corner-radii
    // a negative value will add a chamfer
    // Filip Vandueren 2023
    const pts = aPath.points();
    const it = aPath.inTangents(); const ot = aPath.outTangents(); const cl = aPath.isClosed();
    let newPts = []; let newIt = []; let newOt = [];
    for (let i=0; i<pts.length; i++) {
    rounding = roundings[i%roundings.length];
    if ((!cl && (i==0 || i==pts.length-1)) || length(it[i])!=0 || length(ot[i])!=0) {
    // re-use the first and last vertex unaltered if the path is not closed
    // OR if this vertex originally had tangents, it's also not discarded and chamfered, but kept:
    newPts.push(pts[i]);
    newIt.push(it[i]);
    newOt.push(ot[i]);
    } else {
    // add chamfer vertices, discarding the original vertex
    // giving these new vertices tangents creates the rounded corners
    // look at previous vertex
    let j = i-1;
    if (j<0) j+=pts.length; // loop around in closed paths
    let segment = (pts[j]+ot[j]-pts[i]); // consider a linesegment from this vertex to the prev outTangent
    // where should we place the chamferpoint:
    // on that segment, at a point that's 'roundingvalue' away from the current vertex
    // but on a straight linesegment it should never be further than 1/2 the distance
    // (the rounding is limited by the edges length)
    let n = normalize(segment)*Math.min(Math.abs(rounding), length(segment)/(length(ot[j])==0 ? 2 : 1));
    let chamferPoint = pts[i] + n;
    // add the point and it's tangent, using the magic number 0.55
    // it's on the same linesegment
    newPts.push(chamferPoint);
    newIt.push([0,0]);
    newOt.push(-n*(rounding>0 ? 0.55 : 0));
    // look at next vertex
    j = (i+1)%pts.length; // loop around in closed paths
    segment = (pts[j]+it[j]-pts[i]);
    // same logic as above
    n = normalize(segment)*Math.min(Math.abs(rounding), length(segment)/(length(it[j])==0 ? 2 : 1));
    chamferPoint = pts[i] + n;
    newPts.push(chamferPoint);
    newIt.push(-n*(rounding>0 ? 0.55 : 0));
    newOt.push([0,0]);
    }
    }
    return createPath(newPts, newIt, newOt, cl);
    }
    multiRound(thisProperty, [10,200,-50]);

    View post on imgur.com

  • Filip Vandueren

    May 16, 2023 at 8:43 am in reply to: Tracing along Shape Path with Rounded Corners

    Folllowing a question on reddit, I reverse engineered the rounding function, so I might as well add it here for future reference:

    function roundCorners(aPath, rounding) {
    	// Mimic After Effects' native round corner shape modifier but return an actual new Path
            // Filip Vandueren 2023
    	
    	const pts = aPath.points();
    	const it = aPath.inTangents(); const ot = aPath.outTangents(); const cl = aPath.isClosed();
    
    	let newPts = []; let newIt = []; let newOt = [];
    
    	for (let i=0; i<pts.length; i++) {
    			
    		if ((!cl && (i==0 || i==pts.length-1)) || length(it[i])!=0 || length(ot[i])!=0) {
    			// re-use the first and last vertex unaltered if the path is not closed
    			// OR if this vertex originally had tangents, it's also not discarded and chamfered, but kept:
    			newPts.push(pts[i]);
    			newIt.push(it[i]);
    			newOt.push(ot[i]);	
    		} else {
    			// add chamfer vertices, discarding the original vertex
    			// giving these new vertices tangents creates the rounded corners
    			
    			// look at previous vertex
    			let j = i-1; 
    			if (j<0) j+=pts.length; // loop around in closed paths
    			let segment = (pts[j]+ot[j]-pts[i]); // consider a linesegment from this vertex to the prev outTangent
    			// where should we place the chamferpoint:
    			// on that segment, at a point that's 'roundingvalue' away from the current vertex
    			// but on a straight linesegment it should never be further than 1/2 the distance
    			// (the rounding is limited by the edges length)
    			let n = normalize(segment)*Math.min(rounding, length(segment)/(length(ot[j])==0 ? 2 : 1));
    			let chamferPoint = pts[i] + n;
    			
    			// add the point and it's tangent, using the magic number 0.55 
    			// it's on the same linesegment
    			newPts.push(chamferPoint);
    			newIt.push([0,0]);
    			newOt.push(-n*0.55);
    			
    
    			// look at next vertex
    			j = (i+1)%pts.length;  // loop around in closed paths			
    			segment = (pts[j]+it[j]-pts[i]);
    			// same logic as above
    			n = normalize(segment)*Math.min(rounding, length(segment)/(length(it[j])==0 ? 2 : 1));
    			chamferPoint = pts[i] + n;
    
    			newPts.push(chamferPoint);
    			newIt.push(-n*0.55);
    			newOt.push([0,0]);
    		}
    	}
    
    	return createPath(newPts, newIt, newOt, cl);
    }
    
    roundCorners(thisProperty, 50);
  • Filip Vandueren

    May 14, 2023 at 1:51 pm in reply to: Missing Unmult effect

    You’ll find that the default preset can desaturate the original quite a lot. Using Max RGB to Alpha and then remove BG color is I believe the actual recipe unmult uses.

  • Filip Vandueren

    May 14, 2023 at 8:35 am in reply to: Missing Unmult effect

    Hi Max,

    Possibly it’s the older Knoll Unmult version, see here:

    https://support.maxon.net/hc/en-us/articles/360010345194-Where-can-I-get-Unmult-

  • Filip Vandueren

    May 14, 2023 at 8:29 am in reply to: Define Global Scale Range Using Markers

    If I understand the path you’re describing correctly, you could linear() their scale to the z-component of the position (or the distance from layer to camera if the camera isn’t in the default position/orientation). Then the layers get larger as they are closer to the camera, slightly exaggerating what perspective is already doing.

  • Something like this would work, but it can be a bit more simplified:

    var startKeyframe = 4; // Change this value to the index of the first keyframe you want to play
    var endKeyframe = 6; // Change this value to the index of the last keyframe you want to play
    // Calculate the total duration of the keyframe range
    var rangeDuration = key(endKeyframe).time - key(startKeyframe).time;
    // Calculate the time of the outpoint of the layer
    var outpoint = thisLayer.outPoint;
    var t = linear(time, outpoint-rangeDuration, outpoint, key(startKeyframe).time, key(endKeyframe).time);
    valueAtTime(t);
  • An expression cannot “set” the values of keyframes.

    It can only yield a value which is what the property should be at the current time. That value can be based on the keyframes and the timing of layers, but it won’t change those keyframes.

    I’m not entirely sure what you mean by “play a number of keyframes”. The code appears to want to do that based on the outpoint of the layer.
    Since the expression as it is now is wrong, maybe you should explain in plain words what you expect it to achieve, because now we don’t know what to change to get to your expectation.

Page 10 of 277

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy