123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- import logo from './logo.svg';
- import './App.scss';
- import { useState, useEffect, useRef } from "react";
- const Spoiler = ({ header = "+", open, children }) => {
- const [openMode, setOpenMode] = useState(open)
- return (
- <div onClick={() => setOpenMode(!openMode)}>
- {header}
- {openMode && children}
- </div>
- )
- }
- const RangeInput = ({ min, max }) => {
- const [state, setState] = useState('')
- const colorBorder = state.length <= min || state.length >= max ? 'red' : ''
- return <input style={{ backgroundColor: colorBorder }}
- onChange={(e) => { setState(e.target.value) }} />
- }
- const PasswordConfirm = ({ min }) => {
- const [checked, setChecked] = useState(false)
- const [stateInputOne, setStateInputOne] = useState('')
- const [stateInputTwo, setStateInputTwo] = useState('')
- const reg = /(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/
- const disabledBtn = stateInputOne === stateInputTwo && reg.test(stateInputOne) ? false : true
- return (
- <div>
- <input style={{ borderColor: stateInputOne.length <= min ? 'red' : 'black' }}
- type={checked ? 'password' : 'text'}
- onChange={(e) => { setStateInputOne(e.target.value) }} />
- <input style={{ borderColor: stateInputTwo.length <= min ? 'red' : 'black' }}
- type={checked ? 'password' : 'text'}
- onChange={(e) => { setStateInputTwo(e.target.value) }} />
- <input type='checkbox'
- checked={checked}
- onChange={(e) => setChecked(e.target.checked)}
- />
- <button disabled={disabledBtn} >Я кнопка</button>
- </div>
- )
- }
- const Timer = ({ ms = 5 }) => {
- const [counter, setCounter] = useState(ms)
- let [pause, setPause] = useState(false)
- let timeCounter
- useEffect(() => {
- if (counter <= 0) setPause(true)
- if (!pause) {
- timeCounter = setInterval(() => {
- setCounter(counter => counter - 1)
- }, 1000);
- }
- return () => {
- clearInterval(timeCounter)
- }
- }, [pause, counter])
- let hours = Math.floor(counter / 3600)
- let minuts = Math.floor(counter % 3600 / 60)
- let second = counter % 60
- return (
- <div>
- <span>{hours}</span> : <span>{minuts}</span> : <span>{second} </span>
- <button onClick={() => { setPause(!pause) }}>{pause ? 'start' : 'stop'}</button>
- </div>
- )
- }
- const TimerControl = () => {
- const [hourse, setHours] = useState(0)
- const [minuts, setMinuts] = useState(0)
- const [seconds, setSeconds] = useState(0)
- const [open, setOpen] = useState(false)
- let ms = hourse * 3600 + minuts * 60 + seconds
- return (
- <div>
- <label>Hours :
- <input
- min='0'
- type='number'
- onChange={e => setHours(+e.currentTarget.value)} />
- </label><br />
- <label>Minuts :
- <input
- min='0'
- type='number'
- onChange={e => setMinuts(+e.currentTarget.value)} />
- </label><br />
- <label>Seconds:
- <input
- min='0'
- type='number'
- onChange={e => setSeconds(+e.currentTarget.value)} />
- </label>
- <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>
- </>
- )
- }
- ///////////////////////////////////////////////////////////////////////////
- const TimerC = () => {
- const [hourse, setHours] = useState(0)
- const [minuts, setMinuts] = useState(0)
- const [seconds, setSeconds] = useState(0)
- const [open, setOpen] = useState(false)
- let ms = hourse * 3600 + minuts * 60 + seconds
- return (
- <div>
- <label>Hours :
- <input
- min='0'
- type='number'
- onChange={e => setHours(+e.currentTarget.value)} />
- </label><br />
- <label>Minuts :
- <input
- min='0'
- type='number'
- onChange={e => setMinuts(+e.currentTarget.value)} />
- </label><br />
- <label>Seconds:
- <input
- min='0'
- type='number'
- onChange={e => setSeconds(+e.currentTarget.value)} />
- </label>
- <button onClick={() => setOpen(!open)}>{!open ? 'start' : 'stop'}</button>
- {open && <TimerCont seconds={ms} />}
- </div>
- )
- }
- const SecondsTimer = ({ seconds }) => <h2>{seconds.toFixed(1)}</h2>
- const TimerCont = ({ seconds, refresh }) => {
- 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 (
- <SecondsTimer seconds={time} />
- )
- }
- function App() {
- return (
- <div className="App">
- <Spoiler header={<h1>Заголовок</h1>} open>
- Контент 1
- <p>
- лорем ипсум траливали и тп.
- </p>
- </Spoiler>
- <Spoiler>
- <h2>Контент 2</h2>
- <p>
- лорем ипсум траливали и тп.
- </p>
- </Spoiler>
- <RangeInput min={2} max={10} />
- <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} />
- <hr />
- <strong>TimerControl + TimerContainer:</strong>
- <TimerC />
- </div >
- );
- }
- export default App;
|