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

React环形文字反转:实现底部环形文字从左到右可读

解决React CurvedText组件底部弧形文字正向排列问题

修改后的完整代码

import {
  PropsWithChildren,
  useLayoutEffect,
  useMemo,
  useRef,
  useState,
} from 'react';

interface ICurvedText extends PropsWithChildren {
  text: string;
}

export const CurvedText = ({ text, children }: ICurvedText) => {
  // 修正ref类型:对应外层div而非Heading
  const ref = useRef<HTMLDivElement>(null);
  const [wrapperWidth, setWrapperWidth] = useState(0);

  useLayoutEffect(() => {
    const updateWidth = () => {
      const width = ref.current?.offsetWidth;
      if (width) setWrapperWidth(width);
    };
    // 初始化获取宽度
    updateWidth();
    // 监听窗口resize,适配尺寸变化
    window.addEventListener('resize', updateWidth);
    return () => window.removeEventListener('resize', updateWidth);
  }, []);

  const roundedText = useMemo(() => {
    if (!wrapperWidth) return [];
    const chars = text.split('');
    // 移除不必要的字符反转,保持原始阅读顺序
    return chars.map((char: string, i: number) => {
      // 计算每个字符的旋转角度:从-90°到90°均匀分布,对应下半圆从左到右的位置
      const rotation = (i / (chars.length - 1)) * 180 - 90;
      const radius = wrapperWidth / 2;
      return (
        <div
          className="text-white font-thin text-xs"
          style={{
            transform: `rotate(${rotation}deg)`,
            // 旋转原点设为容器底部中心,确保字符沿下半圆排列
            transformOrigin: `${radius}px ${wrapperWidth}px`,
            position: 'absolute',
            left: '50%',
            top: '100%',
            // 偏移自身一半宽度,让字符中心对齐圆弧
            marginLeft: '-5px',
            width: '10px',
            textAlign: 'center',
          }}
          key={i}
        >
          {char}
        </div>
      );
    });
  }, [text, wrapperWidth]);

  return (
    <div
      ref={ref}
      style={
        wrapperWidth
          ? {
              width: wrapperWidth,
              height: wrapperWidth,
            }
          : {}
      }
      className="relative rounded-full flex justify-center items-center"
    >
      <>
        {children}
        <div className="absolute inset-0">{roundedText}</div>
      </>
    </div>
  );
};

关键修改说明

  • 修正Ref类型:将HTMLHeadingElement改为HTMLDivElement,与外层容器的DOM类型匹配,避免类型错误。
  • 移除字符反转:删除reversed变量,直接使用原始字符数组,保证文字从左到右的阅读顺序。
  • 调整旋转角度计算:将角度范围从0°~180°改为-90°~90°,让字符均匀分布在圆形的下半部分,第一个字符在左侧(-90°),最后一个在右侧(90°)。
  • 修改旋转原点:将transformOrigin设为容器底部中心(${radius}px ${wrapperWidth}px),确保字符围绕圆形底部旋转,形成下半圆弧排列。
  • 优化位置偏移:添加marginLeft: '-5px'和textAlign: 'center',让每个字符的中心对齐圆弧,避免偏移错位。
  • 添加Resize监听:补充窗口resize事件监听,确保容器尺寸变化时文字能重新计算排列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 09:20:43