Skip to main content
Question

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


Alex_FG

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
  • 4873 replies
  • July 1, 2023

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


Alex_FG
  • Author
  • New Participant
  • 32 replies
  • July 1, 2023

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


Alex_FG
  • Author
  • New Participant
  • 32 replies
  • July 1, 2023

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


tank666
  • 4873 replies
  • 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.


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings