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: [],
}