javascript - 将文本包装在一个
标签,当每个字母在 react.js 中都是单独的(用于动画目的)时
问题描述
我的任务是在我正在构建的投资组合网站上创建一个介绍性文本,gatsby.js
每个字母都有一个单独的动画 - 所以当你将鼠标悬停在一个字母上时,它会反弹并放大,然后离开光标反弹并缩小。
我编写了一个组件,它接收文本,将字符串拆分为一个数组,将每个字母映射到另一个组件中,并使用足够的事件侦听器和类名将每个字符包装在标签中。
这是它的外观:
IntroText.js
export default function IntroText({children}) {
return (
<div>
<p className='intro-text'>
{children.split('').map((e, i) => <IntroLetter key={i} char={e}/>)}
</p>
</div>
)
}
IntroLetter.js
export default function IntroLetter({char}) {
const [ hoverClass, setHoverClass ] = useState('single-letter')
if (char === ' ') {
return <span> </span>
} else {
return (
<span
className={hoverClass}
onMouseOver={() => setHoverClass('single-letter hovered')}
onMouseLeave={() => setHoverClass('single-letter unhovered')}
>
{ char }
</span>
)
}
}
和CSS:
.intro-text {
width: 80%;
.single-letter {
display: inline-block;
transform-origin: 50% 84%;
}
.hovered {
animation-name: stretch;
animation-duration: 0.15s;
animation-timing-function: linear;
animation-fill-mode: forwards
}
.unhovered {
animation-name: stretch-back;
animation-duration: 0.25s;
animation-timing-function: linear;
}
}
如果我.single-letter
作为内联元素离开,则动画将不起作用,但文本呈现良好,因此,尽管每个字符都包含在单独<span>
的 中,但线条会在正确的位置中断。如果我设置.single-letter
为inline-block
元素,则动画效果很好,但空格会崩溃(因此有条件检查 if char === ' '
in SingleLetter.js
)。如果我将空格保留为内联 span 元素,将其余字符保留为 span inline-block
,则空格会正确呈现,动画可以正常工作,但是我的换行符不会保留单词。
我可以将我的字符串分成几个IntroText
组件,每个组件对应一行,但这显然不是响应式站点上的可行解决方案。我应该怎么办?
编辑:我制作了 CodeSandbox 示例:CodeSandbox
解决方案
您可以通过将单词放在一起来完成此操作inline-block
。检查此沙箱以获取工作示例:https ://codesandbox.io/embed/jpw2l4j4py
function IntroLetter({ char }) {
const [hoverClass, setHoverClass] = useState("single-letter");
return (
<span
className={hoverClass}
onMouseOver={() => setHoverClass("single-letter hovered")}
onMouseLeave={() => setHoverClass("single-letter unhovered")}
>
{char}
</span>
);
}
function IntroWord({ word }) {
return (
<span style={{ display: "inline-block" }}>
{word.split("").map((letter, letterIndex) => (
<IntroLetter index={letterIndex} char={letter} />
))}
</span>
);
}
function IntroText({ children }) {
return (
<div>
<p className="intro-text">
{children.split(" ").map((word, wordIndex) => (
<Fragment>
<IntroWord key={wordIndex} word={word} />
<span> </span>
</Fragment>
))}
</p>
</div>
);
}
推荐阅读
- git - 仅显示 git-branch 上与另一个分支相比领先+落后的提前提交
- php - 在 php 代码中替换 html 元素的内容
- javascript - 最小化 if 语句以保持 javascript 中的可读性
- unit-testing - 使用 Spock 检查基数时调用太少 0
- c++ - 动态分配大于 SIZE_T/UINT 的内存空间(即在堆上)
- r - 编写一个函数来总结 dunn.test::dunn.test 的结果
- javascript - 获取`Uncaught TypeError: firebase.database is not a function`
- arrays - 在 Swift 中对不同的结果使用相同的 Json 函数
- oracle11g - Oracle Pivot over 值序列
- php - 从 mysql 值中删除单词