🐈

【React(Typescript)】マウスの動きに合わせて回転する風車コンポーネント

2023/08/05に公開

作るもの

見本.gif

実装

  • プロジェクトの雛形作成
terminal
npx create-react-app rotating-windmill --template typescript
  • srcディレクトリ配下に、以下のファイルを作成する。
    ・RotatingWindmill.tsx
    ・RotatingWindmill.css
RotatingWindmill.tsx
import React, { useState, useEffect } from 'react';

const RotatingWindmill: React.FC = () => {
  const [rotationAngle, setRotationAngle] = useState(0);

  const handleMouseMove = (event: MouseEvent) => {
    // カーソルの位置に基づいて回転角度を計算
    const { clientX, clientY } = event;
    const centerX = window.innerWidth / 2;
    const centerY = window.innerHeight / 2;
    const radians = Math.atan2(clientY - centerY, clientX - centerX);
    const degrees = (radians * 180) / Math.PI;
    setRotationAngle(degrees);
  };

  useEffect(() => {
    // マウント時にイベントリスナーを追加
    window.addEventListener('mousemove', handleMouseMove);

    // アンマウント時にイベントリスナーを削除
    return () => {
      window.removeEventListener('mousemove', handleMouseMove);
    };
  }, []);

  return (
    <div className="windmill">
      <div className="blades" style={{ transform: `rotate(${rotationAngle}deg)` }}>
        <div className="blade" />
        <div className="blade" />
        <div className="blade" />
      </div>
    </div>
  );
};

export default RotatingWindmill;

RotatingWindmill.css
.windmill {
  position: relative;
  width: 200px;
  height: 200px;
  background-color: #f0f0f0;
  border-radius: 50%;
  overflow: hidden;
}

.blades {
  position: absolute;
  width: 100%;
  height: 100%;
}

.blade {
  position: absolute;
  top: 0;
  left: 50%;
  width: 10px;
  height: 100px;
  background-color: #333;
  transform-origin: 50% 100%;
}

.blade:nth-child(1) {
  transform: rotate(0deg);
}

.blade:nth-child(2) {
  transform: rotate(120deg);
}

.blade:nth-child(3) {
  transform: rotate(240deg);
}

  • App.tsxを以下のように書き換える。
App.tsx
import React from 'react';
import RotatingWindmill from './RotatingWindmill';
import './App.css';
import './RotatingWindmill.css';

const App: React.FC = () => {
  return (
    <div className="app">
      <RotatingWindmill />
    </div>
  );
};

export default App;
    
  • 動作確認
terminal
npm start

http://localhost:3000にアクセスすると、冒頭の風車のコンポーネントが表示される。

Discussion