Answered

Text widget width attribute, multiple occurances

  • 25 June 2021
  • 2 replies
  • 71 views

Userlevel 2
Badge +6

Tried to find my answers in the doucumentation for text widgets, but without much success. This is what I’m looking at:

I can’t figure out which width attribute corresponds to what exactly since they are both different in value. And if both of these width attributes impact something different, or if they both just determine the actual width of the text widget, where one of the attributes has priority over the other. 

 

Also the reason why I would even want to set width manually, is that when creating a text widget with a API call and simply giving it some text, it doesn’t determine the expected width well enough, for the text to fit in a single line.

The call beneath will give me this result ^

await miro.board.widgets.create({ 

      "capabilities" : {

          "editable" : true

      },

      "scale" : textSize,

      "rotation" : 270,

      "style" : {

        "backgroundColor" : "transparent",

        "backgroundOpacity" : 1,

        "bold" : 0,

        "borderColor" : "transparent",

        "borderOpacity" : 1,

        "borderStyle" : 2,

        "borderWidth" : 2,

        "fontFamily" : 10,

        "highlighting" : 0,

        "italic" : 0,

        "padding" : undefined,

        "strike" : 0,

        "textAlign" : "l",

        "textColor" : "#1a1a1a",

        "underline" : 0

      },

      "text" : “200 mm”,

      "type": "TEXT",

      "x" : Xpos,

      "y" : Ypos

    })

 

EDIT: The text width also doesn’t seem to correspond with width of shape widgets, where a shape of width 3000 can be same in width with a text widget of width 300 for example

 

So my question is, if there is a possibility for the text to automatically appear on 1 line, if not, which width attribute should I target, and what are the differences between  these 2

icon

Best answer by Max Harper 25 June 2021, 16:20

@Sami Ljimari  
I share your confusion. 

-- Here’s what I’ve come understand from using the SDK. … API has different capabilities/limitations.   

 

With my little reverse engineering hat on….(who knows really)
Seems like this is a minimum viable implementation of the data representation and method structure, a compromise by the platform developers early on in V.1 of API / SDK.  This setup allows one to simply update scale on a text items (esp. as it might be updated in a larger collection of items) and get a consistent scale (which extends not only to the bounds of the text box but also to the ‘font size’.   One can separately update width or height and just change the bounds, leaving font size unchanged.  It retains 1 accurate representation of actual width and allows only 1 value to go untrue.  This roughly mirrors the manual UI experience/logic the Miro has implemented. 

 

You can see what Miro did/went through to build their custom text canvas widget here - a fascinating read… and seems to give some context as to why they might be a bit compromising around the text feature. 

 

What I find through testing with SDK:  

On a text widget, there is:

  • A: widget.bounds.width
  • B: widget.scale
  • C: widget.width
  • D: widget.height

A = B * C    ⇒  if scale == 1,  A = C

A: the actual width of the widget on the board 

D: widget height, is actually hidden on the read (widget.get()) of the object but is accepted in the update function.

 

Operations

  • To update font size (along with both bounds), change scale (B above).
  • To update the width or height update C,D above. 
  • To update ‘font size’ while preserving bounds update each inverse to each other.
  • Font size, new lines and height relationship.

    • Font size on a text widget is controlled through SDK by scale (B above)... 
    • New lines can be added to text using html tags. ex: 
      •  miro.board.widgets.update({id: "3074457360644209231",height: 36, text: '<p>hello</p><p>world</p>'})
      •  

    • On a text widget where scale == 1, the text reads size 14 on the board UI and if (for example has been created fresh from a user via manual UI) the height will be 20
      • this means that that the base config for text to bounds is: text size * # lines = 70% of height.  or:
      • text size (UI) * scale *number of lines * 1.43 = height

 

Thinking of these sensitivities to implementing the textbox. . . it kinda makes sense why, in the board UI, we can’t control: 

  • padding
  • line height 
  • have multiple font sizes within one text widget ( while still having ability to bold)  

If we were allowed to it could make these API calls/functions and the math much more complicated. 

 

Hope some of this is helpful,

Max

View original

2 replies

Userlevel 7
Badge +11

@Sami Ljimari  
I share your confusion. 

-- Here’s what I’ve come understand from using the SDK. … API has different capabilities/limitations.   

 

With my little reverse engineering hat on….(who knows really)
Seems like this is a minimum viable implementation of the data representation and method structure, a compromise by the platform developers early on in V.1 of API / SDK.  This setup allows one to simply update scale on a text items (esp. as it might be updated in a larger collection of items) and get a consistent scale (which extends not only to the bounds of the text box but also to the ‘font size’.   One can separately update width or height and just change the bounds, leaving font size unchanged.  It retains 1 accurate representation of actual width and allows only 1 value to go untrue.  This roughly mirrors the manual UI experience/logic the Miro has implemented. 

 

You can see what Miro did/went through to build their custom text canvas widget here - a fascinating read… and seems to give some context as to why they might be a bit compromising around the text feature. 

 

What I find through testing with SDK:  

On a text widget, there is:

  • A: widget.bounds.width
  • B: widget.scale
  • C: widget.width
  • D: widget.height

A = B * C    ⇒  if scale == 1,  A = C

A: the actual width of the widget on the board 

D: widget height, is actually hidden on the read (widget.get()) of the object but is accepted in the update function.

 

Operations

  • To update font size (along with both bounds), change scale (B above).
  • To update the width or height update C,D above. 
  • To update ‘font size’ while preserving bounds update each inverse to each other.
  • Font size, new lines and height relationship.

    • Font size on a text widget is controlled through SDK by scale (B above)... 
    • New lines can be added to text using html tags. ex: 
      •  miro.board.widgets.update({id: "3074457360644209231",height: 36, text: '<p>hello</p><p>world</p>'})
      •  

    • On a text widget where scale == 1, the text reads size 14 on the board UI and if (for example has been created fresh from a user via manual UI) the height will be 20
      • this means that that the base config for text to bounds is: text size * # lines = 70% of height.  or:
      • text size (UI) * scale *number of lines * 1.43 = height

 

Thinking of these sensitivities to implementing the textbox. . . it kinda makes sense why, in the board UI, we can’t control: 

  • padding
  • line height 
  • have multiple font sizes within one text widget ( while still having ability to bold)  

If we were allowed to it could make these API calls/functions and the math much more complicated. 

 

Hope some of this is helpful,

Max

Userlevel 2
Badge +6

@Max Harper 

Thanks for the detailed reply. Since I posted the question I also attempted some “reverse engineering” to maybe find a link between the two width attributes, spent about a hour trying to figure out if there is a “hidden multiplier” of sorts which just converted one value to another, for some scaling reasons maybe, this didn’t work out.

 

What I found out though was that the standalone width param doesn’t have to change, and I don’t have to interfere with parameters inside of bounds. The reason being, that I expect to have a maximum amount of characters, and the width param can handle this perfectly by the seems of it, I currently set it to 120 for each text widget I create with up to 9 characters and it never overflows and leaves just enough space.

 

This means I could find which character takes up the most space (probably “M”) and the exact value of width it needs and just multiply the largest possible unit by amount of characters in the text to get very precise width with no possibility of overflow to next line and not much excess space left. Which is probably what I’ll stick with.

 

The point you made about scale definitely makes sense, and I can understand why they chose that road to go with, since manual users couldn’t care less about bounds, but much rather have the whole widget scale with font size.

 

The miro development article you linked is very interesting, and adds a lot of insight on some of the design choices. There is a lot to take from it for me, I’ll probably have to re-read it once again to grasp all the information mentioned. 

 

About the SDK segment, I found out about most of the things you mention by trial and error, but you explained it very well and anyone viewing this question might find it very helpful, I still think that the SDK provides a lot of useful interactions, mainly considering the styling options of widgets, I just wish some stuff was explained more in the documentation, so that we wouldn’t have to have these kinds of segments to understand a few simple attributes, how they work and what they actually affect.

 

widget height, is actually hidden on the read (widget.get()) of the object but is accepted in the update function.” I assume you mean there’s another height attribute just like the standalone width which can be in fact accessed and tweaked but isn’t shown with the get call. Because there is a height attribute inside bounds of each widget from what I can see

 

 

Thanks for your help and time Max, I appriciate it :)

 

 

 

 

Reply