App.js 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. import logo from './logo.svg';
  2. import './App.scss';
  3. import { useState, useEffect, useRef } from "react";
  4. const Spoiler = ({ header = "+", open, children }) => {
  5. const [openMode, setOpenMode] = useState(open)
  6. return (
  7. <div onClick={() => setOpenMode(!openMode)}>
  8. {header}
  9. {openMode && children}
  10. </div>
  11. )
  12. }
  13. const RangeInput = ({ min, max }) => {
  14. const [state, setState] = useState('')
  15. const colorBorder = state.length <= min || state.length >= max ? 'red' : ''
  16. return <input style={{ backgroundColor: colorBorder }}
  17. onChange={(e) => { setState(e.target.value) }} />
  18. }
  19. const PasswordConfirm = ({ min }) => {
  20. const [checked, setChecked] = useState(false)
  21. const [stateInputOne, setStateInputOne] = useState('')
  22. const [stateInputTwo, setStateInputTwo] = useState('')
  23. const reg = /(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/
  24. const disabledBtn = stateInputOne === stateInputTwo && reg.test(stateInputOne) ? false : true
  25. return (
  26. <div>
  27. <input style={{ borderColor: stateInputOne.length <= min ? 'red' : 'black' }}
  28. type={checked ? 'password' : 'text'}
  29. onChange={(e) => { setStateInputOne(e.target.value) }} />
  30. <input style={{ borderColor: stateInputTwo.length <= min ? 'red' : 'black' }}
  31. type={checked ? 'password' : 'text'}
  32. onChange={(e) => { setStateInputTwo(e.target.value) }} />
  33. <input type='checkbox'
  34. checked={checked}
  35. onChange={(e) => setChecked(e.target.checked)}
  36. />
  37. <button disabled={disabledBtn} >Я кнопка</button>
  38. </div>
  39. )
  40. }
  41. const Timer = ({ ms = 5 }) => {
  42. const [counter, setCounter] = useState(ms)
  43. let [pause, setPause] = useState(false)
  44. let timeCounter
  45. useEffect(() => {
  46. if (counter <= 0) setPause(true)
  47. if (!pause) {
  48. timeCounter = setInterval(() => {
  49. setCounter(counter => counter - 1)
  50. }, 1000);
  51. }
  52. return () => {
  53. clearInterval(timeCounter)
  54. }
  55. }, [pause, counter])
  56. let hours = Math.floor(counter / 3600)
  57. let minuts = Math.floor(counter % 3600 / 60)
  58. let second = counter % 60
  59. return (
  60. <div>
  61. <span>{hours}</span> : <span>{minuts}</span> : <span>{second} </span>
  62. <button onClick={() => { setPause(!pause) }}>{pause ? 'start' : 'stop'}</button>
  63. </div>
  64. )
  65. }
  66. const TimerControl = () => {
  67. const [hourse, setHours] = useState(0)
  68. const [minuts, setMinuts] = useState(0)
  69. const [seconds, setSeconds] = useState(0)
  70. const [open, setOpen] = useState(false)
  71. let ms = hourse * 3600 + minuts * 60 + seconds
  72. return (
  73. <div>
  74. <label>Hours :
  75. <input
  76. min='0'
  77. type='number'
  78. onChange={e => setHours(+e.currentTarget.value)} />
  79. </label><br />
  80. <label>Minuts :
  81. <input
  82. min='0'
  83. type='number'
  84. onChange={e => setMinuts(+e.currentTarget.value)} />
  85. </label><br />
  86. <label>Seconds:
  87. <input
  88. min='0'
  89. type='number'
  90. onChange={e => setSeconds(+e.currentTarget.value)} />
  91. </label>
  92. <button onClick={() => setOpen(!open)}>{!open ? 'start' : 'stop'}</button>
  93. {open && <Timer ms={ms} />}
  94. </div>
  95. )
  96. }
  97. const TimerContainer = ({ seconds, refresh, render: T }) => {
  98. const t0 = performance.now()
  99. const [time, setTime] = useState(seconds)
  100. useEffect(() => {
  101. const timerID = setInterval(() => {
  102. let t1 = performance.now()
  103. if (seconds >= (t1 - t0) / 1000) {
  104. setTime(seconds - (t1 - t0) / 1000)
  105. } else {
  106. setTime(0)
  107. clearInterval(timerID)
  108. }
  109. }, refresh);
  110. return () => {
  111. setTime(seconds)
  112. clearInterval(timerID)
  113. }
  114. }, [])
  115. return (
  116. <T seconds={time} />
  117. )
  118. }
  119. const SecondsTimer = ({ seconds }) => <h2>{seconds.toFixed(1)}</h2>
  120. const TimerLCD = ({ time = 5 }) => {
  121. let hours = Math.floor(time / 3600)
  122. let minuts = Math.floor(time % 3600 / 60)
  123. let seconds = time % 60
  124. return (
  125. <div>
  126. <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>
  127. </div>
  128. )
  129. }
  130. const TimerControlLCD = ({ ms, render: T }) => {
  131. const [open, setOpen] = useState(true)
  132. const t0 = performance.now()
  133. const [time, setTime] = useState(ms)
  134. useEffect(() => {
  135. if (open) {
  136. const timerID = setInterval(() => {
  137. let t1 = performance.now()
  138. if (ms >= (t1 - t0) / 1000) {
  139. setTime(ms - (t1 - t0) / 1000)
  140. } else {
  141. setTime(0)
  142. clearInterval(timerID)
  143. }
  144. }, 1000);
  145. return () => {
  146. setTime(ms)
  147. clearInterval(timerID)
  148. }
  149. }
  150. }, [open])
  151. return (
  152. <div>
  153. <button onClick={() => setOpen(!open)}>{open ? 'start' : 'stop'}</button>
  154. {open && <T time={time} />}
  155. </div>
  156. )
  157. }
  158. const Watch = ({ time }) => {
  159. let hours = (time / 3600 * 30)
  160. let seconds = (time * 6).toFixed(0)
  161. let minuts = (time % 3600 / 60) * 6
  162. return (
  163. <>
  164. <strong>
  165. <TimerLCD time={time} />
  166. </strong>
  167. <div className='Watch'>
  168. <img className='clock' src='./ClockFace.png' />
  169. <img className='hour' style={{ transform: `rotate(${hours}deg)` }} src='./hour.png' />
  170. <img className='minuts' style={{ transform: `rotate(${minuts}deg)` }} src='./minut.png' />
  171. <img className='seconds' style={{ transform: `rotate(${seconds}deg)` }} src='./second.png' />
  172. </div>
  173. </>
  174. )
  175. }
  176. ///////////////////////////////////////////////////////////////////////////
  177. const TimerC = () => {
  178. const [hourse, setHours] = useState(0)
  179. const [minuts, setMinuts] = useState(0)
  180. const [seconds, setSeconds] = useState(0)
  181. const [open, setOpen] = useState(false)
  182. let ms = hourse * 3600 + minuts * 60 + seconds
  183. return (
  184. <div>
  185. <label>Hours :
  186. <input
  187. min='0'
  188. type='number'
  189. onChange={e => setHours(+e.currentTarget.value)} />
  190. </label><br />
  191. <label>Minuts :
  192. <input
  193. min='0'
  194. type='number'
  195. onChange={e => setMinuts(+e.currentTarget.value)} />
  196. </label><br />
  197. <label>Seconds:
  198. <input
  199. min='0'
  200. type='number'
  201. onChange={e => setSeconds(+e.currentTarget.value)} />
  202. </label>
  203. <button onClick={() => setOpen(!open)}>{!open ? 'start' : 'stop'}</button>
  204. {open && <TimerCont seconds={ms} />}
  205. </div>
  206. )
  207. }
  208. const SecondsTimer = ({ seconds }) => <h2>{seconds.toFixed(1)}</h2>
  209. const TimerCont = ({ seconds, refresh }) => {
  210. const t0 = performance.now()
  211. const [time, setTime] = useState(seconds)
  212. useEffect(() => {
  213. const timerID = setInterval(() => {
  214. let t1 = performance.now()
  215. if (seconds >= (t1 - t0) / 1000) {
  216. setTime(seconds - (t1 - t0) / 1000)
  217. } else {
  218. setTime(0)
  219. clearInterval(timerID)
  220. }
  221. }, refresh);
  222. return () => {
  223. setTime(seconds)
  224. clearInterval(timerID)
  225. }
  226. }, [])
  227. return (
  228. <SecondsTimer seconds={time} />
  229. )
  230. }
  231. function App() {
  232. return (
  233. <div className="App">
  234. <Spoiler header={<h1>Заголовок</h1>} open>
  235. Контент 1
  236. <p>
  237. лорем ипсум траливали и тп.
  238. </p>
  239. </Spoiler>
  240. <Spoiler>
  241. <h2>Контент 2</h2>
  242. <p>
  243. лорем ипсум траливали и тп.
  244. </p>
  245. </Spoiler>
  246. <RangeInput min={2} max={10} />
  247. <hr />
  248. <PasswordConfirm min={2} />
  249. <hr />
  250. <strong>Timer :</strong>
  251. <Timer ms={4000} />
  252. <hr />
  253. <strong>TimerControl :</strong>
  254. <TimerControl />
  255. <hr />
  256. <strong>TimerContainer :</strong>
  257. <TimerContainer seconds={1000} refresh={100} render={SecondsTimer} />
  258. <hr />
  259. <strong>LCD :</strong>
  260. <TimerControlLCD ms={5000} render={TimerLCD} />
  261. <hr />
  262. <strong>Watch :</strong>
  263. <TimerControlLCD ms={1560} render={Watch} />
  264. <hr />
  265. <strong>TimerControl + TimerContainer:</strong>
  266. <TimerC />
  267. </div >
  268. );
  269. }
  270. export default App;