14_krutilki_RGB.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. function Control(
  2. el,
  3. {
  4. value = 0,
  5. step = 1,
  6. max = 100,
  7. min = 0,
  8. maxAngle = 360,
  9. minAngle = 0,
  10. } = {}
  11. ) {
  12. const img = document.createElement("img");
  13. img.src = "./1@3xNew.png";
  14. img.width = "200";
  15. el.append(img);
  16. const ratio = (maxAngle - minAngle) / (max - min);
  17. const value2Deg = () => ratio * (value - min) + minAngle;
  18. const changeValue = (delta, fireEvent = false) => {
  19. let newValue = value + delta;
  20. if (newValue >= max) newValue = max;
  21. if (newValue <= min) newValue = min;
  22. value = newValue;
  23. //console.log(value)
  24. if (fireEvent && this.onChange && typeof this.onChange === "function") {
  25. this.onChange(value);
  26. }
  27. img.style.transform = `rotate(${value2Deg()}deg)`;
  28. img.style.transformOrigin = `50% 50%`;
  29. };
  30. const { top, left } = img.getBoundingClientRect();
  31. changeValue(0);
  32. // console.log(img.width, top, left);
  33. // img.onclick = (e) => {
  34. // changeValue(e.clientX - left > img.width / 2 ? step : -step, true);
  35. // };
  36. img.onmousewheel = (e) => {
  37. changeValue((e.deltaY * step) / 25, true); // "/25" - это для лучшей чуствительности для мышки
  38. e.preventDefault();
  39. };
  40. let startDragAngle;
  41. const calcAngle = ({ layerX, layerY }) => {
  42. const deltaX = layerX - img.width / 2;
  43. const deltaY = layerY - img.height / 2;
  44. return (Math.atan2(deltaY, deltaX) / Math.PI) * 180;
  45. };
  46. img.onmousedown = (e) => {
  47. startDragAngle = calcAngle(e);
  48. e.preventDefault();
  49. };
  50. img.onmousemove = (e) => {
  51. if (startDragAngle !== undefined) {
  52. const currentAngle = calcAngle(e);
  53. let deltaAngle = currentAngle - startDragAngle;
  54. // дальше идет коррекция перехода через +-180 градусов
  55. // но из-за функции onclick осталось иногда подергивание
  56. // при выкручивании в крайние положения
  57. // onclick пришлось отключить
  58. if (Math.abs(deltaAngle) >= 180) {
  59. deltaAngle += deltaAngle < 0 ? 360 : -360;
  60. } else {
  61. deltaAngle += deltaAngle < 0 ? -360 : 360;
  62. }
  63. deltaAngle = Math.round(deltaAngle % 360);
  64. changeValue(deltaAngle / ratio, true);
  65. startDragAngle = currentAngle;
  66. e.preventDefault();
  67. }
  68. };
  69. img.onmouseup = img.onmouseout = (e) => {
  70. if (startDragAngle) {
  71. startDragAngle = undefined;
  72. e.preventDefault();
  73. }
  74. };
  75. this.setValue = (v) => changeValue(v - value);
  76. this.changeValue = changeValue;
  77. this.getValue = () => value;
  78. }
  79. //
  80. //
  81. //
  82. const audio = document.getElementById("myaudio");
  83. // для пробы коррекции перехода через +-180 сделал крутилку на 2 оборота
  84. const volumeControl = new Control(volume, {
  85. max: 1,
  86. min: 0,
  87. step: 0.01,
  88. maxAngle: 720,
  89. });
  90. volumeControl.onChange = (value) => {
  91. audio.volume = value;
  92. volumeLevel.value = value;
  93. console.log("VOLUME ", volumeLevel.value);
  94. };
  95. volumeLevel.oninput = () => {
  96. audio.volume = volumeLevel.value;
  97. volumeControl.setValue(audio.volume);
  98. console.log("VOLUME ", volumeControl.getValue());
  99. };
  100. volumeLevel.value = 0;
  101. audio.volume = 0;
  102. // ----------------------------------------------------------
  103. const setGradient = function () {
  104. redGradient.style.background = `linear-gradient(to right, rgb(0,${greenControl.getValue()}, ${blueControl.getValue()}),
  105. rgb(255, ${greenControl.getValue()}, ${blueControl.getValue()}))`;
  106. greenGradient.style.background = `linear-gradient(to right, rgb(${redControl.getValue()}, 0, ${blueControl.getValue()}),
  107. rgb(${redControl.getValue()}, 255, ${blueControl.getValue()}))`;
  108. blueGradient.style.background = `linear-gradient(to right, rgb(${redControl.getValue()}, ${greenControl.getValue()}, 0),
  109. rgb(${redControl.getValue()}, ${greenControl.getValue()}, 255))`;
  110. };
  111. const redControl = new Control(redDiv, {
  112. max: 255,
  113. maxAngle: 150,
  114. minAngle: -150,
  115. });
  116. redControl.onChange = (value) => {
  117. redDiv.setAttribute(
  118. "style",
  119. `background : rgba(255, 0, 0, ${value / 255}); border-radius: 50%;`
  120. );
  121. rgbDiv.setAttribute(
  122. "style",
  123. `background : rgb(${value}, ${greenLevel.value}, ${blueLevel.value})`
  124. );
  125. redLevel.value = Math.round(value);
  126. setGradient();
  127. console.log("RED", Math.round(value));
  128. };
  129. redLevel.oninput = () => {
  130. redControl.onChange(redLevel.value);
  131. redControl.setValue(Math.round(redLevel.value));
  132. };
  133. redLevel.value = 0;
  134. redGradient.style.background =
  135. "linear-gradient(to right, rgb(0,0,0), rgb(255,0,0))";
  136. // ----------------------------------------------------------
  137. const greenControl = new Control(greenDiv, {
  138. max: 255,
  139. maxAngle: 150,
  140. minAngle: -150,
  141. });
  142. greenControl.onChange = (value) => {
  143. greenDiv.setAttribute(
  144. "style",
  145. `background : rgba(0, 255, 0, ${value / 255}); border-radius: 50%;`
  146. );
  147. rgbDiv.setAttribute(
  148. "style",
  149. `background : rgb(${redLevel.value}, ${value}, ${blueLevel.value})`
  150. );
  151. greenLevel.value = Math.round(value);
  152. setGradient();
  153. console.log("GREEN", Math.round(value));
  154. };
  155. greenLevel.oninput = () => {
  156. greenControl.onChange(greenLevel.value);
  157. greenControl.setValue(Math.round(greenLevel.value));
  158. };
  159. greenLevel.value = 0;
  160. greenGradient.style.background =
  161. "linear-gradient(to right, rgb(0,0,0), rgb(0,255,0))";
  162. // ----------------------------------------------------------
  163. const blueControl = new Control(blueDiv, {
  164. max: 255,
  165. maxAngle: 150,
  166. minAngle: -150,
  167. });
  168. blueControl.onChange = (value) => {
  169. blueDiv.setAttribute(
  170. "style",
  171. `background : rgba(0, 0, 255, ${value / 255}); border-radius: 50%;`
  172. );
  173. rgbDiv.setAttribute(
  174. "style",
  175. `background : rgb(${redLevel.value}, ${greenLevel.value}, ${value})`
  176. );
  177. blueLevel.value = Math.round(value);
  178. setGradient();
  179. console.log("BLUE", Math.round(value));
  180. };
  181. blueLevel.oninput = () => {
  182. blueControl.onChange(blueLevel.value);
  183. blueControl.setValue(Math.round(blueLevel.value));
  184. };
  185. blueLevel.value = 0;
  186. blueGradient.style.background =
  187. "linear-gradient(to right, rgb(0,0,0), rgb(0,0,255))";
  188. // ----------------------------------------------------------
  189. rgbDiv.setAttribute("style", "background : rgb(0, 0, 0)");