一个简单的木鱼demo

268 阅读2分钟

打工者的心声与技术分享

打工的人,打工的魂,年年压金线,为他人做衣裳,竹篮打水一场空,甘受压迫为虎作伥。

今天,我将为大家介绍一个使用React结合SSR(服务器端渲染)技术的木鱼demo项目。这个项目不仅展示了React的强大功能,还利用SSR提升了用户体验。下面是该项目的设计思路及实现细节。

初始项目搭建

首先,我们需要使用Vite搭建一个基础的React项目框架:

npx create-vite mu-fish --template react

进入项目目录并安装依赖:

cd mu-fish
npm install

配置React Router

接下来,我们将简单配置React Router,并新增一个木鱼页面:

// route-manager.ts
const manager = new Manager({
  routes: {
    home: {
      url: '/',
    },
    // ... other urls
    fish: {
      url: '/mu-fish',
    },
  },
});

// route.ts
const routes: TRouteObject[] = [
  {
    ErrorBoundary: NotFound,
    Component: AppLayout,
    children: [
      {
        index: true,
        lazy: () => import('@pages/home'),
      },
      // ... other pages
      {
        path: RouteManager.path('fish'),
        Component: MuFish,
      },
    ],
  },
];

构建木鱼页面

在新页面中,我们导入木鱼的图片和音频,并构建基本的页面结构:

import { useState } from 'react';
import MuFishImage from './MuFishImage.png';
import MuFishAudio from './MuFishAudio.mp3';

const FishKnock: React.FC = () => {
  const [count, setCount] = useState<number>(0);
  const muFishPlayer = useRef<HTMLAudioElement>(null);

  const handleClick: React.MouseEventHandler<HTMLButtonElement> = (e) => {
    setCount((prev) => prev + 1);

    if (muFishPlayer.current) {
      muFishPlayer.current.currentTime = 0;
      void muFishPlayer.current.play();
    }

    setIsClicked(true);
    setTimeout(() => setIsClicked(false), 300);

    printText(e);
  };

  const printText = (event: MouseEvent) => {
    console.log(
      '%c [ (mouseX,mouseY) ]-24',
      'font-size:13px; background:pink; color:#bf2c9f;',
      `(${event.clientX},${event.clientY})`
    );

    setSpans([
      ...spans,
      {
        id: Date.now(),
        top: event.clientY,
        left: event.clientX,
      },
    ]);
  };

  return (
    <>
      <div>
        <h2>敲击次数: {count}</h2>
      </div>
      <button
        className={`${styles.imageContainer} ${isClicked ? styles.buttonClicked : ''}`}
        type="button"
        onClick={handleClick}
      >
        <img src={MuFishImage} alt="木鱼" />
      </button>
      <audio id="mu-fish-player" ref={muFishPlayer} src={MuFishAudio} />
      <div>
        {spans.map((span) => (
          <span
            key={span.id}
            className={styles.clickSpan}
            style={{
              top: span.top,
              left: span.left,
            }}
          >
            功德+1!
          </span>
        ))}
      </div>
    </>
  );
};

export default FishKnock;

实现点击动画与动态文本

为了让木鱼在点击时产生视觉反馈,我们为其添加了一个大小变化的动画:

.imageContainer {
  border: none !important;
  background: transparent;
  transition: all 0.3s ease;
}

.buttonClicked {
  animation: clickAnimation 0.3s ease;
}

@keyframes clickAnimation {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(0.95);
  }
  100% {
    transform: scale(1);
  }
}

每次点击木鱼时,还会显示一个“功德+1”的提示:

const [isClicked, setIsClicked] = useState<boolean>(false);
const [spans, setSpans] = useState<SpanType[]>([]);

useEffect(() => {
  const timer = setTimeout(() => {
    setSpans((prevSpans) => prevSpans.slice(1));
  }, 2000);

  return () => clearTimeout(timer);
}, [spans]);
.clickSpan {
  position: absolute;
  background-color: red;
  color: white;
  padding: 2px 4px;
  border-radius: 2px;
  opacity: 1;
  animation: fadeOut 2s forwards;
}

@keyframes fadeOut {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translateY(-20px);
  }
}

结语

以上便是本次分享的木鱼Demo项目,希望通过这个项目能让大家对React结合SSR的应用有更深的理解。愿你在技术探索的路上越走越远,好运常伴!