Browse Source

HW<react03watchface>

Gennadysht 1 năm trước cách đây
mục cha
commit
b0e6530d5b

+ 67 - 0
react/03/myproject03/src/App_lcd.js

@@ -0,0 +1,67 @@
+import logo from './logo.svg';
+import React, { useState, useEffect } from 'react';
+import './App.scss';
+import { getTimeData, getTotalSeconds } from './utills';
+
+
+const TimerContainer = ({ count, render, refresh = 1000 , running = false}) => {
+    let [state, setState] = useState({ paused: !running, count, ...getTimeData(count) });
+    useEffect(() => {
+        let timer = undefined;
+        if (!state.paused) {
+            if (state.count > 0) {
+                const now = new Date();
+                const nextTime = Math.max(1, 1000 - (now.getTime() % refresh));
+                timer = setInterval(() => setStateInt({ count: state.count - 1 }), nextTime);
+            }
+            else
+                pause();
+        }
+        return () => clearInterval(timer);
+    }, [state]);
+    const setStateInt = newState => setState(state = { ...state, ...newState });
+    const start = () => setStateInt({ paused: false });
+    const pause = () => setStateInt({ paused: true });
+    const reset = () => setStateInt({ count });
+    const stop = () => {
+        pause();
+        reset();
+    }
+
+    let timer = getTimeData(state.count);
+    let Render = render;
+    return (
+        <>
+            <input value={state.hours}
+                onChange={e => setStateInt({ hours: e.target.value, count: getTotalSeconds(e.target.value, state.minutes, state.seconds) })}
+                type="number" />
+            <input value={state.minutes}
+                onChange={e => setStateInt({ minutes: e.target.value, count: getTotalSeconds(state.hours, e.target.value, state.seconds) })}
+                type="number" />
+            <input value={state.seconds}
+                onChange={e => setStateInt({ seconds: e.target.value, count: getTotalSeconds(state.hours, state.minutes, e.target.value) })}
+                type="number" />
+            {/*{time.hours} : {time.minutes} : {time.seconds}*/}
+            {/*React.cloneElement(render, { ...render.props, timer })*/}
+            <Render timer={timer} />
+            <br />
+            <button onClick={() => start()}>Start</button>
+            <button onClick={() => pause()}>Pause</button>
+            <button onClick={() => reset()}>Reset</button>
+            <button onClick={() => stop()}>Stop</button>
+        </>
+    );
+}
+const Timer = (props) => <h2>{props.timer.hours} : {props.timer.minutes} : {props.timer.seconds}</h2>;
+function App() {
+
+    return (
+        <>
+            <div className="App">
+                <TimerContainer count={10} render={Timer} />
+            </div>
+        </>
+    );
+}
+
+export default App;

+ 67 - 0
react/03/myproject03/src/App_timer_container.js

@@ -0,0 +1,67 @@
+import logo from './logo.svg';
+import React, { useState, useEffect } from 'react';
+import './App.scss';
+import { getTimeData, getTotalSeconds } from './utills';
+
+
+const TimerContainer = ({ count, render, refresh = 1000 , running = false}) => {
+    let [state, setState] = useState({ paused: !running, count, ...getTimeData(count) });
+    useEffect(() => {
+        let timer = undefined;
+        if (!state.paused) {
+            if (state.count > 0) {
+                const now = new Date();
+                const nextTime = Math.max(1, 1000 - (now.getTime() % refresh));
+                timer = setInterval(() => setStateInt({ count: state.count - 1 }), nextTime);
+            }
+            else
+                pause();
+        }
+        return () => clearInterval(timer);
+    }, [state]);
+    const setStateInt = newState => setState(state = { ...state, ...newState });
+    const start = () => setStateInt({ paused: false });
+    const pause = () => setStateInt({ paused: true });
+    const reset = () => setStateInt({ count });
+    const stop = () => {
+        pause();
+        reset();
+    }
+
+    let timer = getTimeData(state.count);
+    let Render = render;
+    return (
+        <>
+            <input value={state.hours}
+                onChange={e => setStateInt({ hours: e.target.value, count: getTotalSeconds(e.target.value, state.minutes, state.seconds) })}
+                type="number" />
+            <input value={state.minutes}
+                onChange={e => setStateInt({ minutes: e.target.value, count: getTotalSeconds(state.hours, e.target.value, state.seconds) })}
+                type="number" />
+            <input value={state.seconds}
+                onChange={e => setStateInt({ seconds: e.target.value, count: getTotalSeconds(state.hours, state.minutes, e.target.value) })}
+                type="number" />
+            {/*{time.hours} : {time.minutes} : {time.seconds}*/}
+            {/*React.cloneElement(render, { ...render.props, timer })*/}
+            <Render timer={timer} />
+            <br />
+            <button onClick={() => start()}>Start</button>
+            <button onClick={() => pause()}>Pause</button>
+            <button onClick={() => reset()}>Reset</button>
+            <button onClick={() => stop()}>Stop</button>
+        </>
+    );
+}
+const SecondsTimer = (props) => <h2>{props.timer.totalSeconds}</h2>;
+function App() {
+
+    return (
+        <>
+            <div className="App">
+                <TimerContainer count={10} render={SecondsTimer} />
+            </div>
+        </>
+    );
+}
+
+export default App;

+ 71 - 0
react/03/myproject03/src/App_watch.js

@@ -0,0 +1,71 @@
+import logo from './logo.svg';
+import React, { useState, useEffect } from 'react';
+import './App.scss';
+import { getTimeData, getTotalSeconds } from './utills';
+import './WatchFace';
+import { WatchFace } from './WatchFace';
+
+
+const TimerContainer = ({ count, render, refresh = 1000 , running = false}) => {
+    let [state, setState] = useState({ paused: !running, count, ...getTimeData(count) });
+    useEffect(() => {
+        let timer = undefined;
+        if (!state.paused) {
+            if (state.count > 0) {
+                const now = new Date();
+                const nextTime = Math.max(1, 1000 - (now.getTime() % refresh));
+                timer = setInterval(() => setStateInt({ count: state.count - 1 }), nextTime);
+            }
+            else
+                pause();
+        }
+        return () => clearInterval(timer);
+    }, [state]);
+    const setStateInt = newState => {
+        setState(state = { ...state, ...newState });
+    }
+    const start = () => setStateInt({ paused: false });
+    const pause = () => setStateInt({ paused: true });
+    const reset = () => setStateInt({ count });
+    const stop = () => {
+        pause();
+        reset();
+    }
+
+    let timer = getTimeData(state.count);
+    let Render = render;
+    return (
+        <>
+            <input value={state.hours}
+                onChange={e => setStateInt({ hours: e.target.value, count: getTotalSeconds(e.target.value, state.minutes, state.seconds) })}
+                type="number" />
+            <input value={state.minutes}
+                onChange={e => setStateInt({ minutes: e.target.value, count: getTotalSeconds(state.hours, e.target.value, state.seconds) })}
+                type="number" />
+            <input value={state.seconds}
+                onChange={e => setStateInt({ seconds: e.target.value, count: getTotalSeconds(state.hours, state.minutes, e.target.value) })}
+                type="number" />
+            {/*{time.hours} : {time.minutes} : {time.seconds}*/}
+            {/*React.cloneElement(render, { ...render.props, timer })*/}
+            <Render timer={timer} />
+            <br />
+            <button onClick={() => start()}>Start</button>
+            <button onClick={() => pause()}>Pause</button>
+            <button onClick={() => reset()}>Reset</button>
+            <button onClick={() => stop()}>Stop</button>
+        </>
+    );
+}
+
+function App() {
+
+    return (
+        <>
+            <div className="App">
+                <TimerContainer count={10} render={WatchFace} />
+            </div>
+        </>
+    );
+}
+
+export default App;

+ 23 - 0
react/03/myproject03/src/WatchFace.js

@@ -0,0 +1,23 @@
+import "./WatchFace.scss"
+
+export const WatchFace = ({timer}) => {
+    return (
+        <>
+            <h1>{timer.hours} : {timer.minutes} : {timer.seconds}</h1>;
+            <div
+                className='timer'
+                style={{
+                    "--hours": `${timer.hours}`,
+                    "--minutes": `${timer.minutes}`,
+                    "--seconds": `${timer.seconds}`
+                }}
+            >
+                <span className='timer_hours' />
+                <span className='timer_minutes' />
+                <span className='timer_seconds' />
+            </div>
+
+
+        </>
+    )
+}

+ 73 - 0
react/03/myproject03/src/WatchFace.scss

@@ -0,0 +1,73 @@
+body {
+    font-family: sans-serif;
+  }
+  
+  .timer {
+    aspect-ratio: 1;
+    position: relative;
+    border-radius: 50%;
+    border: 1px solid;
+    max-width: 25rem;
+  }
+  
+  .timer::after {
+    content: "";
+    position: absolute;
+    top: 50%;
+    left: 50%;
+    aspect-ratio: 1;
+    width: 5%;
+    background-color: currentColor;
+    border-radius: 50%;
+    transform: translate(-50%, -50%);
+  }
+  
+  .timer_hours,
+  .timer_minutes,
+  .timer_seconds {
+    position: absolute;
+    top: 0;
+    width: 0;
+    left: 50%;
+    height: 50%;
+    transform-origin: 50% 100%;
+    display: grid;
+    align-items: end;
+    justify-content: center;
+  }
+  
+  .timer_hours {
+    transform: rotate(calc(360deg / 12 * var(--hours)));
+  }
+  
+  .timer_minutes {
+    transform: rotate(calc(360deg / 60 * var(--minutes)));
+  }
+  
+  .timer_seconds {
+    transform: rotate(calc(360deg / 60 * var(--seconds)));
+  }
+  
+  .timer_hours::before,
+  .timer_minutes::before,
+  .timer_seconds::before {
+    content: "";
+    background-color: currentColor;
+  }
+  
+  .timer_hours::before {
+    width: 6px;
+    height: 50%;
+  }
+  
+  .timer_minutes::before {
+    width: 6px;
+    height: 90%;
+  }
+  
+  .timer_seconds::before {
+    background-color: #ff0000;
+    height: 96%;
+    width: 2px;
+  }
+  

+ 1 - 1
react/03/myproject03/src/index.js

@@ -1,7 +1,7 @@
 import React from 'react';
 import ReactDOM from 'react-dom/client';
 import './index.css';
-import App from './App_timer_control';
+import App from './App_watch';
 import reportWebVitals from './reportWebVitals';
 
 const root = ReactDOM.createRoot(document.getElementById('root'));

+ 2 - 2
react/03/myproject03/src/utills.js

@@ -1,6 +1,6 @@
-export const getTotalSeconds = (h, m, s) => h * 3600 + m * 60 + s;
+export const getTotalSeconds = (h, m, s) => +h * 3600 + +m * 60 + +s;
 export const getTimeData = (totalSeconds) => {
-    let currDate = new Date(totalSeconds * 1000).toISOString().slice(11, 19);
+    let currDate = new Date(+totalSeconds * 1000).toISOString().slice(11, 19);
     const timeRgx = /([0-9][0-9]):([0-9][0-9]):([0-9][0-9])/;
     const match = currDate.match(timeRgx);
     return {