Bagaimana untuk membuat tangan kedua pada jam hanya bergerak ke hadapan?
P粉952365143
P粉952365143 2023-09-06 15:56:38
0
1
605

Saya membina jam analog menggunakan React tetapi saya mempunyai masalah dengan tangan kedua. Jarum kedua bermula mengikut arah jam, tetapi apabila ia mencapai tanda 59 saat, ia bergerak melawan arah jam sehingga mencapai tanda 1 saat. Selepas itu ia bergerak mengikut arah jam semula. Bagaimana untuk menjadikannya bergerak secara berterusan mengikut arah jam?

import React, { useEffect, useState } from 'react';
import './AnalogClock.css';

const AnalogClock = () => {
  const [time, setTime] = useState(new Date());

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

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

  const getRotation = (unit, max) => {
    const value = time[`get${unit}`]();
    let rotation = (value * 360) / max;

    if (unit === 'Seconds') {
      const seconds = value + time.getMilliseconds() / 1000;
      rotation = (seconds * 6) % 360;

      if (rotation < 0) {
        rotation += 360;
      }
    }

    return {
      transform: `translate(-50%, -100%) rotate(${rotation}deg)`,
    };
  };

  const renderNumbers = () => {
    const numbers = [];

    for (let i = 1; i <= 12; i++) {
      const angle = (i * 30) * (Math.PI / 180);
      const numberStyle = {
        left: `calc(50% + ${Math.sin(angle) * 140}px)`,
        top: `calc(50% - ${Math.cos(angle) * 140}px)`,
      };
      numbers.push(
        <div key={i} className="number" style={numberStyle}>
          {i}
        </div>
      );
    }

    return numbers;
  };

  return (
    <div className="clock">
      {renderNumbers()}
      <div className="hour-hand" style={getRotation('Hours', 12)}></div>
      <div className="minute-hand" style={getRotation('Minutes', 60)}></div>
      <div
        className="second-hand"
        style={
          time.getSeconds() === 59
            ? { ...getRotation('Seconds', 60), transition: 'none' }
            : getRotation('Seconds', 60)
        }
      ></div>
      <div className="center-circle"></div>
    </div>
  );
};

export default AnalogClock;

Tidak pasti sama ada css membantu, tetapi ini dia.

.clock {
    position: relative;
    width: 300px;
    height: 300px;
    border-radius: 50%;
    background-color: #e0e0e0;
    box-shadow: 20px 20px 40px rgba(0, 0, 0, 0.2), -20px -20px 40px rgba(255, 255, 255, 0.7);
    padding: 20px;
  }
  
  .hour-hand,
  .minute-hand,
  .second-hand {
    position: absolute;
    background-color: #333;
    transform-origin: bottom center;
    transition: transform 0.5s ease-in-out;
    box-shadow: 4px 4px 8px rgba(0, 0, 0, 0.2), -4px -4px 8px rgba(255, 255, 255, 0.7);
  }
  
  .hour-hand {
    width: 8px;
    height: 90px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -100%) translateX(-1px);
    border-radius: 8px 8px 0 0;
  }
  
  .minute-hand {
    width: 6px;
    height: 120px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -100%) translateX(-1px);
    border-radius: 6px 6px 0 0;
  }
  
  .second-hand {
    width: 4px;
    height: 130px;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -100%) translateX(-1px);
    border-radius: 4px 4px 0 0;
    background-color: #ff0000;
  }
  
  .center-circle {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 16px;
    height: 16px;
    background-color: #333;
    border-radius: 50%;
    transform: translate(-50%, -50%);
    box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.2), -2px -2px 4px rgba(255, 255, 255, 0.7);
  }
  .number {
    position: absolute;
    font-size: 29px;
    font-weight: bold;
    color: #333;
    transform: translate(-50%, -50%);
  }

P粉952365143
P粉952365143

membalas semua(1)
P粉221046425

Apabila anda cuba menyuntik js dalam css untuk mencapai matlamat anda, saya syorkan anda menggunakan komponen gaya untuk mendapatkan beberapa faedah, bawa ia ke peringkat seterusnya dan gunakan pembolehubah js dalam css

Keterbatasan utama kod ialah anda tidak boleh menentukan bahawa animasi akan diteruskan selama-lamanya, supaya ia dimulakan semula apabila 360 darjah dicapai

Ini boleh dicapai melalui bingkai kunci css dan animasi, tetapi tanpa menggunakan komponen bergaya adalah sukar untuk menghantar beberapa parameter yang diperlukan kepada bingkai utama dan animasi, seperti darjah awal dan saat untuk melengkapkan gelung

Ini lebih kurang cara menggayakan komponen

import React, { useEffect, useState } from 'react';
import styled, { keyframes } from 'styled-components';
import './styles.css';

const rotate = (degree) => keyframes`
  from {
    transform: translate(-50%, -100%) rotate(${degree}deg);
  }
  to {
    transform: translate(-50%, -100%) rotate(${degree+360}deg);
  }
`

const ClockStick = styled.div`
  animation: ${(props) => rotate(props.degree)} ${(props) => props.seconds}s linear;
`

const App = () => {
  const [degrees, setDegrees] = useState({});

  useEffect(() => {
    setDegrees({
      hour: getRotation('Hours', 12),
      minute: getRotation('Minutes', 60),
      second: getRotation('Seconds', 60)
    })
  }, []);

  const getRotation = (unit, max) => {
    const time = new Date();
    const value = time[`get${unit}`]();
    const rotation = (value * 360) / max;
    return rotation;
  };

  const renderNumbers = () => {
    const numbers = [];

    for (let i = 1; i <= 12; i++) {
      const angle = (i * 30) * (Math.PI / 180);
      const numberStyle = {
        left: `calc(50% + ${Math.sin(angle) * 140}px)`,
        top: `calc(50% - ${Math.cos(angle) * 140}px)`,
      };
      numbers.push(
        <div key={i} className="number" style={numberStyle}>
          {i}
        </div>
      );
    }

    return numbers;
  };

  return (
    <div className="clock">
      {renderNumbers()}
      <ClockStick className="hour-hand" seconds={216000} degree={degrees.hour}></ClockStick>
      <ClockStick className="minute-hand" seconds={3600} degree={degrees.minute}></ClockStick>
      <ClockStick
        className="second-hand"
        seconds={60}
        degree={degrees.second}
      ></ClockStick>
      <div className="center-circle"></div>
    </div>
  );
};

export default App;

Saya mengeluarkan beberapa logik yang tidak perlu dan saya akan menerangkan beberapa perkara yang saya tambahkan

  • Kerangka kunci adalah penting untuk mencapai ini kerana ia akan menentukan cara animasi berputar (dari putaran awal kepada putaran awal + 360) dan juga boleh digunakan dengan sifat animasi, yang boleh membantu dengan ClockStick
  • ClockStick ialah komponen gaya yang akan menerima darjah awal dan bilangan saat yang diperlukan untuk animasi melengkapkan gelung
  • Saya hanya mengisytiharkan keadaan yang darjah awalnya sepadan dengan masa tertentu apabila pengguna menjalankan aplikasi
  • Kemudian saya melepasi bilangan saat yang diperlukan setiap batang (ClockStick) untuk melengkapkan gelung (216000 => selama berjam-jam, 3600 => untuk minit, 60 => untuk saat)

Inilah hasilnya

https://codesandbox.io/s/dawn-rgb-qn58t6

Beberapa pautan yang berkaitan dengan jawapan

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan