reactjsreact-konva

React-konva render dynamic Text inside Shape


I am Rendering shape name at bottom center of shape something like this. (Shape name is dynamic)

enter image description here

First approach---> I tried to render Shape name inside of Group of Shape but the problem i am facing when text name length increase it start affecting shape width. So i move to another way

Second Approach---> I have move Group of Shape name Outside group of Shape with same position of Shape. Here is my calculation for this

//on name change this will make move rechtangle to exact x position
if (shapeRef.current?.attrs?.x) {
  nameRef?.current?.parent.x(
    shapeRef.current?.attrs?.x - (nameRef?.current?.textWidth + 4) / 2
  );
}//this will move Child group same as shape group 
if (shapeRef.current?.attrs?.y) {
  nameRef?.current?.parent?.y(
     shapeRef.current?.attrs?.y +
          shapeRef?.current?.attrs?.height / 2 -
          7
  );
}//This will move shape to bottom area

This is working perfectly fine until i introduce rotation as soon as Parent rotation change This calculations fails as now i Need to move some time x and sometime y.

Here is example code

What i am looking for is Text should stay at bottom center enter image description here


Solution

  • When you place a text, make sure it follows the same coordinate system flow and rotation logic. Using group you can do this:

          <Group
            rotation={shapeProps.rotation}
            listening={false}
            x={shapeProps.x}
            y={shapeProps.y}
            offset={{
              x: shapeProps.width / 2,
              y: shapeProps.height / 2
            }}
          >
            <Rect
              ref={nameRefShape}
              height={15}
              width={textWidth} //this does not change as state change
              cornerRadius={5}
              fill="#000"
              x={shapeProps.width / 2 -textWidth / 2}
              y={shapeProps.height}
            />
            <Text
              ref={nameRef}
              x={shapeProps.width / 2 - textWidth / 2}
              y={shapeProps.height}
              text={shapeProps.name}
              ellipsis={true}
              //height={20}
              align="center"
              verticalAlign="middle"
              fontSize={13}
              fontFamily="Calibri"
              fill="#fff"
              background="#000"
              zIndex={3}
            />
          </Group>
    

    About the next width issue, don't change Konva attribute manually. User react and its state instead:

    const [textWidth, setTextWidth] = React.useState(0);
    
    React.useEffect(() => {
        //on name change this will make rechtangle equal to text length width
        setTextWidth(nameRef?.current?.getTextWidth() + 6);
    }, [shapeProps]);
    

    https://codesandbox.io/s/happy-frost-j4shrc?file=/src/index.js