question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

I am trying to surround a Konva.Text with a Konva.Rect, which requires that I measure the text before drawing the rectangle. How would you recommend that I accomplish this?

Currently it requires two passes with React to first render the Text and then render the Rectangle, since I can’t access the underlying Konva.Text element before it is rendered.

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Reactions:1
  • Comments:9 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
lavrtoncommented, Jan 11, 2018

@blueberryfan Something like this:

class MyText extends React.Component {
  componentDidMount() {
    // do your text calculations here
    const width = this.textNode.getTextWidth();
  }
  render() {
    return (
      <Text
        {...someProps}
        ref={node => {
          this.textNode = node;
        }}
      />
    );
  }
}

0reactions
damiangreencommented, Aug 24, 2021

@SyntaxRules the result of measureText appears to be less than the width of textRef.current.width() for some reason. I seem to have to hack a work around by adding additional pixels. It appears this is because measureText omits any padding applied. Is this a bug? Some example working code for those that arrive here.


const textPadding = 4

const TopologyNodeLabel = ({
  text,
  position: { x, y },
  included,
  nodeIsHovered,
}: Props) => {
  const { isDarkTheme, orientation } = useTopologyChartContextValue()
  const labelRef = useRef<Konva.Label>(null)
  const textRef = useRef<Konva.Text>(null)
  const textColor = isDarkTheme ? 'white' : 'black'
  const opacity = included || nodeIsHovered ? 1 : 0.5

  useEffect(() => {
    if (labelRef?.current && textRef?.current) {
      const width = textRef.current.measureSize(text).width + textPadding * 2
      const maxWidth =
        orientation === 'vertical'
          ? nodeLabelWidthVerticalOrientation
          : nodeLabelWidth

      const exceeds = width > maxWidth
      const newWidth = exceeds ? maxWidth : width

      textRef.current.setAttrs({
        ellipsis: exceeds,
        width: newWidth,
      } as Konva.TextConfig)

      if (orientation === 'vertical') {
        const newX = x - newWidth / 2
        labelRef.current.setAttrs({
          x: newX,
        })
      }
    }
  }, [orientation, x, text])

  const labelPosition =
    orientation === 'horizontal'
      ? { x: x + nodeLabelNodeOffset, y: y - 10 }
      : { x: x - nodeLabelWidth / 2, y: y + nodeLabelNodeOffset }
  return (
    <Label
      ref={labelRef}
      x={labelPosition.x}
      y={labelPosition.y}
      transformsEnabled="position"
      listening={false}
    >
      <Tag
        fill={isDarkTheme ? colors.midnight90 : colors.midnight10}
        opacity={opacity}
        listening={false}
        transformsEnabled="position"
      />
      <Text
        ref={textRef}
        text={text}
        padding={textPadding}
        fontFamily={fonts.dattoDIN}
        fill={textColor}
        opacity={opacity}
        wrap="none"
        listening={false}
        transformsEnabled="position"
      />
    </Label>
  )
}

export default TopologyNodeLabel

Read more comments on GitHub >

github_iconTop Results From Across the Web

CanvasRenderingContext2D.measureText() - Web APIs | MDN
measureText() method returns a TextMetrics object that contains information about the measured text (such as its width, for example).
Read more >
HTML canvas measureText() Method - W3Schools
The measureText() method returns an object that contains the width of the specified text, in pixels. Tip: Use this method if you need...
Read more >
HTML | canvas measureText() Method - GeeksforGeeks
The measureText() method is used to return an object that represents the width of the specified text in terms of pixels.
Read more >
HTML5 Canvas: Why does measuring text with measureText ...
I benchmarked offsetWidth() vs measureText and I am getting drastically different values. Shouldn't they be the same? Why are they different ...
Read more >
TextRenderer.MeasureText Method (System.Windows.Forms)
Provides the size, in pixels, of the specified text when drawn with the specified font in the specified device context, using the specified...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found