iT邦幫忙

2024 iThome 鐵人賽

DAY 2
0

Day02 要做的是虛擬時鐘,就讓我們直接開始ㄅ

時間資料

  • 先用 useState 建立目前的時間
const [time, setTime] = useState(new Date());

更新時間

  • 接著使用 useEffectsetInterval 來讓資料可以跟著每秒重設

    • 記得也要清理掉
  useEffect(() => {
    const interval = setInterval(() => {
      setTime(new Date());
    }, 1000);

    return () => clearInterval(interval);
  }, []);
  • 把時、分、秒傳進時鐘面板的元件裡面

    • 使用 getSeconds()getMinutes()getHours() 方法
      <ClockPanel
        hours={time.getHours()}
        minutes={time.getMinutes()}
        seconds={time.getSeconds()}
      />

主要元件

export default function Clock() {
  const [time, setTime] = useState(new Date());

  useEffect(() => {
    const interval = setInterval(() => {
      setTime(new Date());
    }, 1000);

    return () => clearInterval(interval);
  }, []);

  return (
    <div className="my-24 mx-auto w-60 h-60 relative shadow-[0_0_0_4px_rgba(0,0,0,0.1),_inset_0_0_0_3px_#EFEFEF,_inset_0_0_10px_black,_0_0_10px_rgba(0,0,0,0.2)] bg-blue-700 border border-white rounded-full">
      <ClockPanel
        hours={time.getHours()}
        minutes={time.getMinutes()}
        seconds={time.getSeconds()}
      />
    </div>
  );
}

繪製時鐘面板

  • 這邊利用 CSS transform: rotate() 來根據時間做不同角度的旋轉

    • (由於 TailwindCSS 不支援動態更新,所以寫在 style)
          style={{
            transform: `rotate(${(hours / 12) * 360 + 270}deg)`,
          }}
  • 再使用 CSS 的 transform-origin 來更改定位

    • 這邊 TailwindCSS 可以寫 origin-left

    • (跟原版不同的是我定位改為左方)

className={`w-1/3 h-2 bg-black absolute top-1/2 left-1/2 origin-left transition-all duration-75 linear`}

https://tailwindcss.com/docs/transform-origin

時鐘元件

type ClockPanelPropType = {
  hours: number;
  minutes: number;
  seconds: number;
};

function ClockPanel(props: ClockPanelPropType) {
  const { hours, minutes, seconds } = props;

  return (
    <>
      <div className="relative w-full h-full -translate-y-[3px]">
        <div
          style={{
            transform: `rotate(${(hours / 12) * 360 + 270}deg)`,
          }}
          className={`w-1/3 h-2 bg-black absolute top-1/2 left-1/2 origin-left transition-all duration-75 linear`}
        />
        <div
          style={{
            transform: `rotate(${(minutes / 60) * 360 + 270}deg)`,
          }}
          className={`w-2/5 h-2 bg-black absolute top-1/2 left-1/2 origin-left transition-all duration-75 linear`}
        />
        <div
          style={{
            transform: `rotate(${(seconds / 60) * 360 + 270}deg)`,
          }}
          className={`w-1/2 h-2 bg-black absolute top-1/2 left-1/2 origin-left transition-all duration-[50ms] linear`}
        />
      </div>
    </>
  );
}

DEMO

https://codesandbox.io/p/devbox/4pwdd6

總結

  • setInterval 來設置定時器

  • CSS transform-origin 可以修改定位


上一篇
[Day01]_Drum-Kit
下一篇
[Day03]_CSS-Variables
系列文
React30——用 React 探索 JavaScript30 的魅力10
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言