Framer Motion交互式悬停按钮动画:文本截断问题
Framer Motion交互式悬停按钮文本截断问题
需求
- 默认状态下显示
idleText,背景为白色 - 悬停时,通过clipPath动画隐藏白色背景,同时显示
hoverText - 按钮宽度可平滑动画以适配不同文本长度
当前问题
idleText(例如"Instagram")被截断,仅显示部分文本(如"stagra")
代码实现
import { motion } from "motion/react"; import type { ComponentPropsWithRef } from "react"; import { useState } from "react"; import { clsx } from "clsx"; interface InteractiveHoverButtonProps extends ComponentPropsWithRef<"button"> { idleText: string; hoverText: string; } function InteractiveHoverButton({ className, ref, idleText, hoverText, }: InteractiveHoverButtonProps) { const [isHovered, setIsHovered] = useState(true); return ( <motion.button className={clsx( "relative overflow-hidden bg-black border-2 border-gray-800 text-white font-semibold rounded-full cursor-pointer transition-all duration-300 ease-in-out h-[36px]", { "pl-7 pr-4": isHovered, "px-5": !isHovered, }, className )} onMouseEnter={() => setIsHovered(true)} onMouseLeave={() => setIsHovered(false)} transition={{ duration: 0.3, ease: "easeInOut", }} ref={ref} > <motion.div className="relative z-10 flex items-center justify-center h-full overflow-hidden" animate={{ width: isHovered ? "auto" : 0, }} transition={{ duration: 0.3, ease: "easeInOut", }} > <span className="whitespace-nowrap text-sm text-white"> {hoverText} </span> </motion.div> <motion.div className="absolute inset-0 bg-white rounded-full flex items-center justify-center" animate={{ clipPath: isHovered ? "circle(6px at 20px 50%)" : "circle(100% at 50% 50%)", }} transition={{ duration: 0.3, ease: "easeInOut", }} > <motion.span className="text-black font-semibold" animate={{ opacity: isHovered ? 0 : 1, }} transition={{ duration: 0.1, delay: isHovered ? 0 : 0.2, }} > {idleText} </motion.span> </motion.div> </motion.button> ); } export { InteractiveHoverButton };
已尝试的解决方案
- 固定内边距方案:使用统一的px-6内边距,但无法适配不同文本长度
- 布局动画:使用Framer Motion的layout属性,但动画仍有跳变
- 计算宽度:尝试根据文本长度计算宽度,但对不同字体不准确
- 最小宽度方案:尝试min-w-fit、w-auto等多种组合
内容的提问来源于stack exchange,提问作者Bart Krakowski
相关产品推荐
相关产品推荐

