|
@@ -1,6 +1,6 @@
|
|
|
import logo from './logo.svg';
|
|
|
-import './App.css';
|
|
|
-import { useState, useEffect } from "react";
|
|
|
+import './App.scss';
|
|
|
+import { useState, useEffect, useRef } from "react";
|
|
|
|
|
|
const Spoiler = ({ header = "+", open, children }) => {
|
|
|
|
|
@@ -112,7 +112,93 @@ const TimerControl = () => {
|
|
|
<button onClick={() => setOpen(!open)}>{!open ? 'start' : 'stop'}</button>
|
|
|
{open && <Timer ms={ms} />}
|
|
|
</div>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const TimerContainer = ({ seconds, refresh, render: T }) => {
|
|
|
+ const t0 = performance.now()
|
|
|
+ const [time, setTime] = useState(seconds)
|
|
|
+ useEffect(() => {
|
|
|
+ const timerID = setInterval(() => {
|
|
|
+ let t1 = performance.now()
|
|
|
+ if (seconds >= (t1 - t0) / 1000) {
|
|
|
+ setTime(seconds - (t1 - t0) / 1000)
|
|
|
+ } else {
|
|
|
+ setTime(0)
|
|
|
+ clearInterval(timerID)
|
|
|
+ }
|
|
|
+ }, refresh);
|
|
|
+ return () => {
|
|
|
+ setTime(seconds)
|
|
|
+ clearInterval(timerID)
|
|
|
+ }
|
|
|
+ }, [])
|
|
|
+ return (
|
|
|
+ <T seconds={time} />
|
|
|
+ )
|
|
|
+}
|
|
|
+const SecondsTimer = ({ seconds }) => <h2>{seconds.toFixed(1)}</h2>
|
|
|
+
|
|
|
|
|
|
+const TimerLCD = ({ time = 5 }) => {
|
|
|
+ let hours = Math.floor(time / 3600)
|
|
|
+ let minuts = Math.floor(time % 3600 / 60)
|
|
|
+ let seconds = time % 60
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <span>{hours < 10 ? `0${hours}` : hours}</span> : <span>{minuts < 10 ? `0${minuts}` : minuts}</span> : <span>{seconds < 10 ? `0${seconds.toFixed(0)}` : seconds.toFixed(0)} </span>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const TimerControlLCD = ({ ms, render: T }) => {
|
|
|
+ const [open, setOpen] = useState(true)
|
|
|
+ const t0 = performance.now()
|
|
|
+ const [time, setTime] = useState(ms)
|
|
|
+ useEffect(() => {
|
|
|
+ if (open) {
|
|
|
+ const timerID = setInterval(() => {
|
|
|
+ let t1 = performance.now()
|
|
|
+ if (ms >= (t1 - t0) / 1000) {
|
|
|
+ setTime(ms - (t1 - t0) / 1000)
|
|
|
+ } else {
|
|
|
+ setTime(0)
|
|
|
+ clearInterval(timerID)
|
|
|
+ }
|
|
|
+ }, 1000);
|
|
|
+ return () => {
|
|
|
+ setTime(ms)
|
|
|
+ clearInterval(timerID)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }, [open])
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div>
|
|
|
+ <button onClick={() => setOpen(!open)}>{open ? 'start' : 'stop'}</button>
|
|
|
+ {open && <T time={time} />}
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+}
|
|
|
+
|
|
|
+const Watch = ({ time }) => {
|
|
|
+
|
|
|
+ let hours = (time / 3600 * 30)
|
|
|
+ let seconds = (time * 6).toFixed(0)
|
|
|
+ let minuts = (time % 3600 / 60) * 6
|
|
|
+
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <strong>
|
|
|
+ <TimerLCD time={time} />
|
|
|
+ </strong>
|
|
|
+ <div className='Watch'>
|
|
|
+ <img className='clock' src='./ClockFace.png' />
|
|
|
+ <img className='hour' style={{ transform: `rotate(${hours}deg)`}} src='./hour.png' />
|
|
|
+ <img className='minuts' style={{ transform: `rotate(${minuts}deg)`}} src='./minut.png' />
|
|
|
+ <img className='seconds' style={{ transform: `rotate(${seconds}deg)`}} src='./second.png' />
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
)
|
|
|
}
|
|
|
|
|
@@ -136,10 +222,21 @@ function App() {
|
|
|
<hr />
|
|
|
<PasswordConfirm min={2} />
|
|
|
<hr />
|
|
|
+ <strong>Timer :</strong>
|
|
|
<Timer ms={4000} />
|
|
|
<hr />
|
|
|
+ <strong>TimerControl :</strong>
|
|
|
<TimerControl />
|
|
|
<hr />
|
|
|
+ <strong>TimerContainer :</strong>
|
|
|
+ <TimerContainer seconds={1000} refresh={100} render={SecondsTimer} />
|
|
|
+ <hr />
|
|
|
+ <strong>LCD :</strong>
|
|
|
+ <TimerControlLCD ms={5000} render={TimerLCD} />
|
|
|
+ <hr />
|
|
|
+ <strong>Watch :</strong>
|
|
|
+ <TimerControlLCD ms={1560} render={Watch} />
|
|
|
+ {/* <Watch /> */}
|
|
|
</div >
|
|
|
);
|
|
|
}
|