main.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. function Control(el, { value = 0,
  2. min = 0,
  3. max = 100,
  4. minAngle = 0,
  5. maxAngle = 270,
  6. width = 200,
  7. wheelSpeed = 0.1,
  8. step = 1 } = {}) {
  9. const img = document.createElement('img')
  10. img.src = '1@3x.png'
  11. img.width = width
  12. el.append(img)
  13. const ratio = (maxAngle - minAngle) / (max - min)// сколько градусов 1 ед. велью
  14. const getAngle = () => (value - min) * ratio + minAngle // текущий угол ползунка
  15. this.setValue = newValue => { //проверить, вдруг в этом объекте есть onchange
  16. if (newValue > max) newValue = max
  17. if (newValue < min) newValue = min
  18. if (typeof this.onchange === 'function') {
  19. this.onchange(newValue)
  20. }
  21. value = newValue //и запустить его с новым value
  22. img.style.transform = `rotate(${getAngle()}deg)`
  23. }
  24. this.getValue = () => value
  25. img.onmousewheel = e => {
  26. const { deltaY } = e
  27. const newValue = value + deltaY * wheelSpeed
  28. this.setValue(newValue)
  29. e.preventDefault()
  30. }
  31. img.onclick = e => {
  32. const { layerX } = e
  33. const { width } = img
  34. layerX > width / 2 ? this.setValue(value + step) : this.setValue(value - step)
  35. }
  36. const toDeg = rad => ((rad * 180) / Math.PI + 360 + 90) % 360
  37. let prevMouseAngle = null
  38. img.onmousedown = e => {
  39. const y = e.layerY - img.height / 2
  40. const x = e.layerX - img.width / 2
  41. prevMouseAngle = toDeg(Math.atan2(y, x))
  42. e.preventDefault()
  43. }
  44. img.onmousemove = e => {
  45. if (prevMouseAngle === null) return
  46. const y = e.layerY - img.height / 2
  47. const x = e.layerX - img.width / 2
  48. let currentAngle = toDeg(Math.atan2(y, x))
  49. let moveAngleDiff = (currentAngle - prevMouseAngle)
  50. this.setValue(value + moveAngleDiff / ratio)
  51. prevMouseAngle = currentAngle
  52. }
  53. img.onmouseout = img.onmouseup = () => {
  54. prevMouseAngle = null
  55. }
  56. this.setValue(value)
  57. }
  58. // const volumeControl = new Control(container1, { value: 13, min: 0, max: 100, minAngle: 0, maxAngle: 270, width: 150 })
  59. // volumeControl.onchange = value => console.log(value) //на каждый setValue
  60. // console.log(volumeControl.getValue())
  61. // setTimeout(() => volumeControl.setValue(80), 2000)
  62. //пришейте к нему тэг audio для громкости
  63. function setRGB() {
  64. box.style.backgroundColor = `rgb(${red.getValue().toFixed(0)},${green.getValue().toFixed(0)},${blue.getValue().toFixed(0)})`
  65. box.children[0].innerText = `color rgb:${red.getValue().toFixed(0)},${green.getValue().toFixed(0)},${blue.getValue().toFixed(0)}`
  66. }
  67. const red = new Control(containerRgb, { min: 0, max: 255, width: 100 })
  68. red.onchange = setRGB
  69. const green = new Control(containerRgb, { min: 0, max: 255, width: 100 })
  70. green.onchange = setRGB
  71. const blue = new Control(containerRgb, { min: 0, max: 255, width: 100 })
  72. blue.onchange = setRGB
  73. // громкость звука
  74. const volume = new Control(volMus, {
  75. value: 1, min: 0, max: 1, width: 100, wheelSpeed: 0.001, step: 0.1
  76. })
  77. volume.onchange = controlAudio
  78. // скорость проигрывания
  79. const speedTrack = new Control(speedMus, {
  80. value: 1, min: 0.5, max: 1.5, width: 100, wheelSpeed: 0.001, step: 0.1
  81. })
  82. speedTrack.onchange = controlAudio
  83. // прогресс трека
  84. const progressTrack = new Control(progressMus, {
  85. value: 0, min: 0, max: 100, width: 100, wheelSpeed: 0.01, step: 1
  86. })
  87. // отрисовка изначальных данных в хтмл
  88. volMus.children[0].innerText = `${(volume.getValue() * 100).toFixed(0)}%`
  89. speedMus.children[0].innerText = `${(speedTrack.getValue() * 100).toFixed(0)}%`
  90. progressMus.children[0].innerText = `${progressTrack.getValue().toFixed(0)}%`
  91. // ф-я контейнер для контроллеров
  92. function controlAudio() {
  93. track.volume = volume.getValue()
  94. volMus.children[0].innerText = `${(volume.getValue() * 100).toFixed(0)}%`
  95. track.playbackRate = speedTrack.getValue()
  96. speedMus.children[0].innerText = `${(speedTrack.getValue() * 100).toFixed(0)}%`
  97. track.currentTime = (track.duration / 100) * progressTrack.getValue()
  98. progressMus.children[0].innerText = `${progressTrack.getValue().toFixed(0)}%`
  99. }
  100. btn.onclick = regulatorPlayTrack()
  101. function regulatorPlayTrack() {
  102. let chek = false//чек для плей и стоп
  103. let stopAnim;
  104. let stopGlyuk;
  105. return function () {
  106. // функция для визуального ефекта прогресса проигрывания
  107. let reDraw = function () {
  108. progressTrack.setValue((track.currentTime * 100) / track.duration)
  109. progressMus.children[0].innerText = `${progressTrack.getValue().toFixed(0)}%`
  110. }
  111. // рандом боди при проигрывание
  112. let glyuk = function () {
  113. body.style.backgroundColor = `rgb(${Math.round(Math.random() * 255).toFixed(0)},${Math.round(Math.random() * 255).toFixed(0)},${Math.round(Math.random() * 255).toFixed(0)})`
  114. }
  115. // добавляем клас для замены отрисовки кнопки
  116. btn.classList.toggle("active");
  117. if (!chek) {
  118. track.play()
  119. progressTrack.onchange = ''
  120. chek = true
  121. stopAnim = setInterval(reDraw, 100);
  122. stopGlyuk = setInterval(glyuk, 300);
  123. } else {
  124. track.pause()
  125. progressTrack.onchange = controlAudio
  126. chek = false
  127. clearInterval(stopAnim)
  128. clearInterval(stopGlyuk)
  129. }
  130. }
  131. }