简体   繁体   中英

Fade in Text Animation does not appear at all

I want to create a text animation that fades in when the user scrolls down to the desired section. I am trying to recreate this example - https://codepen.io/alvarotrigo/pen/ExvqdNa - in React with inline styling and I dont know why its not working. Can anyone help out and say where my error is?

I suspect I did not correctly declare my styles?

import React from 'react';

const styles = {
    body: {
        padding: '0px',
        margin: '0px',
        height: '100vh',
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'center',
        alignItems: 'center',
    },

    h1: {
        fontFamily: 'Montserrat Medium',
        maxWdth: '40ch',
        textAlign: 'center',
        transform: 'scale(0.94)',
        animation: 'scale 3s forwards cubic-bezier(0.5, 1, 0.89, 1)',
    },
    '@keyframes scale': {
        '100%': {
            transform: 'scale(1)',
        },
    },

    span: {
        display: 'inline-block',
        opacity: 0,
        filter: 'blur(4px)',
    },

    'span:nth-child(1)': {
        animation: 'fade-in 0.8s 0.1s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(2)': {
        animation: 'fade-in 0.8s 0.2s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(3)': {
        animation: 'fade-in 0.8s 0.3s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(4)': {
        animation: 'fade-in 0.8s 0.4s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(5)': {
        animation: 'fade-in 0.8s 0.5s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(6)': {
        animation: 'fade-in 0.8s 0.6s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(7)': {
        animation: 'fade-in 0.8s 0.7s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(8)': {
        animation: 'fade-in 0.8s 0.8s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(9)': {
        animation: 'fade-in 0.8s 0.9s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(10)': {
        animation: 'fade-in 0.8s 1s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(11)': {
        animation: 'fade-in 0.8s 1.1s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(12)': {
        animation: 'fade-in 0.8s 1.2s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(13)': {
        animation: 'fade-in 0.8s 1.3s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(14)': {
        animation: 'fade-in 0.8s 1.4s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(15)': {
        animation: 'fade-in 0.8s 1.5s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(16)': {
        animation: 'fade-in 0.8s 1.6s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    'span:nth-child(17)': {
        animation: 'fade-in 0.8s 1.7s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },
    'span:nth-child(18)': {
        animation: 'fade-in 0.8s 1.8s forwards cubic-bezier(0.11, 0, 0.5, 0)',
    },

    '@keyframes fade-in': {
        '100%': {
            opacity: 1,
            filter: 'blur(0)',
        },
    },
};

function TextAnimation() {
    return (
        <>
            <h1 style={styles.h1}>
                <span style={styles.span}>
                    <span style={styles['span:nth-child(1)']}>There</span>
                    <span style={styles['span:nth-child(2)']}>are</span>
                    <span style={styles['span:nth-child(3)']}>no</span>
                    <span style={styles['span:nth-child(4)']}>limits</span>
                    <span style={styles['span:nth-child(5)']}>to</span>
                    <span style={styles['span:nth-child(6)']}>what</span>
                    <span style={styles['span:nth-child(7)']}>you</span>
                    <span style={styles['span:nth-child(8)']}>can</span>
                    <span style={styles['span:nth-child(9)']}>accomplish,</span>
                    <span style={styles['span:nth-child(10)']}>except</span>
                    <span style={styles['span:nth-child(11)']}>the</span>
                    <span style={styles['span:nth-child(12)']}>limits</span>
                    <span style={styles['span:nth-child(13)']}>you</span>
                    <span style={styles['span:nth-child(14)']}>place</span>
                    <span style={styles['span:nth-child(15)']}>on</span>
                    <span style={styles['span:nth-child(16)']}>your</span>
                    <span style={styles['span:nth-child(17)']}>own</span>
                    <span style={styles['span:nth-child(18)']}>thinking.</span>
                </span>
            </h1>
        </>
    );
}

export { TextAnimation };





i defined your keyframes as following, and removed them from the styles object (since they were never used anyway).

const fadeIn = `
    @-webkit-keyframes fade-in { 
        0% { 
            opacity: 0;
            filter: blur(4px);
        } 

        100% { 
            opacity: 1; 
            filter: blur(0); 
        } 
    } 
    `;
const scale = `
    @-webkit-keyframes scale {
         0% {
            transform: scale(0) 
        } 100% {
            transform: scale(1) 
        } 
    } `;

Now that allows you to solve the issue of not having the keyframes in your document by simply adding the following above the return of the TextAnimation component:

const style = document.createElement("style");
style.innerHTML = `${fadeIn} ${scale}`;
document.getElementsByTagName("head")[0].appendChild(style);

Finally you need to remove the default styling (of opacity and filter ) regarding the spans (since we moved those to the keyframes themselves). span in styles now looks like this:

span: {
    display: "inline-block",
},

Now when rendering TextAnimation , it should work. Complete code:

const styles = {
    body: {
        padding: "0px",
        margin: "0px",
        height: "100vh",
        display: "flex",
        flexDirection: "column",
        justifyContent: "center",
        alignItems: "center",
    },

    h1: {
        fontFamily: "Montserrat Medium",
        maxWdth: "40ch",
        textAlign: "center"
        transform: "scale(0.94)",
        animation: "scale 3s forwards cubic-bezier(0.5, 1, 0.89, 1)",
    },

    span: {
        display: "inline-block",
    },

    "span:nth-child(1)": {
        animation: "fade-in 0.8s 0.1s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(2)": {
        animation: "fade-in 0.8s 0.2s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(3)": {
        animation: "fade-in 0.8s 0.3s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(4)": {
        animation: "fade-in 0.8s 0.4s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(5)": {
        animation: "fade-in 0.8s 0.5s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(6)": {
        animation: "fade-in 0.8s 0.6s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(7)": {
        animation: "fade-in 0.8s 0.7s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(8)": {
        animation: "fade-in 0.8s 0.8s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(9)": {
        animation: "fade-in 0.8s 0.9s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(10)": {
        animation: "fade-in 0.8s 1s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(11)": {
        animation: "fade-in 0.8s 1.1s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(12)": {
        animation: "fade-in 0.8s 1.2s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(13)": {
        animation: "fade-in 0.8s 1.3s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(14)": {
        animation: "fade-in 0.8s 1.4s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(15)": {
        animation: "fade-in 0.8s 1.5s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(16)": {
        animation: "fade-in 0.8s 1.6s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },

    "span:nth-child(17)": {
        animation: "fade-in 0.8s 1.7s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },
    "span:nth-child(18)": {
        animation: "fade-in 0.8s 1.8s forwards cubic-bezier(0.11, 0, 0.5, 0)",
    },
};

const fadeIn = `
    @-webkit-keyframes fade-in { 
        0% { 
            opacity: 0;
            filter: blur(4px); 
        } 

        100% { 
            opacity: 1; 
            filter: blur(0); 
        } 
    } 
    `;
const scale = `
    @-webkit-keyframes scale {
         0% {
            transform: scale(0) 
        } 100% {
            transform: scale(1) 
        } 
    } `;

function TextAnimation() {
    const style = document.createElement("style");
    style.innerHTML = `${fadeIn} ${scale}`;
    document.getElementsByTagName("head")[0].appendChild(style);

    return (
        <>
            <h1 style={styles.h1}>
                <span style={styles.span}>
                    <span style={styles["span:nth-child(1)"]}>There</span>
                    <span style={styles["span:nth-child(2)"]}>are</span>
                    <span style={styles["span:nth-child(3)"]}>no</span>
                    <span style={styles["span:nth-child(4)"]}>limits</span>
                    <span style={styles["span:nth-child(5)"]}>to</span>
                    <span style={styles["span:nth-child(6)"]}>what</span>
                    <span style={styles["span:nth-child(7)"]}>you</span>
                    <span style={styles["span:nth-child(8)"]}>can</span>
                    <span style={styles["span:nth-child(9)"]}>accomplish,</span>
                    <span style={styles["span:nth-child(10)"]}>except</span>
                    <span style={styles["span:nth-child(11)"]}>the</span>
                    <span style={styles["span:nth-child(12)"]}>limits</span>
                    <span style={styles["span:nth-child(13)"]}>you</span>
                    <span style={styles["span:nth-child(14)"]}>place</span>
                    <span style={styles["span:nth-child(15)"]}>on</span>
                    <span style={styles["span:nth-child(16)"]}>your</span>
                    <span style={styles["span:nth-child(17)"]}>own</span>
                    <span style={styles["span:nth-child(18)"]}>thinking.</span>
                </span>
            </h1>
        </>
    );
}

I reproduced the codepen example with styled-components and made this more custom, when the sentence length changes you don't need to add or delete an extra pseudo-class each time. And this approach without any innerHTML injection.

TextAnimation.tsx

import styled, { keyframes } from 'styled-components';

const fadeIn = keyframes`
100% {
    opacity: 1;
    filter: blur(0);
  }
`;

const H1Style = styled.h1`
  max-width: 500px;
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  justify-content: center;
`;

const ChunksStyle = styled.span<{ order: number }>`
  display: inline-block;
  color: aliceblue;
  opacity: 0;
  filter: blur(4px);
  animation: ${fadeIn} 0.8s forwards cubic-bezier(0.11, 0, 0.5, 0);
  animation-delay: ${props => `${props.order}s`};
`;

const TextAnimation = ({ text }: { text: string }) => {
  const words = text.split(' ');

  const chunks = words.map((word, index) => {
    // index + 1 - our index start from 1
    // 10 - number of decimal seconds in one second
    const count = (index + 1) / 10;

    return (
      <ChunksStyle key={index} order={count}>
        {word}
      </ChunksStyle>
    );
  });

  return <H1Style>{chunks}</H1Style>;
};

App.tsx

import "./styles.css";
import { TextAnimation } from './TextAnimation';

export default function App() {
  const text =
    'There are no limits to what you can accomplish, except the limits you place on your own thinking.';
  return (
    <>
      <TextAnimation text={text} />
    </>
  );
}

编辑令人眼花缭乱的代码

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM