Skip to main content
Alex_FG
New Participant
July 1, 2023
Question

Is it possible to create a text object temporarily to measure its size?

  • July 1, 2023
  • 4 replies
  • 346 views

I am trying a scheme where to measure an object’s size in the middle of a calculation, using an async mechanism I send a request to Figma and it sends a response back. What I’m asking is to measure the size of a text object.

So I send all the data to Figma, create the object, and then try to read its width and height, send back the result. Here’s the code that does this:

function figGetObjectSize(genObj)
{
    const figObj = figCreateObject(genObj);
    
    const width  = figObj.width;
    const height = figObj.height;

    figObj.remove();

    figPostMessageToUi(
    {
        cmd: 'uiForwardToGenerator',
        msg: 
        {
            cmd:     'returnFigGetObjectSize',
            objectId: genObj.objectId,
            width:    width,
            height:   height
        }
    });
}

figCreateObject() eventually calls this function:

function figCreateText(genText)
{
    const figText = figma.createText();
    
    if (!genTextIsValid(genText))
        return figText;

    (async function() 
    {
        const fontName = 
        { 
            family: genText.font, 
            style:  genText.style
        };

        await figma.loadFontAsync(fontName); 

        figText.fontName      = fontName;
        figText.fontSize      = Math.max(1, genText.size);
        
        figText.characters    = genText.text;

        figText.lineHeight    = {unit: 'PERCENT', value: genText.lineHeight   };
        figText.letterSpacing = {unit: 'PERCENT', value: genText.letterSpacing};

             if (genText.alignH == 0) figText.textAlignHorizontal = 'LEFT';
        else if (genText.alignH == 1) figText.textAlignHorizontal = 'CENTER';
        else if (genText.alignH == 2) figText.textAlignHorizontal = 'RIGHT';
        else if (genText.alignH == 3) figText.textAlignHorizontal = 'JUSTIFIED';

             if (genText.alignV == 0) figText.textAlignVertical   = 'TOP';
        else if (genText.alignV == 1) figText.textAlignVertical   = 'CENTER';
        else if (genText.alignV == 2) figText.textAlignVertical   = 'BOTTOM';

        setObjectTransform(figText, genText);
        setObjectProps    (figText, genText);

        if (     genText.width  == 0
              && genText.height == 0) figText.textAutoResize = 'WIDTH_AND_HEIGHT';
        else if (genText.width  == 0) figText.textAutoResize = 'HEIGHT';
        else                          figText.textAutoResize = 'NONE';

    })();

    return figText;
}

The code is correct, because it works during normal functioning of my plugin, but when I try to use it like I do in the first function, I get the following error:

Error: in set_fontName: The node with id "511:14141" does not exist

What’s the issue here? Is the temporary text object not being created? Is figma.createText() async somehow?

This topic has been closed for replies.

4 replies

tank666
July 1, 2023

You are removing the node before the async font load function has completed.

UX/UI designer. Figma expert. Creator and developer of plugins and widgets for Figma and FigJam. Check out my resources in Figma Community: figma.com/@tank
Alex_FG
Alex_FGAuthor
New Participant
July 1, 2023

🤦‍♂️ 🤦‍♂️ 🤦‍♂️ 🤦‍♂️ 🤦‍♂️ 🤦‍♂️ 🤦‍♂️

Alex_FG
Alex_FGAuthor
New Participant
July 1, 2023

Hmmm, actually it happens even if I don’t remove the temp object…

tank666
July 1, 2023

As soon as the call to the async font loading function starts, JavaScript adds it to the queue and continues to call the synchronous code of the main function.

Delete the anonymous wrapper function inside the figCreateText() function. Make this function asynchronous and wait for it to complete in the figGetObjectSize() function.

UX/UI designer. Figma expert. Creator and developer of plugins and widgets for Figma and FigJam. Check out my resources in Figma Community: figma.com/@tank