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

在React Konva中实现矩形各边长度居中显示的技术问询

在React Konva矩形的四条边中心显示长度的实现方案

核心思路

要实现该功能,关键是基于矩形的x/y/width/height计算每条边的中心坐标和长度,再通过Konva.Text组件定位到对应位置,利用文本对齐属性确保显示在边的中心。


步骤1:确认矩形数据结构

先保证Redux的dataReadingSlice中存储的矩形对象包含x、y、width、height基础属性(绘制矩形时已记录这些值),示例结构如下:

// dataReadingSlice.js
const initialState = {
  annotations: [
    {
      id: 'rect-1',
      x: 50,
      y: 50,
      width: 200,
      height: 150
      // 其他自定义属性
    }
  ]
};

步骤2:编写边参数计算工具函数

在DrawAnnotations.js中添加工具函数,计算每条边的长度、中心坐标,以及文本的显示位置(因Text默认锚点为左上角,需偏移文本自身一半宽高实现居中):

// DrawAnnotations.js
const calculateEdgeParams = (rect) => {
  const { x, y, width, height } = rect;

  // 上边:水平方向,长度=width
  const topEdge = {
    length: width.toFixed(1),
    textX: x + width / 2,
    textY: y - 15, // 文本置于边上方,避免重叠,可调整偏移量
    align: 'center',
    verticalAlign: 'middle'
  };

  // 下边:水平方向,长度=width
  const bottomEdge = {
    length: width.toFixed(1),
    textX: x + width / 2,
    textY: y + height + 15, // 文本置于边下方
    align: 'center',
    verticalAlign: 'middle'
  };

  // 左边:垂直方向,长度=height
  const leftEdge = {
    length: height.toFixed(1),
    textX: x - 25, // 文本置于边左侧
    textY: y + height / 2,
    align: 'right',
    verticalAlign: 'middle',
    rotation: -90 // 垂直显示文本
  };

  // 右边:垂直方向,长度=height
  const rightEdge = {
    length: height.toFixed(1),
    textX: x + width + 10, // 文本置于边右侧
    textY: y + height / 2,
    align: 'left',
    verticalAlign: 'middle',
    rotation: 90 // 垂直显示文本
  };

  return { topEdge, bottomEdge, leftEdge, rightEdge };
};

步骤3:渲染矩形与长度文本

在DrawAnnotations组件中,遍历Redux中的矩形数据,同时渲染矩形和四条边的长度文本:

// DrawAnnotations.js
import { useSelector } from 'react-redux';
import { Rect, Text, Group } from 'react-konva';

const DrawAnnotations = () => {
  const annotations = useSelector(state => state.dataReading.annotations);

  return (
    <>
      {annotations.map(rect => {
        const edgeParams = calculateEdgeParams(rect);
        return (
          <Group key={rect.id}>
            {/* 绘制矩形 */}
            <Rect
              x={rect.x}
              y={rect.y}
              width={rect.width}
              height={rect.height}
              stroke="blue"
              strokeWidth={2}
              fill="rgba(0,0,255,0.1)"
            />

            {/* 上边长度文本 */}
            <Text
              text={`${edgeParams.topEdge.length}px`}
              x={edgeParams.topEdge.textX}
              y={edgeParams.topEdge.textY}
              fontSize={12}
              fill="black"
              align={edgeParams.topEdge.align}
              verticalAlign={edgeParams.topEdge.verticalAlign}
            />

            {/* 下边长度文本 */}
            <Text
              text={`${edgeParams.bottomEdge.length}px`}
              x={edgeParams.bottomEdge.textX}
              y={edgeParams.bottomEdge.textY}
              fontSize={12}
              fill="black"
              align={edgeParams.bottomEdge.align}
              verticalAlign={edgeParams.bottomEdge.verticalAlign}
            />

            {/* 左边长度文本 */}
            <Text
              text={`${edgeParams.leftEdge.length}px`}
              x={edgeParams.leftEdge.textX}
              y={edgeParams.leftEdge.textY}
              fontSize={12}
              fill="black"
              align={edgeParams.leftEdge.align}
              verticalAlign={edgeParams.leftEdge.verticalAlign}
              rotation={edgeParams.leftEdge.rotation}
            />

            {/* 右边长度文本 */}
            <Text
              text={`${edgeParams.rightEdge.length}px`}
              x={edgeParams.rightEdge.textX}
              y={edgeParams.rightEdge.textY}
              fontSize={12}
              fill="black"
              align={edgeParams.rightEdge.align}
              verticalAlign={edgeParams.rightEdge.verticalAlign}
              rotation={edgeParams.rightEdge.rotation}
            />
          </Group>
        );
      })}
    </>
  );
};

export default DrawAnnotations;

细节调整与注意事项

  • 若矩形支持拖拽、缩放,需确保Redux中矩形数据实时更新,工具函数会自动重新计算参数,文本位置同步更新。
  • 可根据需求调整文本的fontSize、fill、偏移量等样式,或添加backgroundFill属性让文本更清晰。
  • 若需要极致精准的居中,可通过Text组件的getClientRect()方法获取文本实际宽高,动态调整textX/textY值。

内容的提问来源于stack exchange,提问作者Deep Kakkar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:23:00