Copy link to clipboard
Copied
Hi there. I followed a tutorial on youtube to scale a shape while maintaing a constant stroke width. Tutorial link: https://www.youtube.com/watch?v=0Bpf_H3vtZ0&t=21s
He uses the expression:
sf = thisComp.layer("CONTROL").transform.scale[0]/100;
ov = value;
nv = ov / sf
The shapes are tied to a parent null where the transformations are keyframed.
However, I keep getting an orange pop-up warning me:
It says: "After Effects warning: Expression Disabled
Error at line 1 in propert 'Stroke Width' of layer 2 ('Circle WERT') in comp 'Charlie.001'.
couldn't turn result into numeric value."
The stroke width is 2px and the scaling value are keyframed at whole numbers, 0 and 100%. In the preview, everything looks fine.
Any ideas why? Or are there other expressions to try?
1 Correct answer
I would give that tutorial a C-. The explanation is incomplete and the workflow is inefficient. The expression makes no allowance for divide by zero errors.
Here is the expression I would use for Stroke:
if (hasParent)
{scl = thisLayer.parent.scale[0]/100;
if (scl == 0)
sv = 1
else
sv = scl;
value / sv }
else
value
The layer name if the parent no longer a potential problem, the expression is just looking for a layer with a parent. The first if statement keeps the original stroke
...Copy link to clipboard
Copied
Use the Expression provided by Mike Abbot in this post -
Copy link to clipboard
Copied
Hi thanks for the response. the expression is for a fixed height and only follows a change in X value. I am looking for something that can be changed with a null because there are many shapes in my shape layer.
Copy link to clipboard
Copied
Noticed that the expression I used from the tutorial only kicks up an error when the parent scale is keyframed to 0. Any idea how to fix it? Or should I ignore it?
Copy link to clipboard
Copied
I was under the impression that Mike's Expression worked by increasing xScale; which was what you were doing too. Anyways, to get by the error when value is 0, set your 0 to 0.01 and see if this helps.
Copy link to clipboard
Copied
I would give that tutorial a C-. The explanation is incomplete and the workflow is inefficient. The expression makes no allowance for divide by zero errors.
Here is the expression I would use for Stroke:
if (hasParent)
{scl = thisLayer.parent.scale[0]/100;
if (scl == 0)
sv = 1
else
sv = scl;
value / sv }
else
value
The layer name if the parent no longer a potential problem, the expression is just looking for a layer with a parent. The first if statement keeps the original stroke value is there is no parent. f there is no parent the original stroke value is retained. The second if statement prevents divide by zero errors and retains the original stroke value if the scale gets to zero. The Stroke value is now modified by the X layer scale no matter what the parent layer is.
When you get the expression working for one stroke you can copy expression only, type Stroke in the timeline search to show all stroke properties on the layer and then select them all and paste. It will take about 2 seconds and you could have a couple hundred stroked layers tied to the scale of their parent layer and show no errors if there was no parent. The expression is so good that I'm saving it as an animation preset. It's something that I will use once in a while.
Here you go: https://www.dropbox.com/s/w4rn60hlf1je8kj/stroke%20tied%20to%20parent.ffx?dl=0
All you have to do is type Stroke in the timeline search field to reveal all stroke width properties in all shape layers, drag a selection around all of them and then apply the animation preset. Then parent the shape layer to any null and the stroke will remain the same relative size no matter what the scale of the parent layer is.
I think I'll work on one that ties stroke width to distance from the camera. That will also be useful for some designs.
Copy link to clipboard
Copied
Worked perfectly! Thanks Rick!
Copy link to clipboard
Copied
Hi Rick!
Many thanks for this preset, this has worked great for everything apart from the animated elements which are already parented to different layers.
And I'm wondering how to alter the expression to recognize the different parenting.
Copy link to clipboard
Copied
I am not sure what you mean when you say "And I'm wondering how to alter the expression to recognize the different parenting." The parent's position properties are always in comp space, a child layer can be retrieved relative to comp space by using toComp or toWorld. What are you trying to do?
I would have to see a screenshot with the modified properties of the layers you are having problems with revealed to offer much help. Press 'uu' to show everything you've modified or send a link to a project file and describe your design goals.
Copy link to clipboard
Copied
Thanks Rick. For negetive value I have added || scl<0 in the 2nd if condition. and it worked perfectly.
if (hasParent)
{scl = thisLayer.parent.scale[0]/100;
if (scl == 0 || scl<0)
sv = 1
else
sv = scl;
value / sv }
else
value
Copy link to clipboard
Copied
previous did not worked but this one did
if (hasParent)
{scl = thisLayer.parent.scale[0]/100;
if (scl == 0 || scl<0)
sv = 1
else
sv = Math.abs(scl);
value / sv }
else
value
for whatever reason Adobe is not letting me delete my previous reply. I have made a mistake on that one.
this one is working though
Copy link to clipboard
Copied
In my case neither seems to work, I have a shape and when i connect the shape layer to the null the stroke width turns from 5 px to 0.3. I have a big shape which is scaled in only to smaller stages within the animation. Using the expression above Strokes get squeezed and stretched wich creates a really odd look.
Are there any updates on this topic?
Copy link to clipboard
Copied
Hello everyone! So the day after me having this issue battle axe updated their buttcapper plug in which fixes any stroke widths scaling issues I had! And it's free!
https://www.battleaxe.co/buttcapper
hope this helps everyone!

