rgb.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. {
  2. function colorReducer(state, {type, value}) {
  3. if (state === undefined) {
  4. return {
  5. red: 0,
  6. green: 0,
  7. blue: 0
  8. }
  9. }
  10. if (type === 'COLOR_RED' && typeof value === 'number' && value >= 0 && value <= 255) {
  11. return {
  12. ...state,
  13. red: value
  14. }
  15. }
  16. if (type === 'COLOR_GREEN' && typeof value === 'number' && value >= 0 && value <= 255) {
  17. return {
  18. ...state,
  19. green: value
  20. }
  21. }
  22. if (type === 'COLOR_BLUE' && typeof value === 'number' && value >= 0 && value <= 255) {
  23. return {
  24. ...state,
  25. blue: value
  26. }
  27. }
  28. return state
  29. }
  30. function createStore(reducer) {
  31. let state = reducer(undefined, {}) //стартовая инициализация состояния, запуск редьюсера со state === undefined
  32. let cbs = [] //массив подписчиков
  33. const getState = () => state //функция, возвращающая переменную из замыкания
  34. const subscribe = cb => (cbs.push(cb), //запоминаем подписчиков в массиве
  35. () => cbs = cbs.filter(c => c !== cb)) //возвращаем функцию unsubscribe, которая удаляет подписчика из списка
  36. const dispatch = action => {
  37. const newState = reducer(state, action) //пробуем запустить редьюсер
  38. if (newState !== state) { //проверяем, смог ли редьюсер обработать action
  39. state = newState //если смог, то обновляем state
  40. for (let cb of cbs) cb() //и запускаем подписчиков
  41. }
  42. }
  43. return {
  44. getState, //добавление функции getState в результирующий объект
  45. dispatch,
  46. subscribe //добавление subscribe в объект
  47. }
  48. }
  49. let store = createStore(colorReducer);
  50. console.log(store.getState())
  51. console.log(store.dispatch("COLOR_RED", 50))
  52. console.log(store.getState())
  53. store.subscribe(() => console.log(store.getState()))
  54. store.dispatch("COLOR_RED", 60)
  55. store.dispatch("COLOR_BLUE", 600);
  56. const actionColorRed = value => ({type: "COLOR_RED", value});
  57. const actionColorGreen = value => ({type: "COLOR_GREEN", value});
  58. const actionColorBlue = value => ({type: "COLOR_BLUE", value});
  59. store.dispatch(actionColorBlue(100))
  60. store.subscribe(() => {
  61. const {red, green, blue} = store.getState()
  62. document.body.style.backgroundColor = `rgb(${red}, ${green}, ${blue})`
  63. })
  64. store.dispatch(actionColorGreen(100))
  65. store.dispatch(actionColorGreen(200))
  66. const redInput = document.createElement('input')
  67. redInput.type = 'number'
  68. redInput.min = 0;
  69. redInput.max = 255
  70. redInput.oninput = () => store.dispatch(actionColorRed(+redInput.value))
  71. document.body.append(redInput)
  72. const greenInput = document.createElement('input')
  73. greenInput.type = 'number'
  74. greenInput.min = 0;
  75. greenInput.max = 255
  76. greenInput.oninput = () => store.dispatch(actionColorGreen(+greenInput.value))
  77. document.body.append(greenInput)
  78. store.subscribe(() => redInput.value = store.getState().red)
  79. store.dispatch(actionColorRed(100))
  80. const inputColor = document.createElement('input')
  81. inputColor.type = 'color'
  82. inputColor.oninput = () => console.log(inputColor.value)
  83. document.body.append(inputColor)
  84. inputColor.oninput = () => {
  85. const hex = inputColor.value
  86. const red = parseInt(hex.slice(1, 3), 16)
  87. const green = parseInt(hex.slice(3, 5), 16)
  88. const blue = parseInt(hex.slice(5, 7), 16)
  89. store.dispatch(actionColorRed(red))
  90. store.dispatch(actionColorGreen(green))
  91. store.dispatch(actionColorBlue(blue))
  92. console.log(red, green, blue)
  93. }
  94. store.subscribe(() => {
  95. const {red, green, blue} = store.getState()
  96. const colorToHex = value => (value < 16 ? '0' : '') + value.toString(16)
  97. inputColor.value = `#${colorToHex(red)}${colorToHex(green)}${colorToHex(blue)}`
  98. })
  99. store.dispatch(actionColorRed(0))
  100. store.dispatch(actionColorGreen(0))
  101. store.dispatch(actionColorBlue(0))
  102. } */