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
相关产品推荐
相关产品推荐

