我有一个具有以下结构的 Next js 项目:
.
├── media
│ └── img.jpg
├── package.json
├── package-lock.json
├── postcss.config.js
├── src
│ ├── components
│ │ └── AnimatedCharacters.js
│ ├── pages
│ │ ├── _app.js
│ │ ├── index.js
│ │ └── index_.js
│ └── styles
│ └── global.css
└── tailwind.config.js
文件内容如下:
包.json
{
"private": true,
"scripts": {
"build": "next build",
"dev": "next dev",
"start": "next start"
},
"dependencies": {
"eslint": "^8.54.0",
"framer-motion": "^10.16.5",
"next": "latest",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"engines": {
"node": ">=18"
},
"devDependencies": {
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.5"
}
}
postcss.config.js
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
tailwind.config.js
/** @type {import('tailwindcss').Config} */
const { fontfamily } = require("tailwindcss/defaultTheme");
module.exports = {
content: ["./src/**/*.{js,ts,jsx,tsx,mdx}"],
theme: {
extend: {
fontFamily: {
poppins: ["var(--font-poppins)"],
},
colors: {
dark: "#1b1b1b",
light: "#f5f5f5",
primary: "#B63E96", // 240,86,199
primaryDark: "#58E6D9", // 80,230,217
white: "#fff",
light_purple: "#8490ff",
light_white: "#f9f9ff",
text_color: "#777777",
},
},
borderWidth: {
1: "1px",
2: "2px",
},
},
plugins: [],
};
src/styles/global.css
@tailwind base;
@tailwind components;
@tailwind utilities;
src/pages/_app.js
import Head from "next/head";
import "../styles/global.css";
import { Poppins } from "next/font/google";
const poppins = Poppins({
subsets: ["latin"],
variable: "--font-poppins",
weight: ["100", "200", "400", "300", "500", "600", "700"],
});
export default function App({ Component, pageProps }) {
return (
<>
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={`${poppins.variable} font-poppins`}>
<Component {...pageProps} />
</main>
</>
);
}
src/pages/index.js
import Head from "next/head";
import Image from "next/image";
import profilepicture from "../../media/img.jpg";
export default function Home() {
return (
<div>
<Head>
<title>Create Next App</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main className="w-full h-auto pl-14 pr-14 flex bg-light_white text-black">
<div className="flex items-center justify-between w-full pt-20 pb-20">
<div className="flex-1 pr-14">
<p className="text-text_color mb-2">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
<p className="text-text_color mb-2">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
<p className="text-text_color mb-2">
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua.
</p>
</div>
<div className="w-80 h-80">
<Image
src={profilepicture}
alt="bird"
className="w-full h-full object-cover rounded-full"
/>
</div>
</div>
</main>
</div>
);
}
运行时
npm run dev
,这按预期工作;文本占据图像放置好后留下的空间。
此外,当我调整窗口大小时,文本也会适应空间。
但是,当我添加
AnimatedCharacters.js
组件时,文本会占用尽可能多的空间,当我调整大小时,文本甚至超过了屏幕的宽度。
这里是代码:
src/components/AnimatedCharacters.js
import React from "react";
import { motion } from "framer-motion";
export default function AnimatedCharacters({
text,
className = "",
reverse = false,
}) {
// splitting text into letters
const letters = Array.from(text);
// Variants for Container
const container = {
hidden: { opacity: 0 },
visible: (i = 1) => ({
opacity: 1,
transition: {
staggerChildren: 0.02,
delayChildren: 0.03 * i,
staggerDirection: reverse ? -1 : 1, // Adjust staggerDirection based on reverse prop
},
}),
};
// Variants for each letter
const child = {
visible: {
opacity: 1,
x: 0,
y: 0,
transition: {
type: "spring",
damping: 12,
stiffness: 100,
},
},
hidden: {
opacity: 0,
x: reverse ? 20 : -20, // Adjust initial x position based on reverse prop
y: 10,
transition: {
type: "spring",
damping: 12,
stiffness: 100,
},
},
};
return (
<motion.div
className={className}
variants={container}
initial="hidden"
animate="visible"
>
{letters.map((letter, index) => (
<motion.span variants={child} key={index}>
{letter === " " ? "\u00A0" : letter}
</motion.span>
))}
</motion.div>
);
}
这就是添加新组件后 index.js 的样子:
import Head from "next/head";
import Image from "next/image";
import profilepicture from "../../media/img.jpg";
import AnimatedCharacters from "../components/AnimatedCharacters";
export default function Home() {
return (
<div>
<Head>
<title>Create Next App</title>
</Head>
<main className="w-full h-auto pl-14 pr-14 flex bg-light_white text-black">
<div className="flex items-center justify-between w-full pt-20 pb-20">
<div className="pr-14">
<AnimatedCharacters
text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua."
className="text-text_color mb-2 overflow-hidden flex"
/>
<AnimatedCharacters
text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua."
reverse
className="text-text_color mb-2 overflow-hidden flex"
/>
<AnimatedCharacters
text="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed
do eiusmod tempor incididunt ut labore et dolore magna aliqua."
className="text-text_color mb-2 overflow-hidden flex"
/>
</div>
<div className="w-80 h-80">
<Image
src={profilepicture}
alt="bird"
className="w-full h-full object-cover rounded-full"
/>
</div>
</div>
</main>
</div>
);
}
这是我刚刚制作的视频记录的链接。
有没有办法让文本适合放置图像后剩下的空间,并将运动效果逐行应用于格式化文本(即从左侧出现第 n 行,从右侧出现第 n+1 行)?
我正在使用 Tailwind CSS 和 framer-motion
如果你设法让文本在 div 内换行
这行有问题
{letter === " " ? "\u00A0" : letter}
因为现在每个字母都在 span 中,所以让我们说单词 text
如果您调整页面大小,它可能不会显示text,它可能是这样的:
特
xt
所以在将文本拆分为字母之前
const letters = Array.from(text);
代码:
const text="separate- every- word- with- any- symbol- also- with- a- white- space"
return (
<div>
{text
.replaceAll("-", `${"\u00A0"}`)
.split(" ")
.map((word, i) => (
<div key={"word" + i}>
{word.split("").map((letter, i) => (
<motion.span key={"letter" + i}>{letter}</motion.span>
))}
</div>
))}
</div>
)
你必须用符号分隔
const text
中的每个单词,这样你就可以用它来替换每个单词之间的空格
text
我用空格替换了符号${"\u00A0"}
" "
来分隔每个单词motion.span