Answers.Body: <p>Looks like Adobe have come to the party on this one. A new update as of After Effects CC 2014.2 (13.2) has a sourceRectAtTime() method that does exactly what I'm wanting. To quote <a href="http://blogs.adobe.com/aftereffects/2014/12/after-effects-cc-2014-2-13-2.html" rel="nofollow">their blur</a>b:</p>
  
  <blockquote>
    <p>You can now read the rectangle bounds of a layer’s content, including
    the corrected bounds of a text layer, for any time in a composition.
    The sourceRectAtTime() method from the After Effects scripting API is
    now accessible in expressions as a read-only layer object attribute.</p>
  </blockquote>
  
  <p>Yee-hah!</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-12-21T20:12:10.487Z
Answers.Text: Oh cool finally. Thanks for updating the question with this info.
Answers.UserDisplayName: timonsku
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-12-19T06:16:04.410Z
Answers.LastActivityDate: 2014-12-19T06:16:04.410Z
Answers.UserDisplayName: stib
Answers.Body: <p>So you want the width of the whole text object no single characters?
  In that case you could use this: <a href="http://motionboutique.com/text-bounds-expresssion-580/" rel="nofollow">http://motionboutique.com/text-bounds-expresssion-580/</a>
  A tutorial plus sample project on how to get the bounding box of a text layer.</p>
  
  <p>In case the link dies, here is the complete expression they use to determine the bounding box.</p>
  
  <pre><code>step = 1.0; // higher values speed things up (2 means two times faster) but reduce precision
  L = thisComp.layer("MyTextLayer"); // text layer whose size must be evaluated
  
  w = thisComp.width;
  h = thisComp.height;
  halfW = w / 2;
  halfH = h / 2;
  halfStep = step / 2;
  
  left = w;
  right = 0;
  top = h;
  bottom = 0;
  
  // find left
  found = false;
  for (x = 0; !found &amp;&amp; x &lt; w; x+=step)
  {
      if (L.sampleImage([x,halfH], [halfStep,halfH], true)[3] &gt; 0)
      {
          found = true;
          if (x &lt; left) 
              left = x;
      }
  }
  // find right
  found = false;
  for (x = w; !found &amp;&amp; x &gt;= 0; x-=step)
  {
      if (L.sampleImage([x,halfH], [halfStep,halfH], true)[3] &gt; 0)
      {
          found = true;
          if (x &gt; right) 
              right = x;
      }
  }
  // find top
  found = false;
  for (y = 0; !found &amp;&amp; y &lt; h; y+=step)
  {
      if (L.sampleImage([halfW,y], [halfW,halfStep], true)[3] &gt; 0)
      {
          found = true;
          if (y &lt; top) 
              top = y;
      }
  }
  // find bottom
  found = false;
  for (y = h; !found &amp;&amp; y &gt;= 0; y-=step)
  {
      if (L.sampleImage([halfW,y], [halfW,halfStep], true)[3] &gt; 0)
      {
          found = true;
          if (y &gt; bottom) 
              bottom = y;
      }
  }
  
  /*"Size of text\n" + (right-left) + "x" + (bottom-top)*/
  left + "," + top + "," + (right-left) + "," + (bottom-top)
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-14T09:07:04.080Z
Answers.Text: Thanks for that. This looks like it samples the pixels to see if there's any opacity and determines the size that way. Good thinking outside the square. I'll have to test to see if it works on animated text.
Answers.UserDisplayName: stib
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-14T18:51:01.780Z
Answers.Text: Expressions evaluate per frame so animation shouldn't be any issue. It will just slow your rendertime down a little as the sampleImage function is quite CPU heavy.
Answers.UserDisplayName: timonsku
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-10-26T12:15:09.097Z
Answers.Text: Expressions evaluate each time the frame is *rendered*. If you have motion blur on, the layer can get rendered dozens of time per-frame. So an expression that slows down the playback a little while you're working on it can suddenly become a beast when you turn on MB in the render.
Answers.UserDisplayName: stib
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-11-13T17:05:49.043Z
Answers.LastActivityDate: 2014-11-13T17:05:49.043Z
Answers.UserDisplayName: timonsku
Body: <p>I have a type effect that requires a couple of layers, one with the type, and another moving behind the letters as they appear (simulating the little text bubbles you get when typing on an iPhone). It's very tedious animating the position of the bottom layer to match the text, so I'm wondering if it's possible to use any javascript tools to measure the characters and drive the position value.</p>
  
  <p>Currently I have an expression driving the opacity like this, to automatically turn the background off for spaces:</p>
  
  <pre><code>theOffset=thisComp.layer(1).text.animator("Animator 1").selector("Range Selector 1").offset;
  if (thisComp.layer(1).text.sourceText.substr(theOffset, 1) == " " ){0} else {100}
  </code></pre>
  
  <p>and another that folows the text animator range selector so that I can retime if I want without having to nudge keyframes till doomsday:</p>
  
  <pre><code>theOffset=thisComp.layer(1).text.animator("Animator 1").selector("Range Selector 1").offset;
  try {
      transform.position.key(theOffset + 1).value
  }
  catch(error){[-10000,0]}//effectively hide it on errors (like the index going out of bounds)
  </code></pre>
  
  <p>…but this relies on me going through and creating keyframes to match the spacing of all the letters in the text, and frankly I'd rather be doing something else with the time that takes. so I'm trying to find a string method that I could use like this:</p>
  
  <pre><code>xOffset = thisComp.layer(1).text.sourceText.substr(1, theOffset).getTextWidth()
  </code></pre>
  
  <p>but <strong>getTextWidth</strong> obviously isn't a valid method. Is there a JS method that can get the size of a string on screen? There seems to be several solutions for this when the client is a web browser, but I can't find any that work for AE expressions.</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-12-19T06:19:26.900Z
Comments.Text: No, I'm talking expressions. A lot of undocumented javascript creeps into expressions; for example many of the javascript string methods are there, like regex and so on.
Comments.UserDisplayName: stib
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-11-13T10:24:49.450Z
Comments.Text: As you are asking for JavaScript, I'm assuming you are using ExtendScript and not the limited After Effects expressions you apply directly to layers?
Comments.UserDisplayName: timonsku
Tags: <after-effects><after-effects-expressions>
Title: Can you measure the width of a character in an AE expression?
UserDisplayName: stib
ThreadText: # Can you measure the width of a character in an AE expression?
  
  (Asked by: username_0 on 2014-11-12)
  
  I have a type effect that requires a couple of layers, one with the type, and another moving behind the letters as they appear (simulating the little text bubbles you get when typing on an iPhone). It's very tedious animating the position of the bottom layer to match the text, so I'm wondering if it's possible to use any javascript tools to measure the characters and drive the position value.
  
  Currently I have an expression driving the opacity like this, to automatically turn the background off for spaces:
  
  ```
  theOffset=thisComp.layer(1).text.animator("Animator 1").selector("Range Selector 1").offset;
  if (thisComp.layer(1).text.sourceText.substr(theOffset, 1) == " " ){0} else {100}
  
  ```
  
  and another that folows the text animator range selector so that I can retime if I want without having to nudge keyframes till doomsday:
  
  ```
  theOffset=thisComp.layer(1).text.animator("Animator 1").selector("Range Selector 1").offset;
  try {
      transform.position.key(theOffset + 1).value
  }
  catch(error){[-10000,0]}//effectively hide it on errors (like the index going out of bounds)
  
  ```
  
  …but this relies on me going through and creating keyframes to match the spacing of all the letters in the text, and frankly I'd rather be doing something else with the time that takes. so I'm trying to find a string method that I could use like this:
  
  ```
  xOffset = thisComp.layer(1).text.sourceText.substr(1, theOffset).getTextWidth()
  
  ```
  
  but **getTextWidth** obviously isn't a valid method. Is there a JS method that can get the size of a string on screen? There seems to be several solutions for this when the client is a web browser, but I can't find any that work for AE expressions.
  
  **Tags:** after-effects, after-effects-expressions
  
  > **Comments:**
  > **username_1**: As you are asking for JavaScript, I'm assuming you are using ExtendScript and not the limited After Effects expressions you apply directly to layers?  
  > **username_0**: No, I'm talking expressions. A lot of undocumented javascript creeps into expressions; for example many of the javascript string methods are there, like regex and so on.  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_0 on 2014-12-19. Score: 2 | Accepted answer
  
  Looks like Adobe have come to the party on this one. A new update as of After Effects CC 2014.2 (13.2) has a sourceRectAtTime() method that does exactly what I'm wanting. To quote [their blur](http://blogs.adobe.com/aftereffects/2014/12/after-effects-cc-2014-2-13-2.html)b:
  
  > You can now read the rectangle bounds of a layer’s content, including
  > the corrected bounds of a text layer, for any time in a composition.
  > The sourceRectAtTime() method from the After Effects scripting API is
  > now accessible in expressions as a read-only layer object attribute.
  
  Yee-hah!
  
  > **Comments:**
  > **username_1**: Oh cool finally. Thanks for updating the question with this info.  
  
  ---
  
  ### Answer by username_1 on 2014-11-13. Score: 2
  
  So you want the width of the whole text object no single characters?
  In that case you could use this: <http://motionboutique.com/text-bounds-expresssion-580/>
  A tutorial plus sample project on how to get the bounding box of a text layer.
  
  In case the link dies, here is the complete expression they use to determine the bounding box.
  
  ```
  step = 1.0; // higher values speed things up (2 means two times faster) but reduce precision
  L = thisComp.layer("MyTextLayer"); // text layer whose size must be evaluated
  
  w = thisComp.width;
  h = thisComp.height;
  halfW = w / 2;
  halfH = h / 2;
  halfStep = step / 2;
  
  left = w;
  right = 0;
  top = h;
  bottom = 0;
  
  // find left
  found = false;
  for (x = 0; !found && x < w; x+=step)
  {
      if (L.sampleImage([x,halfH], [halfStep,halfH], true)[3] > 0)
      {
          found = true;
          if (x < left) 
              left = x;
      }
  }
  // find right
  found = false;
  for (x = w; !found && x >= 0; x-=step)
  {
      if (L.sampleImage([x,halfH], [halfStep,halfH], true)[3] > 0)
      {
          found = true;
          if (x > right) 
              right = x;
      }
  }
  // find top
  found = false;
  for (y = 0; !found && y < h; y+=step)
  {
      if (L.sampleImage([halfW,y], [halfW,halfStep], true)[3] > 0)
      {
          found = true;
          if (y < top) 
              top = y;
      }
  }
  // find bottom
  found = false;
  for (y = h; !found && y >= 0; y-=step)
  {
      if (L.sampleImage([halfW,y], [halfW,halfStep], true)[3] > 0)
      {
          found = true;
          if (y > bottom) 
              bottom = y;
      }
  }
  
  /*"Size of text\n" + (right-left) + "x" + (bottom-top)*/
  left + "," + top + "," + (right-left) + "," + (bottom-top)
  
  ```
  
  > **Comments:**
  > **username_0**: Thanks for that. This looks like it samples the pixels to see if there's any opacity and determines the size that way. Good thinking outside the square. I'll have to test to see if it works on animated text.  
  > **username_1**: Expressions evaluate per frame so animation shouldn't be any issue. It will just slow your rendertime down a little as the sampleImage function is quite CPU heavy.  
  > **username_0**: Expressions evaluate each time the frame is *rendered*. If you have motion blur on, the layer can get rendered dozens of time per-frame. So an expression that slows down the playback a little while you're working on it can suddenly become a beast when you turn on MB in the render.  
  
  ---
  
  