Issue
I am trying to achieve a smooth fade in text animation with CSS in React and Typescript using inline styling.I am creating an object with styling information, and refer to it in the style attribute. The code is down below. It does not work and I have a problem to get it work, can someone help or give some hints please?
Thats a working example what I am trying to achieve: https://codepen.io/kazed972/pen/bQOQGR
My code:
import React from 'react';
const styles = {
body: {
margin: 0,
backgroundColor: '#232323',
color: '#fff',
fontFamily: 'Calibri, sans-serif',
boxSizing: 'border-box',
},
center: {
width: '100%',
height: '100vh',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
},
p: {
width: '70%',
fontSize: '30px',
display: 'block',
textAlign: 'center',
},
char: {
fontSize: '40px',
height: '40px',
animation: 'an 1s ease-out 1 both',
display: 'inline-block',
},
'@keyframes an': {
from: {
opacity: 0,
transform: 'perspective(500px) translate3d(-35px, -40px, -150px) rotate3d(1, -1, 0, 35deg)',
},
to: {
opacity: 1,
transform: 'perspective(500px) translate3d(0, 0, 0)',
},
},
};
function FadeInText() {
var text = document.getElementById('text') as HTMLElement;
var newDom = '';
var animationDelay = 6;
for (let i = 0; i < text.innerText.length; i++) {
newDom += '<span class="char">' + (text.innerText[i] === ' ' ? ' ' : text.innerText[i]) + '</span>';
}
text.innerHTML = newDom;
var length = text.children.length;
for (let i = 0; i < length; i++) {
text.children[i].style['animation-delay'] = animationDelay * i + 'ms';
}
return (
<div style={styles.center}>
<p id="text">
Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate incidunt praesentium, rerum
voluptatem in reiciendis officia harum repudiandae tempore suscipit ex ea, adipisci ab porro.
</p>
</div>
);
}
export { FadeInText };```
Solution
Try the solution with styled-components
to keep your react component consistent.
I refactored the styles a bit. Now, parent element (Section) uses flexbox. (TextStyle) each letter has a default position with a transform that we can remove now from the keyframes and keep only the last frame. Also, (TextStyle) gets two props: delay and color as custom values.
TextAnimation.tsx
import styled, { keyframes } from 'styled-components';
const an = keyframes`
100% { opacity: 1; transform: translate3d(0, 0, 0) }
`;
const Section = styled.section`
width: 70vw;
display: flex;
flex-wrap: wrap;
`;
const TextStyle = styled.span<{ color: string; delay: number }>`
animation: ${an} 1s ease-out forwards;
animation-delay: ${(props) => props.delay}ms;
color: ${(props) => props.color};
font-size: 2em;
line-height: 1.3;
opacity: 0;
transform-style: perspective(500px);
transform: translate3d(-35px, -40px, -150px) rotate3d(1, -1, 0, 35deg);
`;
const DELAY = 6; // ms
export const TextAnimation = ({ text }: { text: string }) => {
// Splitting text on each character and return an array of HTML nodes.
const letters = text.split('').map((letter, index) => {
// Calculate delay for each sign
const delayCounter = DELAY * (index + 1);
return (
<TextStyle key={index} delay={delayCounter} color="white">
{letter === ' ' ? <> </> : letter}
</TextStyle>
);
});
return <Section>{letters}</Section>;
};
App.tsx
import { TextAnimation } from "./TextAnimation";
export default function App() {
const text =
"Lorem ipsum dolor sit amet consectetur adipisicing elit. Cupiditate incidunt praesentium, rerum voluptatem in reiciendis officia harum repudiandae tempore suscipit ex ea, adipisci ab porro.";
return (
<div className="App">
<TextAnimation text={text} />
</div>
);
}
Answered By - Anton
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.