You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Konva中创建带动态文本定位的标注型垂直箭头

解决react-konva中带标注垂直箭头的文本定位问题

在使用Konva和react-konva绘制带尺寸标注的垂直箭头时,原实现存在两个核心问题:

  • 文本未实现垂直居中:Text组件默认原点在左上角,未考虑文本自身高度,导致位置偏移
  • 布局鲁棒性差:箭头与文本的间距采用硬编码值,修改字号或文本长度会直接导致布局错乱

解决方案:通过ref获取文本尺寸动态计算位置

react-konva的Text组件可以通过ref获取到Konva.Text实例,实例提供的getWidth()和getHeight()方法能准确获取文本的实际尺寸,基于这两个值就能动态计算出正确的文本位置:

  1. 垂直居中逻辑:让文本的垂直中点与箭头的垂直中点对齐,y坐标计算公式为 (y0 + y1) / 2 - 文本高度 / 2
  2. 动态间距逻辑:文本右侧与箭头左侧保持固定留白(可配置),x坐标计算公式为 箭头x坐标 - 文本宽度 - 留白值

修改后的完整代码

import { useState, useRef, useEffect } from 'react';
import { Stage, Layer, Group, Arrow, Text } from 'react-konva';

function AnnotatedVerticalArrow({ x, y0, y1, text, fontSize = 12, gap = 8 }) {
  const textRef = useRef(null);
  const [textPos, setTextPos] = useState({ x: 0, y: 0 });

  useEffect(() => {
    if (textRef.current) {
      const textWidth = textRef.current.getWidth();
      const textHeight = textRef.current.getHeight();
      // 动态计算文本的最终位置
      const targetX = x - textWidth - gap;
      const targetY = (y0 + y1) / 2 - textHeight / 2;
      setTextPos({ x: targetX, y: targetY });
    }
  }, [x, y0, y1, text, fontSize, gap]);

  return (
    <Group>
      <Arrow
        points={[x, y0, x, y1]}
        pointerAtBeginning={true}
        pointerAtEnding={true}
        fill="black"
        stroke="black"
      />
      <Text
        ref={textRef}
        x={textPos.x}
        y={textPos.y}
        text={text}
        fontSize={fontSize}
      />
    </Group>
  );
}

function App() {
  return (
    <Stage width={window.innerWidth} height={window.innerHeight}>
      <Layer>
        <AnnotatedVerticalArrow
          x={50}
          y0={0}
          y1={100}
          text="2.54"
          fontSize={14}
          gap={10}
        />
        {/* 测试不同参数的适配效果 */}
        <AnnotatedVerticalArrow
          x={150}
          y0={50}
          y1={200}
          text="10.00"
          fontSize={16}
          gap={8}
        />
      </Layer>
    </Stage>
  );
}

export default App;

补充说明

  • 用useEffect监听所有影响文本尺寸和位置的参数,参数变化时自动重新计算位置
  • 将字号、间距设为可配置props,提升组件复用性
  • 直接通过Konva实例获取尺寸,避开了measureText的潜在问题,准确性更高

内容的提问来源于stack exchange,提问作者比尔盖子

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 23:32:21