Skip to content

Commit

Permalink
feat: enhance hero button
Browse files Browse the repository at this point in the history
  • Loading branch information
kuizuo committed Jun 14, 2024
1 parent 937c4b8 commit ee140c5
Show file tree
Hide file tree
Showing 4 changed files with 132 additions and 46 deletions.
14 changes: 7 additions & 7 deletions src/components/landing/Hero/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Translate from '@docusaurus/Translate'
import HeroSvg from './img/hero.svg'

import SocialLinks from '@site/src/components/SocialLinks'
import { MovingButton } from '../../magicui/moving-border'
import styles from './styles.module.css'

const variants: Variants = {
Expand Down Expand Up @@ -70,15 +71,14 @@ export default function Hero() {
</motion.div>

<motion.div className="mt-4 flex gap-2" custom={4} initial="hidden" animate="visible" variants={variants}>
<div className="relative w-max overflow-hidden rounded-2xl p-0.5">
<div className={styles.gradient} />
<a
className="relative z-10 flex items-center rounded-2xl border border-[rgba(41,41,41,.1)] border-solid bg-background px-6 py-3 text-center font-semibold hover:no-underline"
href={'./about'}
>
<MovingButton
borderRadius="1.25rem"
className="relative z-10 flex items-center rounded-2xl border border-neutral-200 border-solid bg-background px-5 py-3 text-center font-semibold text-base dark:border-neutral-800"
>
<a href={'/about'} className="font-semibold">
<Translate id="hompage.hero.introduce">自我介绍</Translate>
</a>
</div>
</MovingButton>
</motion.div>
</div>
<motion.div className={styles.background}>
Expand Down
39 changes: 0 additions & 39 deletions src/components/landing/Hero/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -61,45 +61,6 @@
@apply absolute inline-flex justify-center items-center bg-transparent text-transparent backdrop-blur-[2px] shadow-[inset_1px_1px_5px_rgb(255,255,255,0.3),0_0_5px_rgb(0,0,0,0.2)] rounded-lg p-2 w-14 h-14;
}

@keyframes surround {
0% {
transform: translateY(-25%) translateX(40%) rotate(0deg);
}

30% {
transform: translateY(0) translateX(0) rotate(90deg) scaleX(0.7);
}

50% {
transform: translateY(-25%) translateX(-40%) rotate(180deg);
}

70% {
transform: translateY(0) translateX(0) rotate(270deg) scaleX(0.7);
}

100% {
transform: translateY(-25%) translateX(40%) rotate(1turn);
}
}

.gradient {
@apply absolute inset-0 h-full rounded-2xl bg-[conic-gradient(transparent_50deg,var(--ifm-color-primary-light)_80deg,transparent_100deg)] blur-lg;
animation: surround -0.64s linear 4s infinite;
transform-origin: center;
will-change: transform;
}

html[data-theme='dark'] {
.gradient {
background: conic-gradient(
transparent 50deg,
var(--ifm-color-primary-darker) 80deg,
transparent 100deg
);
}
}

@media (max-width: 1000px) {
.hero {
@apply grid-cols-1 grid-rows-[max-content_minmax(0,max-content)] items-start h-auto;
Expand Down
113 changes: 113 additions & 0 deletions src/components/magicui/moving-border.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use client'
import { cn } from '@site/src/lib/utils'
import { motion, useAnimationFrame, useMotionTemplate, useMotionValue, useTransform } from 'framer-motion'
import React, { useRef } from 'react'

export function MovingButton({
borderRadius = '1.75rem',
children,
as: Component = 'div',
containerClassName,
borderClassName,
duration,
className,
...otherProps
}: {
borderRadius?: string
children: React.ReactNode
as?: any
containerClassName?: string
borderClassName?: string
duration?: number
className?: string
[key: string]: any
}) {
return (
<Component
className={cn('relative h-14 w-auto min-w-32 overflow-hidden bg-transparent p-[2px] text-xl', containerClassName)}
style={{
borderRadius: borderRadius,
}}
{...otherProps}
>
<div className="absolute inset-0" style={{ borderRadius: `calc(${borderRadius} * 0.96)` }}>
<MovingBorder duration={duration} rx="30%" ry="30%">
<div
className={cn(
'size-20 bg-[radial-gradient(var(--ifm-color-primary)_40%,transparent_60%)] opacity-[0.8]',
borderClassName,
)}
/>
</MovingBorder>
</div>

<div
className={cn(
'relative flex h-full w-full items-center justify-center bg-slate-900/[0.8] text-sm antialiased backdrop-blur-xl',
className,
)}
style={{
borderRadius: `calc(${borderRadius} * 0.96)`,
}}
>
{children}
</div>
</Component>
)
}

export const MovingBorder = ({
children,
duration = 5000,
rx,
ry,
...otherProps
}: {
children: React.ReactNode
duration?: number
rx?: string
ry?: string
[key: string]: any
}) => {
const pathRef = useRef<any>()
const progress = useMotionValue<number>(0)

useAnimationFrame(time => {
const length = pathRef.current?.getTotalLength()
if (length) {
const pxPerMillisecond = length / duration
progress.set((time * pxPerMillisecond) % length)
}
})

const x = useTransform(progress, val => pathRef.current?.getPointAtLength(val).x)
const y = useTransform(progress, val => pathRef.current?.getPointAtLength(val).y)

const transform = useMotionTemplate`translateX(${x}px) translateY(${y}px) translateX(-50%) translateY(-50%)`

return (
<>
<svg
xmlns="http://www.w3.org/2000/svg"
preserveAspectRatio="none"
className="absolute h-full w-full"
width="100%"
height="100%"
{...otherProps}
>
<rect fill="none" width="100%" height="100%" rx={rx} ry={ry} ref={pathRef} />
</svg>
<motion.div
style={{
position: 'absolute',
top: 0,
left: 0,
display: 'inline-block',
transform,
}}
>
{children}
</motion.div>
</>
)
}
12 changes: 12 additions & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,19 @@ const twConfig: Config = {
},
)
}),
addVariablesForColors,
],
}

export default twConfig

function addVariablesForColors({ addBase, theme }: any) {
const allColors = flattenColorPalette(theme('colors'))
const newVars = Object.fromEntries(
Object.entries(allColors).map(([key, val]) => [`--${key}`, val]),
)

addBase({
':root': newVars,
})
}

0 comments on commit ee140c5

Please sign in to comment.