123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- import {useEffect, useState, useRef} from "react";
- import React from 'react';
- import './App.css';
- import ClockFace from './pics/ClockFace.png'
- import ClockSec from './pics/ClockFace_S.png'
- import ClockMin from './pics/ClockFace_M.png'
- import ClockHour from './pics/ClockFace_H.png'
- const Spoiler = ({header="+", open=true, children}) => {
- const [open2, setOpen] = useState(open);
- return(
- <>
- <div onClick={()=> setOpen(open2===true?false:true)}>
- {header}
- {open2 && children}
- </div>
- </>
- )
- }
- const RangeInput = ({min=0, max=0}) => {
- //const [min2, setMin] = useState(min);
- //const [max2, setMax] = useState(max);
- const [length, setLength] = useState(0);
- return(
- <>
- <input type='text' style={{backgroundColor: (length<min || length>max)?'red':'green'}}
- onChange={e=>setLength(+e.target.value.length)} />
- </>
- )
- }
- const PasswordConfirm = ({min=0}) => {
- const [val, setVal] = useState('');
- const [secVal, setSecVal] = useState('');
- const [length, setLength] = useState(0);
- return(
- <>
- <div className='BTF'>
- <input type='password' onChange={e=>{setVal(e.target.value); setLength(e.target.value.length)}}
- style={{backgroundColor: length<min?'red':'green'}} className='btf1'/>
- <h3>{val}</h3>
- </div>
- <div className='BTF'>
- <input type='password' style={{backgroundColor: (length<min||secVal.toLowerCase()!==val.toLowerCase())?'red':'green'}}
- onChange={e=>setSecVal(e.target.value)} className='btf1'/>
- <p>{secVal}</p>
- </div>
- </>
- )
- }
- const Timer = ({startSec, onDelete, c}) => {
- const [sec, setSec] = useState(startSec);
- const [stop, setStop] = useState(false);
- const [add, setAdd] =useState(0);
- const [min,setMin] = useState(0);
- const [hour, setHour] = useState(0);
- const [err, setErr] = useState('');
- const [count, setCount] = useState(c);
- useEffect(() => {
- if(!stop) {
- if(sec === 0) return;
- const interval = setInterval(() => {
- setSec(sec => sec - 1)
- }, 1000)
- return () => {
- clearInterval(interval)
- }
- }
- }, [stop, sec, add])
- return (
- <div className='t'>
- <hr className='h' />
- <p>{count}</p>
- <p>{new Date(new Date().setHours(hour, min, sec)).toLocaleString().split (", ")[1]}</p>
- <input onChange={e=>setAdd(+e.target.value)} placeholder='add' />
- <button onClick={()=>setSec(sec+add)}>Add</button>
- <button onClick={() => setStop(!stop)}>Stop</button>
- <button onClick={onDelete}>x</button>
- {err}
- </div>
- )
- }
- //доделать: как сделать чтобы count совподал с текущей позицией
- const TimerControl = ({hours, minutes, seconds}) => {
- const [timers, setTimers] = useState([]);
- const [count, setCount] = useState(0);
- let [h, setH] = useState(hours);
- let [m, setM] = useState(minutes);
- let [s, setS] = useState(seconds);
- let item=0;
- let res = (h * 3600) + (m * 60) + +s;
- console.log(timers);
- return (
- <>
- <input value={h.toString()} type='number' min='0' max='23' placeholder='hours' onChange={e => setH(+e.target.value)}/>
- <input value={m.toString()} type='number' min='0' max='59' placeholder='minutes' onChange={e => setM(+e.target.value)}/>
- <input value={s.toString()} type='number' min='0' max='59' placeholder='seconds' onChange={e => setS(+e.target.value)}/>
- <button onClick={() =>{setCount(count+1); setTimers([Math.random(), ...timers]);}}>Start</button>
- <p>{timers.map(i => <Timer startSec={res} c={count} key={i} onDelete={()=>{setCount(count-1); setTimers(timers.filter(t=>t!==i));}}/>)}</p>
- </>
- )
- }
- const SecondsTimer = ({seconds}) => <h2>{seconds || 0}</h2>
- const TimerContainer = ({seconds, refresh, render:Tag}) => {
- const [count, setCount] = useState(seconds);
- useEffect(()=>{
- if(count<=0) return;
- let interval = setInterval(()=>{
- setCount(count=>count-1);
- }, refresh)
- return ()=> clearInterval(interval);
- }, [count, refresh])
- return(
- <>
- <Tag seconds={count}/>
- </>
- )
- }
- const Timer2 = ({startSec}) => {
- return (
- <div className='t'>
- <p>00:00:{startSec}</p>
- <input placeholder='not used' />
- <button>Add</button>
- <button>Stop</button>
- </div>
- )
- }
- const TimerContainer2 = ({startSec, refresh, render:Tag}) => {
- const [count, setCount] = useState(startSec);
- useEffect(()=>{
- if(count<=0) return;
- let interval = setInterval(()=>{
- setCount(count=>count-1);
- }, refresh)
- return ()=> clearInterval(interval);
- }, [count, refresh])
- return(
- <>
- <Tag startSec={count>0?(count<10?'0'+count:count):'00'}/>
- </>
- )
- }
- const Watch = ({ seconds = 1000 }) =>
- <div style={{ width: 'fit-content' }}>
- <img src={ClockFace} style={{ width: 'inherit', position: 'absolute' }} alt='img' />
- <img src={ClockSec} style={{
- width: 'inherit', position: 'absolute',
- transform: `rotate(${seconds % 60 * 6}deg)`
- }} alt='img' />
- <img src={ClockMin} style={{
- width: 'inherit', position: 'absolute',
- transform: `rotate(${(seconds / 60) % 60 * 6}deg)`
- }} alt='img' />
- <img src={ClockHour} style={{
- width: 'inherit', position: 'absolute',
- transform: `rotate(${((seconds) / (60 * 60)) % 24 * 30}deg)`
- }} alt='img' />
- </div>
- const TimerContainer3 = ({ seconds = 0, refresh = 10, render: Tag}) => {
- const [time, setTime] = useState(seconds * 1000)
- let [isPause, setIsPause] = useState(false)
- useEffect(() => {
- setTime(seconds * 1000)
- }, [seconds])
- useEffect(() => {
- let interval = null
- let now = performance.now()
- if (time > 0) {
- interval = setInterval(() => {
- if(!isPause){
- console.log('1:'+`${isPause}`)
- time > 0 ? setTime(time => time - (performance.now() - now)) : clearInterval(interval)
- }else{
- console.log('2:'+`${isPause}`)
- }
- }, refresh)
- }
- return () => clearInterval(interval)
- })
- return (
- <div>
- <button onClick={()=>setIsPause(!isPause)}>Pause / Continue</button>
- <Tag className="clock" seconds={time > 0 ? time / 1000 : 0} />
- </div>
- )
- }
- const Timer_Control_Container = ({h=0, m=0, s=0, render:Tag, refresh=10}) => {
- const [sec, setSec] = useState(s)
- const [min, setMin] = useState(m)
- const [hour, setHour] = useState(h)
- const [work, setWork] = useState(null)
- const [active, setActive] = useState(false)
- return (
- <div>
- <span>
- <input type="number" min="0" max="30" placeholder='hour'
- onChange={(e) => setHour(+e.target.value)}
- />
- <input type="number" min="0" max="59" placeholder='minutes'
- onChange={(e) => setMin(+e.target.value)}
- />
- <input type="number" min="0" max="59" placeholder='seconds'
- onChange={(e) => setSec(+e.target.value)}
- />
- {active===false ? <button disabled={!hour && !min && !sec} onClick={() => { setWork(hour * 60 * 60 + min * 60 + sec); setActive(true) }}>Start</button> :
- <button className='bckgr' onClick={() => { setWork(null); setActive(false) }}>Stop</button>}
- <br />
- </span>
- {work ? <TimerContainer3 seconds={work} render={Tag} refresh={refresh} /> :
- <TimerContainer3 seconds={0} render={Tag} refresh={refresh} />}
- </div>
- )
- }
-
- function App() {
- return (
- <div className="App">
- <h2><hr/>Spoiler</h2>
- <Spoiler header={<h1>Заголовок</h1>} open>
- Контент 1
- <p>
- лорем ипсум траливали и тп.
- </p>
- </Spoiler>
- <Spoiler>
- <h2>Контент 2</h2>
- <p>
- лорем ипсум траливали и тп.
- </p>
- </Spoiler>
- <h2><hr/>RangeInput</h2>
- <RangeInput min={5} max={10} />
- <h2><hr/>PasswordConfirm</h2>
- <PasswordConfirm min={2} />
- <h2><hr/>Timer</h2>
- <Timer startSec={5}/>
- <h2><hr/>TimerControl</h2>
- <TimerControl hours={1} minutes={10} seconds={10}/>
- <h2><hr/>TimerContainer</h2>
- <TimerContainer seconds={200} refresh={100} render={SecondsTimer}/>
- <h2><hr/>LCD</h2>
- <TimerContainer2 startSec={20} refresh={1000} render={Timer2}/>
- <h2><hr/>Watch</h2>
- <Timer_Control_Container render={Watch} />
- </div>
- );
- }
- export default App;
|