视频地址: https://www.bilibili.com/vide...
根底款式
如鼠标指针、背景图片等。
鼠标指针
* { cursor: url('/default.cur'), default;}a,a *,button,button *,.btn,.btn *,.prose .post-image { cursor: url('/pointer.cur'), pointer;}
背景图片切换
@layer components { #background { @apply fixed inset-0 saturate-150 z-[-1]; background: url('/images/bg.jpg') no-repeat center center fixed; background-size: cover; transition: all 0.25s ease-in-out; transform-style: preserve-3d; } #background.dark { @apply brightness-50 saturate-100; transform: rotate(-3deg) scale(1.2); /* scaleX(-1); */ }}
Header
Link 封装
locale-link:
import { Link, type LinkProps, NavLink, type NavLinkProps} from '@remix-run/react';import { useI18n } from 'remix-i18n';export function LocaleLink({ to, children, ...props}: LinkProps & { to: string }) { const i18n = useI18n(); const path = `/${i18n.locale()}${to}`; return ( <Link to={path} {...props}> {children} </Link> );}export function LocaleNavLink({ to, children, ...props}: NavLinkProps & { to: string }) { const i18n = useI18n(); const path = `/${i18n.locale()}${to}`; return ( <NavLink to={path} {...props}> {children} </NavLink> );}
router-link:
import { type NavLinkProps } from '@remix-run/react';import clsx from 'classnames';import { LocaleNavLink } from './locale-link';export function RouteLink({ children, to}: Pick<NavLinkProps, 'children' | 'to'>) { return LocaleNavLink({ to, className: ({ isActive }) => clsx(isActive ? 'glass' : 'btn-ghost', 'btn btn-sm rounded-btn'), children });}
header 组件:
import { useI18n } from 'remix-i18n';import { LocaleLink } from './atom/locale-link';import { RouteLink } from './atom/router-link';import { ToggleLocale } from './atom/toggle-locale';import { ToggleTheme } from './atom/toggle-theme';export function Header() { const i18n = useI18n(); const { t } = i18n; return ( <header className='fixed w-full z-20 opacity-90 hover:opacity-100'> <div className='navbar mb-2 shadow-lg bg-neutral text-neutral-content'> <div className='px-2 mx-2 navbar-start'> <LocaleLink to='/'> <span className='text-lg font-bold'>Willin Wang</span> </LocaleLink> </div> <div className='hidden px-2 mx-2 navbar-center lg:flex'> <div className='flex items-stretch'> <RouteLink to='/'>{t('nav.home')}</RouteLink> <RouteLink to='/posts'>{t('nav.posts')}</RouteLink> <RouteLink to='/projects'>{t('nav.projects')}</RouteLink> <RouteLink to='/playground'>{t('nav.playground')}</RouteLink> <RouteLink to='/about'>{t('nav.about')}</RouteLink> </div> </div> <div className='navbar-end'> <ToggleTheme /> <ToggleLocale /> </div> </div> </header> );}
Footer
// import { useMatches } from '@remix-run/react';// import clsx from 'classnames';import { useI18n } from 'remix-i18n';import { LocaleLink } from './atom/locale-link';import { Github, CSDN, Juejin, SegmentFault, WillinLogo, Zhihu } from './svg';export function Footer() { const { t } = useI18n(); // const matches = useMatches(); return ( <footer className='p-4 sm:p-6 bg-base-200 text-base-content opacity-90'> <div className='md:flex md:justify-between'> <div className='mb-6 md:mb-0'> <LocaleLink to='/'> <WillinLogo size='5em' /> </LocaleLink> </div> <div className='grid grid-cols-2 gap-8 sm:gap-6 sm:grid-cols-3'> {/* <div className={clsx({ hidden: posts.length === 0 })}> <ul> {posts .filter((x) => x.type === 'pages') .map((page) => ( <li key={page.slug}> <LocaleLink to={`/${page.slug}`}>{page.title}</LocaleLink> </li> ))} </ul> </div> */} <div> <ul> <li> <LocaleLink to='/'>{t('nav.home')}</LocaleLink> </li> <li> <LocaleLink to='/posts'>{t('nav.posts')}</LocaleLink> </li> <li> <LocaleLink to='/playground'>{t('nav.playground')}</LocaleLink> </li> </ul> </div> {/* <div> <ul> <li className='mb-4'> <a href='#' target='_blank' className='text-gray-600 hover:underline dark:text-gray-400'> Privacy Policy </a> </li> <li> <a href='#' target='_blank' className='text-gray-600 hover:underline dark:text-gray-400'> Terms & Conditions </a> </li> </ul> </div> */} </div> </div> <hr className='my-6 border-gray-200 sm:mx-auto dark:border-gray-700 lg:my-8' /> <div className='sm:flex sm:items-center sm:justify-between'> <span className='text-sm text-gray-500 sm:text-center dark:text-gray-400'> Willin Wang <small>© 2002 ~ {new Date().getFullYear()}.</small> <small> Made with ❤️ and{' '} <a href='http://remix.run' target='_blank' rel='noopener noreferrer'> Remix </a>{' '} |{' '} <a href='https://beian.miit.gov.cn/' target='_blank' rel='noopener noreferrer'> 苏ICP备17011988号-1 </a> </small> </span> <div className='flex mt-4 space-x-6 sm:justify-center sm:mt-0'> <a href='https://segmentfault.com/u/willin' target='_blank' className='hover:text-secondary' rel='noopener noreferrer' aria-label='SegmentFault'> <SegmentFault /> </a> <a href='https://blog.csdn.net/jslygwx?type=blog' target='_blank' className='hover:text-secondary' rel='noopener noreferrer' aria-label='CSDN'> <CSDN /> </a> <a href='https://www.zhihu.com/people/willin' target='_blank' className='hover:text-secondary' rel='noopener noreferrer' aria-label='知乎'> <Zhihu /> </a> <a href='https://juejin.cn/user/1873223546052391' target='_blank' className='hover:text-secondary' rel='noopener noreferrer' aria-label='掘金'> <Juejin /> </a> <a href='https://github.com/willin' target='_blank' className='hover:text-secondary' aria-label='Github'> <Github /> </a> </div> </div> </footer> );}