Next.js Discord

Discord Forum

framer motion split text animation

Unanswered
Manchester Terrier posted this in #help-forum
Open in Discord
Manchester TerrierOP
I try to animate a split text with framer motion on next.js on the animated text is a next-intl i make a simple animation for testing but it doesn't work

"use client";

import { ReactNode } from "react";
import { useTranslations } from "next-intl";
import { motion } from "framer-motion";

export function splitText(text: string): ReactNode[] {
  return text.split("").map((char, index) => (
    <motion.span
      key={index}
      className="letter"
      initial={{ scale: 1 }}
      animate={{ scale: 2 }}
      transition={{ duration: 0.5, delay: index * 0.05 }}
    >
      {char}
    </motion.span>
  ));
}

const Home: React.FC = () => {
  const t = useTranslations("HomePage");

  const images = [
    "/festival-agicole.jpg",
    "/festival-national.jpg",
    "/festival-printemps.jpeg",
    "/marathon.jpg",
    "/mariage.jpg",
    "/semi-marathon-2.jpg",
    "/semi-marathon.jpg",
  ];

  return (
    <div className="container flex-1 flex justify-center items-center">
      <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[400px] h-[300px]">
        {images.map((url, index) => (
          <div
            key={index}
            className={`block b-${index + 1}`}
            style={{
              background: `url(${url}) 50% 50% no-repeat`,
              backgroundSize: "cover",
            }}
          ></div>
        ))}
      </div>

      <div className="overlay absolute w-full h-[50vh] bottom-[-10rem]"></div>

      <h1
        id="title"
        className="title text-[10em] font-bold font-mono mt-[20rem] overflow-hidden"
      >
        {splitText(t("title"))}
      </h1>
    </div>
  );
};

export default Home;

2 Replies

Manchester TerrierOP
i fix it with using another way for animate split text
if you intresting here is te code
"use client";

import { useTranslations } from "next-intl";
import { motion } from "framer-motion";

const Home: React.FC = () => {
  const t = useTranslations("HomePage");

  const images = [
    "/festival-agicole.jpg",
    "/festival-national.jpg",
    "/festival-printemps.jpeg",
    "/marathon.jpg",
    "/mariage.jpg",
    "/semi-marathon-2.jpg",
    "/semi-marathon.jpg",
  ];

  const title = t("title");

  const containerVariants = {
    hidden: { opacity: 1 },
    visible: {
      opacity: 1,
      transition: {
        staggerChildren: 0.1,
      },
    },
  };

  const letterVariants = {
    hidden: { y: "100%" },
    visible: {
      y: 0,
      transition: {
        type: "spring",
        damping: 12,
        stiffness: 100,
      },
    },
  };

  return (
    <div className="container flex-1 flex justify-center items-center relative">
      <div className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-[400px] h-[300px]">
        {images.map((url, index) => (
          <div
            key={index}
            className={`block b-${index + 1}`}
            style={{
              background: `url(${url}) 50% 50% no-repeat`,
              backgroundSize: "cover",
            }}
          ></div>
        ))}
      </div>

      <div className="overlay absolute w-full h-[50vh] bottom-[-10rem]"></div>

      <motion.h1
        id="title"
        className="title text-[10em] font-bold font-mono mt-[20rem] overflow-hidden flex"
        variants={containerVariants}
        initial="hidden"
        animate="visible"
      >
        {title.split("").map((char, index) => (
          <motion.span
            key={index}
            className="inline-block"
            variants={letterVariants}
          >
            {char}
          </motion.span>
        ))}
      </motion.h1>
    </div>
  );
};

export default Home;