我试图在React中使用HTML和CSS重新创建这个动画,使用内联样式和TypeScript。我正在创建一个带有样式信息的对象,并在style属性中引用它。下面是代码。它不起作用,我不确定我做错了什么,我怀疑样式没有正确定义和引用?
这是我尝试重写的原始Codepen示例: Apple动画
这是我的代码
import React from 'react';
const styles = {
'@keyframes showTopText': {
'0%': { transform: 'translate3d(0, 100%, 0)' },
'40%, 60%': { transform: 'translate3d(0, 50%, 0)' },
'100%': { transform: 'translate3d(0, 0, 0)' },
},
'@keyframes showBottomText': {
'0%': { transform: 'translate3d(0, -100%, 0)' },
'100%': { transform: 'translate3d(0, 0, 0)' },
},
animatedTitle: {
color: '#222',
fontFamily: 'Roboto, Arial, sans-serif',
height: '90vmin',
left: '50%',
top: '50%',
transform: 'translate(-50%, -50%)',
width: '90vmin',
},
'animatedTitle > div': {
height: '50%',
overflow: 'hidden',
position: 'absolute',
width: '100%',
},
'animatedTitle > div div': {
fontSize: '12vmin',
padding: '2vmin 0',
position: 'absolute',
},
'animatedTitle > div div span': {
display: 'block',
},
'animated-title > div.text-top': {
borderBottom: '1vmin solid #000',
top: 0,
},
'animatedTitle > div.text-top div': {
animation: 'showTopText 1s',
animationDelay: '0.5s',
animationFillMode: 'forwards',
bottom: 0,
transform: 'translate(0, 100%)',
},
'animatedTitle > div.text-top div span:first-child': {
color: '#767676',
},
'animatedTitle > div.text-bottom': {
bottom: 0,
},
'animatedTitle > div.text-bottom div': {
animation: 'showBottomText 0.5s',
animationDelay: '1.75s',
animationFillMode: 'forwards',
top: 0,
transform: 'translate(0, -100%)',
},
};
function Design() {
return (
<div style={styles.animatedTitle}>
<div style={styles['animatedTitle > div.text-top div']}>
<div>
<span>mimicking</span>
<span>apple's design</span>
</div>
</div>
<div style={styles['animatedTitle > div.text-bottom']}>
<div>for the win!</div>
</div>
</div>
);
}
export { Design }; Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
您可以尝试使用
styled-components来使您的组件更灵活和兼容。我使用styled-components复制了 codepen 的示例,并使其易于扩展。因此,
TopAnimateBlock和BottomAnimateBlock都有 numOfLine 属性,表示块内有多少行。在BottomAnimateBlock中的第二个属性是 delayTopLine,它应该与TopAnimateBlock中的 numOfLine 数量相同,因为我们需要等待顶部行播放。此外,您可以通过
TextStyle的 color 属性轻松更改文本颜色,并传递颜色值,HEX 颜色或 rgba() / hsla()。TextAnimation.tsx
import styled, { keyframes } from 'styled-components'; const showTopText = keyframes` 0% { transform: translate3d(0, 100% , 0); } 40%, 60% { transform: translate3d(0, 50%, 0); } 100% { transform: translate3d(0, 0, 0); } `; const showBottomText = keyframes` 0% { transform: translate3d(0, -100%, 0); } 100% { transform: translate3d(0, 0, 0); } `; const Section = styled.section` width: calc(100% + 10vmin); display: flex; flex-flow: column; padding: 2vmin 0; overflow: hidden; &:last-child { border-top: 1vmin solid white; } `; const Block = styled.div<{ numOfLine: number }>` position: relative; `; const TopAnimateBlock = styled(Block)` animation: ${showTopText} calc(0.5s * ${props => props.numOfLine}) forwards; animation-delay: 0.5s; transform: translateY(calc(100% * ${props => props.numOfLine})); `; const BottomAnimateBlock = styled(Block)<{ delayTopLine: number }>` animation: ${showBottomText} calc(0.5s * ${props => props.numOfLine}) forwards; animation-delay: calc(0.7s * ${props => props.delayTopLine}); transform: translateY(calc(-100% * ${props => props.numOfLine})); `; const TextStyle = styled.p<{ color: string }>` font-family: Roboto, Arial, sans-serif; font-size: 12vmin; color: ${props => props.color}; `; export const TextAnimation = () => { return ( <> <Section> <TopAnimateBlock numOfLine={2}> <TextStyle color="grey">mimicking</TextStyle> <TextStyle color="white">apple's design</TextStyle> </TopAnimateBlock> </Section> <Section> <BottomAnimateBlock numOfLine={1} delayTopLine={2}> <TextStyle color="white">for the win!</TextStyle> </BottomAnimateBlock> </Section> </> ); };如果我们想要动画化3行而不是2行,只需添加/更改:
TextStyle组件TopAnimateBlock中将 numOfLine 从2更改为3,在BottomAnimateBlock中将 delayTopLine 从2更改为3const showTopText = keyframes` 0% { transform: translate3d(0, 100% , 0); } 25%, 40% { transform: translate3d(0, 66%, 0); } 60%, 75% { transform: translate3d(0, 33%, 0); } 100% { transform: translate3d(0, 0, 0); } `;