-
Auto Text Wrap Using String Pixel Length
Hello,
I’m trying to code a bit of text that will auto wrap text when the user input string hits a certain max pixel length.
I know after affects does not natively allow you to get the pixel length of a text layer, so I’ve created a look up table using string.match. I went in and manually counted the pixel width of each character for the font (its variable width) then grouped them into variables based on size. Then, I’m using str.match to see how many times a character from each size group is used, then multiplying that result by its pixel length. At the end everything is summed together to get the overall string length.
I’ve been using this to drive the position of other elements on screen and it seems to be working well, and its much less processor intensive then some of the screen match versions I’ve seen to calculate text length in AE.
I’ve also got a bit of code that takes care of the text wrapping perfectly, however, it relys on the str.length being over a trigger amount to make the split, then inserting the “\n” at that location in the string. I’m not quite sure how to wrap my head around using this pixel width input as the trigger, but still using str.length to find the appropriate insert point in the string. I keep trying different things but getting errors.
I’ve posted to code for the pixel width counter and the text wrap bellow. Any help would be greatly appreciated!
//On a separate layer from the text wrap code, this section counts the input string pixel width//defines the variables
input = thisComp.layer("ENTER TEXT").text.sourceText + "\n";//this "\n" was needed to account for some of the matches in the string like other "\"s
var line = input.split("\r")[0];var a = (line.match(/i/g)||[]).length;
var b = (line.match(/:/g)||[]).length;
var c = (line.match(/\.|!/g)||[]).length;
var d = (line.match(/l|,|;|‘|\]|\[|\|/g)||[]).length;
var e = (line.match(/\`|\(|\)|j/g)||[]).length;
var f = (line.match(/\-/g)||[]).length;
var g = (line.match(/1| |\}|\{/g)||[]).length;
var h = (line.match(/r/g)||[]).length;
var i = (line.match(/f|t|\/|\\|\u201C|\u201D/g)||[]).length;
var j = (line.match(/s|J|\*/g)||[]).length;
var k = (line.match(/z|L|\?/g)||[]).length;
var l = (line.match(/a|c|h|n|u|F|2|7|~/g)||[]).length;
var m = (line.match(/e|k|E|S|3|5|8|\#|_|/g)||[]).length;
var n = (line.match(/B|6|9|0|\<|\>|\"/g)||[]).length;
var o = (line.match(/b|d|g|o|p|q|v|x|y|P|R|Z|4|\=|\+|\$/g)||[]).length;
var p = (line.match(/T|U|\^/g)||[]).length;
var q = (line.match(/H/g)||[]).length;
var r = (line.match(/K|\&/g)||[]).length;
var s = (line.match(/|D|N/g)||[]).length;
var t = (line.match(/|C|G|V|X|Y|/g)||[]).length;
var u = (line.match(/A/g)||[]).length;
var v = (line.match(/O|\@/g)||[]).length;
var w = (line.match(/m|M|\%/g)||[]).length;
var x = (line.match(/Q/g)||[]).length;
var y = (line.match(/w/g)||[]).length;
var z = (line.match(/W/g)||[]).length;//multiply input variables by each characters pixel width
var a1 = a*9.5;
var b1 = b*9.5;
var c1 = c*9.5;
var d1 = d*10.5
var e1 = e*12.5;
var f1 = f*13.5;
var g1 = g*15.5;
var h1 = h*16.5;
var i1 = i*18.5;
var j1 = j*19.5;
var k1 = k*19.5;
var l1 = l*20.5;
var m1 = m*21.5;
var n1 = n*25.5;
var o1 = o*23.5;
var p1 = p*24.5;
var q1 = q*25.5;
var r1 = r*26.5;
var s1 = s*27.5;
var t1 = t*28.5;
var u1 = u*30.5;
var v1 = v*31.5;
var w1 = w*32.5;
var x1 = x*34.5;
var y1 = y*37.5;
var z1 = z*40.5;//prints the total value
(a1+b1+c1+d1+e1+f1+g1+h1+i1+j1+k1+l1+m1+n1+o1+p1+q1+r1+s1+t1+u1+v1+w1+x1+y1+z1);
//
// On another layer, this is the text wrap code that needs to be modified
////define variables
var str = thisComp.layer("ENTER TEXT").text.sourceText; //user input, source of string
var strPixLeng = parseInt(thisComp.layer("var CharCounter4OverlayLength").text.sourceText); //layer countering pixel width//call function
var result = stringDivider(str, 60, "\n", strPixLeng);
result;// define function
function stringDivider(str, width, spaceReplacer, strPixLeng) {
if (str.length>width) {
var p=width
for (;p>0 && str[p]!=' ';p--) {
}
if (p>0) {
var left = str.substring(0, p);
var right = str.substring(p+1);
return left + spaceReplacer + stringDivider(right, width, spaceReplacer);
}
}
return str;
}