From c5eafdaa0211b84afca6970e3355869baea44291 Mon Sep 17 00:00:00 2001 From: "wkylin.w@gmail.com" Date: Thu, 23 Jan 2025 15:38:11 +0800 Subject: [PATCH] feat word rotate --- src/components/stateless/BorderBeam/index.jsx | 41 +++++++++++++++++++ src/components/stateless/WordRotate/index.jsx | 38 +++++++++++++++++ src/pages/home/index.jsx | 15 +++++-- src/pages/home/index.module.less | 8 ++-- tailwind.config.js | 13 +++++- 5 files changed, 107 insertions(+), 8 deletions(-) create mode 100644 src/components/stateless/BorderBeam/index.jsx create mode 100644 src/components/stateless/WordRotate/index.jsx diff --git a/src/components/stateless/BorderBeam/index.jsx b/src/components/stateless/BorderBeam/index.jsx new file mode 100644 index 00000000..45af4977 --- /dev/null +++ b/src/components/stateless/BorderBeam/index.jsx @@ -0,0 +1,41 @@ +import React from 'react' +import clsx from 'clsx' + +const BorderBeam = ({ + className, + size = 200, + duration = 15, + anchor = 90, + borderWidth = 1.5, + colorFrom = '#ffaa40', + colorTo = '#9c40ff', + delay = 0, + ...props +}) => { + return ( +
+ ) +} + +export default BorderBeam diff --git a/src/components/stateless/WordRotate/index.jsx b/src/components/stateless/WordRotate/index.jsx new file mode 100644 index 00000000..09d17f60 --- /dev/null +++ b/src/components/stateless/WordRotate/index.jsx @@ -0,0 +1,38 @@ +import React, { useEffect, useState } from 'react' +import { AnimatePresence, motion, MotionProps } from 'motion/react' + +import clsx from 'clsx' + +const WordRotate = ({ + words, + duration = 2500, + motionProps = { + initial: { opacity: 0, y: -50 }, + animate: { opacity: 1, y: 0 }, + exit: { opacity: 0, y: 50 }, + transition: { duration: 0.25, ease: 'easeOut' }, + }, + className, +}) => { + const [index, setIndex] = useState(0) + + useEffect(() => { + const interval = setInterval(() => { + setIndex((prevIndex) => (prevIndex + 1) % words.length) + }, duration) + + return () => clearInterval(interval) + }, [words, duration]) + + return ( +
+ + + {words[index]} + + +
+ ) +} + +export default WordRotate diff --git a/src/pages/home/index.jsx b/src/pages/home/index.jsx index 33581a4b..93199dd0 100644 --- a/src/pages/home/index.jsx +++ b/src/pages/home/index.jsx @@ -53,6 +53,8 @@ import SparklesCore from '@stateless/Sparkles' import SparklesText from '@stateless/SparklesText' import ColorfulText from '@stateless/ColorfulText' import MemoizedStars from '@stateless/MemoizedStars' +import WordRotate from '@stateless/WordRotate' +import BorderBeam from '@stateless/BorderBeam' import firstImage from '@assets/images/88-300x160.jpg' import secondImage from '@assets/images/2-300x160.jpg' @@ -274,10 +276,9 @@ const Home = () => {
-
I love coding in{' '} - . + .
X岁的你,正处在一个特殊的位置: @@ -506,6 +507,14 @@ const Home = () => {
+
+
+ + Border Beam + + +
+
{ width: 360, height: 200, position: 'relative', - backgroundColor: 'rgba(0, 0,0, 0.9)', + backgroundColor: 'rgba(0, 0,0, 0.2)', borderRadius: 8, }} > diff --git a/src/pages/home/index.module.less b/src/pages/home/index.module.less index 484a0c3f..331d97ce 100644 --- a/src/pages/home/index.module.less +++ b/src/pages/home/index.module.less @@ -454,12 +454,12 @@ justify-content: center; align-items: center; padding: 12px; - border: 3px solid #0000; + border: 3px solid #85858500; border-radius: 12px; background: - linear-gradient(#131219, #131219) padding-box, - linear-gradient(var(--angle), #070707, #687aff) border-box; - animation: 4s rotate linear infinite; + linear-gradient(#515153, #3a374a) padding-box, + linear-gradient(var(--angle), #777676, rgb(81 174 132)) border-box; + animation: 10s rotate linear infinite; } @keyframes rotate { diff --git a/tailwind.config.js b/tailwind.config.js index 1385b6db..90bc7120 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -2,7 +2,18 @@ module.exports = { content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], theme: { - extend: {}, + extend: { + animation: { + 'border-beam': 'border-beam calc(var(--duration)*1s) infinite linear', + }, + keyframes: { + 'border-beam': { + '100%': { + 'offset-distance': '100%', + }, + }, + }, + }, }, plugins: [], }