sourceRectAtTime(); | After Effects Expressions

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey it's Jake and today we are gonna be diving deep into the source wrecked at time expression we're gonna pick it all apart figure out what makes it work and why it's going to make your life easier [Music] if you've ever wanted to make some kind of a templatized graphic that was based on a text layer size and dynamically changes with whatever the text is doing you need source wrecked it time to make that happen now there's definitely a learning curve to this expression it seems pretty complicated and overwhelming at first because there are a lot of options but it's a very powerful expression and it's my goal that by the end of this tutorial you'll have a firm grasp on how it works all of the parameters of it and how you can use it to make some pretty cool stuff so what a source wrecked it time actually do for us why is it useful well it will return one of four values it'll give you the width or height of any layer as well as the top and left edge and those last two are gonna be for a very unique scenario that we'll get to in just a little bit but first let's just start with the width and height if I were to make a box obviously we know the size of that because there is a size property it's 1920 by 1080 I could turn this down to 500 and the width is gonna be 281 that's not hard to determine but on a layer like this a text layer there is no property in any of these drop-down menus that's gonna tell me the exact width and height of that layer so I can use this expression source rect at time to tell me the width or the height and to show you how this all works I'm gonna be making a box that sizes to this text and follows it around no matter what it will always stay right behind it all right so I'll take this box and I'm going to go to the size property and start writing an expression by pressing option or alt clicking on that stopwatch and I'll give myself a little bit more room here and we need to start defining some variables so if you don't know the variable is it's just basically a placeholder for expression code so that I can kind of create my own shorthand to reference later on in the code so we'll start typing in my expression I'm going to say var for variable s for source equals and that s for source that is totally made-up by me you can name your variables whatever you want so I'm just making mine as short as possible s for source and I want to use the expression pick whip to select my text layer so that is my source I'll finish that off with a semicolon then I'm gonna add another variable and I'm gonna call it W for width and this is where I'm gonna use my first source rec to time expression so I'll start by saying s which is the variable I just defined so this text layer dot source rect at time and that capitalization is very important 99% of the time in expression code the first word of an expression is lowercase and the rest is capitalized so that's called camelcase but we've got s dot source rekted time open parentheses close parentheses dot width and that's how I tell the source rekted time that i want to find the width of that rectangle and not the height but I do want to know the height so I'm going to copy this line drop down and make another variable this time changing it to H and instead of width say height so now I've got W which will contain the source width of this text layer and H which will contain the height of that source text layer and now that I have those variables defined I'll drop down and write an array so opening bracket W for width comma H for height close bracket and I'll do a semicolon to finish off that line of code and if you don't know what an array is it's just a set of numbers instead of a single number so we look at the size property this has two numbers the X and y the width and the height of that size and they're separated by a comma so to get aftereffects to know how to fill out those two individual properties I have to write them in an array or within these square brackets and divide it by a comma all right now that that's all set I can click off and instantly my size changes it's now 880 by 79 that looks about the same size as this text so I'm just going to click and drag while holding down command to temporarily snap and then I'll just move that box below the text layer there we go it looks like that box is perfectly sized to the text goes to the top and bottom edges and I have a stroke on there actually so I'm going to turn that all the way down to zero and there you go you can see it fits perfectly on the edges wherever the farthest out parts of this text layer are that's what this box is sighs - that's great it seems like it's working just fine I'll rename this text box and I'm gonna change the color to red and the text color to white and I'm just gonna rename this text all right so now that the box is sizing properly I should be able to type in anything I want and look at that the box is following the size of the text and it looks like there are a couple of issues like up here that a isn't touching even though that looks like it's the top part of the text and the Y&G are getting cut off so we're definitely gonna have to revisit the code a little bit and another issue that I'm running into is that this is Center justified text and it looks like it's working just fine but if I change this to left justified and then you know realign this up so that they're both centered on each other and I type in something else that is not lining up at all as I type I'll just do one character at a time you see that the box and I'll make this dark so we can see it easier but as I type the box is scaling from the center even though the text is coming from the left to right since it's left justified so how can we get around these issues what we'll just be a little bit clever with some properties in our shape layer so I'm going to open this up go into the contents rectangle rectangle path and basically what I want to happen is for this to shoot off to the right as the text is expanding so that instead of scaling from the center it's scaling from the left edge but this size is constantly changing which means this anchor point for the shape layer will constantly have to change so I need to base this number on the size of the box you see that I just kind of manually lined that up and this number 324 is basically half of 647 or the width the reason that number is half is because when it's at zero anchor point is dead center in the shape layer so taking half of the entire width would be the same as the distance from this point to here so I should be able to just divide the size by two and plug that straight into the position and that will move my anchor point to the top left corner of the box no matter what size the box is so let's do that I'll hold down option and click on the position stopwatch and just pick with the size and say divided by two apply that and there we go our box shifts over now the anchor point is in the top left corner of this box and if I now just move the layer over a hold command again to snap to the top left corner it's lined up and now I can type and it will work just fine and to keep this text box with the text all I have to do is parent it to that text layer now it'll move around with that type okay so that seems like it's working just fine but let's say I want to change the size of my type suddenly that box is not following the type anymore the reason for this is because of the way that text layers behave you see that the bounding box so is all the way out here but the anchor point is right here down on the bottom left now this is because that's where the origin of the text is it's the baseline that's where most of the text rests but you can have things like descenders like this Y here that goes below it but because it's a text layer it's going to scale off of that anchor point and I don't mean if I were to change this anchor point and change the text size that's going to scale off that anchor point but by default the text layers anchor point lines up with that origin of the text layer on the baseline so when I change the size of the text that's where it's scaling from whereas our text box is scaling from the top-left corner so it's still taking the correct size from the text layer it's just scaling it off of a point that isn't quite right and this is where the top and left parts of source rect at time are going to come into play the source rect at time top expression will give us the distance between the top edge of the layer and the baseline and the left part a source wrecked a time will give us the distance between the left edge of the layer and the origin we can use those two numbers to offset the anchor point of our text box so that it scales from where it needs to so the size expression is working just fine but I need to add some more variables to my position expression so I'm gonna go in here and edit this and I'll just copy this one to make it a little bit quicker and paste it here change H to L for left and then get rid of this height divided by 2 and type in left and then I'll copy and paste that change it to T and top now that I have those accessible I can put them into my expression so what I want to do is add the left edge to the width so width plus L and I want to add the top edge to the height so height plus top if I apply that the box shifts up but if I click on it you can see the anchor point is now existing in this bottom left area of very near where the anchor point for the text layer is so I'll just grab this layer hold command and snap it to the anchor point of that type layer and it lines up perfectly again now if I change the font size you see the box scales with it perfectly if I change the type of font or the font completely it will always fit I can even change the justification and that box is always gonna fit exactly around that text so we fix that issue no matter what it's always going to work and because it's parented it will move with the text and I have a working text box now let's say that you don't want it to be directly on the edges of the text that is a little bit close for comfort so we want to expand it out a little bit well I could go in to the size and add some manual padding into this like width plus 10 type plus 10 and that'll push out the edges a little bit but that's annoying to me I don't like having to type in hard coded numbers like that so instead because this is a shape layer I'm just gonna go to add and say offset paths now I can just simply control them margin with a single amount of property so if I want 10 pixel margin all the way around that text there we go alright that's great but let's say that we want to animate this text I mean one of the best uses of source rect to time is for making templates that follow text dynamically so let's just add a quick animator to this text this is one that I made up it's just going to animate the text on from left to right as I play this back you'll notice that the box is sizing with it and that is great maybe that's exactly what you want it to be but as I scrub through this you'll notice that the box is scaling vertically as well as horizontally and maybe you don't want the box to scale vertically like that maybe you want it to stay the same width as it is once the animation is finished well there's actually a little bit more to source rect at time so let me type this out one more time so we can see it nice and clear source rect at time open close parenthesis and a semicolon these open and close parentheses actually aren't there for nothing we can put some values in here to control how the expression is actually working there are two possible values you can put in here the first one is time and then a comma and the second one is extense so let's just focus on time for a second what that's going to let us do is determine at what point in time in our composition that it's looking at the width or the height or the top or the left edge if we leave these parenthesis open and it's going to default to a time of time which translates to the current time whatever frame you're on that's what the source rector time value is going to be looking at so that's why the box is scaling with the text because at the beginning the text is smaller and it grows out to the right so every frame it's looking at whatever the width and height of that text layer is at the given time but I could change this to say 1 and that would mean source rect at time at 1 second which is after this animation is completed so why don't we just do that I'll double tap you to bring up my expressions this is the one for the size that's the one I'm really concerned with the height I want this to be source rect at time not at the current time but at 1 second I'll click off of that and now if I play this back see the box is staying the same height now we're still getting some weird issues here at the beginning it's shifting up and down and that's because of the way that this position expression is working with the top edge and the actual height so I need to add that one in to my height source rec to time expression as well as the top value so it's looking at the 1 second value for those variables and now you see that the box height isn't changing and it isn't shifting up and down however it is shifting left and right as this first layer is scaling up so I also need to go to that left edge and type 1 in there and now it's almost working but before I go any further trying to get this to work I want to point out an issue that this brings up when you're hard coding in numbers like this say I want to make my animation longer than one second maybe I want it to be one and a half seconds well now it's gonna be looking at the height at one second and in this particular case that's not actually an issue because the tallest part of the text has increased by that point but the point is hard-coding in numbers like this kind of limits you so instead of using that hard-coded number I want to put in something a little bit more dynamic so let's say that my text layer gets trimmed down to three seconds I can reference that out point in my expressions and use it as that time indicator so where the source rect is pulling its value from so instead of saying one second I'm going to say s which is the text layer dot out point that's going to return the time value for the out point of that layer so it's looking at that outpoint for the height of that text layer then I'll just copy that and replace all of these ones with that same value and the animation doesn't look any different but it is much more flexible now it's always going to look at the end of my animation which should be after the animation is completed but let's say that I want to animate the Box on slightly differently than the text maybe the motion isn't exactly what I want maybe I want the box to come out quicker than the text well in that case then I'm not going to want the width to follow that text size either so I'll jump into the size expression go to the width source rect it time and change this to s dot out point as well for the width and I'll do it down here for the position as well so now all of my source rec to time expressions are looking at the out point of the layer to find its values from and if I scrub this back now you can see my text is animating on the box size however is never changing that's great because now I can move this text forward and then let's say I want to have that box scale out from the left but take a little bit more time so I'll collapse the layer maybe go into the transform controls for this rectangle and because the Anchor Point is on the left edge I should be able to just animate the X scale to scale that up now if i zoom in here nice and close you can see that's actually giving me a little bit of an issue because it's scaling from this point right here and my offset paths is pushing the margin outwards so I need to shift the anchor points so that it isn't right here but it's actually over here on the edge it's accounting for the left edge as well as the offset path so I'm going to borrow again some of the expressions from my position property I'll just copy all the variables and delete what I don't need so I'll start with the Anchor Point option click and paste I don't actually need the width or the height just the top and left edges then I need another variable which is the offset pads amount so I'm going to type another variable in here er / offset equals and then expression pick whip the amount there we go and now I'll write my array so I want the anchor point of this box to be the left edge for the width - the offset comma edge for the height - the offset as well close bracket semicolon and apply now my box gets moved around so it's not where it needs to be anymore but I can counteract that using the position very simply I'm just gonna make the position the exact same values as the anchor point so I add an expression expression pick whip the anchor point and apply it and now the box is back where it needs to be and we can see that shape layer anchor point for this rectangle is now in the very top left corner so if I grab my scale the X scale now it is scaling off of that left edge because it is accounting for this offset as well as the top and left edge offset with that done I can now add some animation to this layer so I'll go to the scale property set the x value down to zero to add a keyframe go forward maybe a second and then change it back up to 100% then I'll just really increase this YZ and see how that looks so there we go now my animation for this shape layer happens independently of the text but it's based on the width of that text after it's been completely animated so I can change this and the box is still gonna animate to that size let's say that I wanted to add a little bit of overshoot to this maybe just make it a little bit more bouncy I'll grab that keyframe and I'm using motion - from mount mograph but this is just gonna add a quick overshoot and that's obviously way too much maybe we'll turn up the friction turn down the overshoot but now that comes out and the text follows so you can really customize the way that this is animating out but it's completely dynamic based on the text that you type in again you can change the font to whatever you want you can change the size of it and the box is always going to size perfectly to it but now that I've got my text animated on let's say I want it to animate back off I'll go to my range selector add a keyframe on the start value and then animate that to 100 and then I'll just add some easing to it and it animates off but something broke my box is no longer showing up well that's because we told all of our expressions to base the source rect at time at the out point of this text layer which now is nothing the text is gone so it's looking at a source rect at time that is zero so how do we correct for that what we're going to do a little bit more clever math to make it happen so just like we can target the out point of a layer we can also target the end point if we can know both of those values then we can find what the exact middle point of a layer would be which would give me a point in time on this layer that the text is completely visible for so let me double tap e to bring up the expressions on my text box and I need to add in some more variables for the size so let me go into this and underneath the source I'm just gonna add a new variable var start equals s dot in point and then var end equals s dot out point then I'll make one more variable and type var mid equals the end or the out point minus the start / to close that off now what I'm trying to do here is find the difference between the start and end values and that will tell me the duration and then divide that number by 2 which will give me the midway point of that layer and that way it's based on the in and out point so wherever the layer is in time it'll subtract the end point from that endpoint giving me the duration of the layer and then half it to give me the midpoint of the layer however the way I wrote this isn't actually gonna work because of the order of operations remember multiplication and division is calculated before addition and subtraction to get the start to be subtracted from the end before dividing I need to put the end minus start in parentheses that way it'll calculate that number and then divide it by two so if that's my midpoint that's the halfway point of the layer I can now change the S dot out point to be just mid because that variable contains the halfway point in time for that layer I'll just replace all of this s dot out point with mid and I'll just copy these variables before I apply it and then I'll go into the position expression and paste in those variables and change all of these s doubt points to mid swap all of them out and now that text box jumps back to where it should be and it's basing the size on the text layer at the halfway point right in the dead center which is where the text is completely visible so it's no longer being affected by the animation in or out and the great thing about this is now I could actually just make a duplicate of this text box and style a different so I'll call it accents and maybe I'll turn off the fill so I'll go into the rectangle turn off that fill and make the stroke blue and then I'll increase the stroke width so it's got a little bit of depth and to change the caps to round Brown join and then increase the offset paths now it's got this kind of outline around it and I'll animate it with a trim paths so I'll add a trim pads here go to the beginning of my animation and change the end value down to zero set a keyframe I'll set a keyframe for the offset as well I'll go forward 30 frames change this to 100 change this to maybe 180 and then I'll copy and paste these keyframes onto the start value as well and shift these around a little bit and it'll just ease everything nicely and see how that looks so I've got this animated line moving around the box now I think that the scale animation is messing with it a little bit so I'll press you to bring up the keyframes get rid of that scale and maybe I'll get rid of the exciton the original one as well but I'll leave the keyframes just ease it manually and forget about that overshoot but now that box scales out and we've got this animated line going around it and maybe I don't like it starting down in the bottom left corner I can just take the offset and shift it around and now it's coming from the bottom left edge so this is very dynamic very customizable and because it's all being based on that source rect at time I can change this text to say something else and it's always going to update and fit that text so it's very very powerful and it doesn't have to be a square box either because they're shape layers I could just go in to the contents into the rectangle and turn up the roundness so it's kind of like this pill shape then I'll just increase the offset so I've got a little bit more margin and I'll do the same thing for the accents and you could even link up all of these properties from the accents to the original text box so that you wouldn't have to change these manually it opens up a lot of creative possibilities so there we go we've got something like that now I'll play it these values until I've got something that I'm completely happy with at the end it's going to animate off just like it should now there's one more part to source wrecked at time remember I said you could put two values in here and the second one was extents so we've got time and extents extense is a little bit confusing but I want to explain it just so you know if you ever see this written out you'll understand what it means I'm going to turn off my other layers for now so we can focus and the extents is basically something like a stroke around an object and I'm actually going to use another text layer to kind of demonstrate what these values are gonna look like so if I add another text layer I won't type anything in I can actually add in an expression just like any other property so I actually want to just borrow some expressions that we've already written out so I'll grab all of these variables again I'll just get rid of what I don't need and I'll paste that into the source text so my source right now is defined as this text layer I want to change that to this source rect at time layer so I'm going to replace that code and now all these other variables are being based on this layer instead of this one so I'm gonna get rid of some of this code I don't need any of this stuff in here I won't need the left or the top values just the width and the height and I'll get rid of that divided by two so I've got the source rect a time for the width and height of this text layer right up here and I want to display that in my new text layer so I'll write down some expression code right here to display these values in a text layer so I'm gonna start by putting in quotes width equals and then add a plus W for the source rector time width plus height equals plus h for the height on the source rector time semicolon to end it off and apply and I've got a whole bunch of text showing up now so I'm going to scale this down so it's easier to see it looks like I've got a typo on height and I also want to drop this height line down so I'm going to go right between width plus height and add a /n plus and that will drop it down a line and there we go now we've got two incredibly accurate numbers for the width and height of this layer now obviously this is really hard to look at I don't need to know these values to ten decimals I'm just gonna round them off simply by changing the variables a little bit so I'm gonna wrap my width and height in what's called a round variable to do this you start by typing capital M for math it's one of the very few times that you have a capital letters starting off the expression dot round open parentheses and then all the code I want and close parentheses and I'll do the same thing for the height math dot round open parentheses close parentheses that will round off these numbers so it's much much easier to see all right with all of that work out of the way now we can take a look at what this extents is actually doing the value defaults to being false so if you don't put anything in here for the second value or if you leave this blank it's going to default to time and false so this time and false is identical to not putting anything in there so if the extents are false that means it's not going to pay attention to anything that's not affecting the bounding box and that might seem a little confusing so what I'll do real quick is just draw you a box and then add a stroke to it so if I increase this stroke you'll notice the bounding box of that shape layer is not changing I can make this as big as I want and it's not going to change so if I actually take this little readout text layer that we just made and I change the source to being this box instead of this text I'll just pick that new box we get a width of 253 and a height of 253 and if I change this stroke nothing changes however if I come into my expressions at the source wrecked at time I say time , true and I put that on the width and the height those numbers change and as I increase or decrease this stroke you see that now because the extents are true it is accounting for that stroke in its calculations so that's great to know for shape layers it works great like that but for whatever reason when you add a stroke to a text layer and I'll turn off my raid and M colors this is easier to see if I increase the stroke of this text layer the bounding box you can see is also increasing not only that it's increasing beyond what the stroke actually is now I did a little bit of research on this and I couldn't really come up with a good answer as to why this happens other than text layers are just unique in the way that After Effects is rendering them and this bounding box is kind of representing the canvas for which the text is actually being generated so it's uniquely not going to behave how you expect with a text layer I think the easiest way to think about it is just looking at the bounding box if you're adding something to a layer that's pushing pixels outside of the bounding box those are the extents and if you include them then this source rect at time is going to account for them if you don't it will ignore them again the default is set to false so if you just leave these empty it's gonna look at the current time and not include the extents and my number drops down again this stroke isn't changing anything all right I'll go ahead and delete that box and that's gonna give me an expression error because I need to change my source back to this text layer here there we go apply it and now we're reading out the width and height of this text box again one final issue with this source rekted time expression is that it does not account for this scale of a layer the scale of my text layer right now is 100% if I scale it down the width and height are not changing this could definitely cause an issue if your text boxes and accents or any other elements that you're basing on the width and height of a layer aren't parented to that layer but we can just do a little bit of simple math to account for that so I'll go into my empty text layer double tap E and I want to define one more variable so var X scale equals and then expression pick whip the source text layers X scale value so I have that as a variable now and I want to put that above the width and height so that I can now use it in my width and height variables so I'm gonna go to the end of this source rect at time width and say times X scale divided by 100 I'll do that for both the width and the height I'll apply that and my numbers have not changed but if I take the scale now and scale this down see either the width and height are being scaled down as well and if I just check this math a little bit by just drawing a quick box roughly around the size of this text you were to that stroke we can see I'll double tap you that it is about 766 by 33 so we've got 766 and 44 looks like my height was a little bit off but I just manually type in 44 there we go we know that this box is sized correctly to that text so the way that this is working is we're just multiplying the width and height by the scale or the scale factor and then dividing it by 100 so effectively when this is 100 it is multiplying the entire width by 100 and then dividing it by 100 meaning that the number doesn't change but as it scales down say 250 it's going to multiply it by 50 and then divide that number by 100 so if we just left it at multiplying it by 50 it's obviously gonna be 50 times bigger than it should be but because we divide it by 100 it shifts the decimal point over and preserves the proper width and height and that's very very useful for making these expressions much more flexible all right there you have it hopefully now you have a very firm grasp on the source rekted time expression I found that it's incredibly helpful for making things like templates like a motion graphics template that you're gonna hand off to an editor you know a lower third that has a design based on the text and dynamically changes for whatever the editor types in there is just incredibly valuable and makes your life easier as a moe designer it's also just really great to know how to find these specific values and base other things off of them you can position these boxes within a comp based on the size and just tie them to sliders that are percentages instead of pixel values it opens up a lot of possibilities so hopefully you got a lot out of this tutorial thanks for watching and I'll catch you in the next one
Info
Channel: Jake In Motion
Views: 75,848
Rating: undefined out of 5
Keywords: After Effects, Animation, Motion Graphics, Mograph, Motion Design, Tutorial, Adobe, Adobe After Effects, Expressions
Id: CVliDoNgoCg
Channel Id: undefined
Length: 34min 32sec (2072 seconds)
Published: Tue Mar 13 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.