function Control(
  el,
  {
    min = 0,
    max = 255,
    step = 1,
    value = 0,
    onChange,
    minAngle = 0,
    wheelStepRatio = 0.01,
    maxAngle = 360,
    src = "1@3x.png",
  } = {}
) {
  this.value = value;
  const img = document.createElement("img");
  el.appendChild(img);
  img.src = src;
  const angleRatio = (maxAngle - minAngle) / (max - min);

  const getAngle = () => (value - min) * angleRatio + minAngle;

  const updateImg = (angle = getAngle()) =>
    (img.style.transform = `rotate(${angle}deg)`);

  updateImg();

  const updateValue = (st = step) => {
    value >= max ? (value -= max) : value < min ? (value += max) : value;
    value += st;
    onChange(Math.floor(value));
    updateImg();
  };

  img.onclick = (e) => {
    const { x: imgX, width: imgWidth } = img.getBoundingClientRect();
    const xOnImg = e.clientX - imgX;
    const st = xOnImg > imgWidth / 2 ? step : -step;

    updateValue(st);
  };

  img.onmousewheel = (e) => {
    const st = e.deltaY * wheelStepRatio;
    updateValue(st);
  };

  const toDeg = (rad) => (360 / (2 * Math.PI)) * rad;
  let startAngle;

  const getAngleByCoords = (x, y) => {
    const { x: imgX, y: imgY, width, height } = img.getBoundingClientRect();
    const xOnImg = x - imgX - width / 2;
    const yOnImg = y - imgY - height / 2;
    const angle = toDeg(Math.atan2(yOnImg, xOnImg));
    return angle;
  };

  img.onmousedown = (e) => {
    startAngle = getAngleByCoords(e.clientX, e.clientY);
    e.preventDefault();
  };

  img.onmousemove = (e) => {
    if (e.buttons && startAngle) {
      const angleDiff = getAngleByCoords(e.clientX, e.clientY) - startAngle;
      const angle = getAngle();
      updateImg(angle + angleDiff);
    }
  };
  img.onmouseup = (e) => {
    const angleDiff = getAngleByCoords(e.clientX, e.clientY) - startAngle;
    updateValue(angleDiff / angleRatio);
    startAngle = null;
  };
}

let rgb = { red: 0, green: 0, blue: 0 };
function mixPalette(colors) {
  let { red, green, blue } = colors;
  let paletteForMix = document.querySelector("body");
  paletteForMix.style = `width:500px;height:500px;background:rgb(${red},${green},${blue})`;
}

let soundlRed = new Control(sound1, {
  max: 255,
  onChange: (value) => {
    sound1.style = `width:500px;background:rgb(${value},0,0)`;
    rgb.red = value;
    mixPalette(rgb);
  },
});
let soundlGreen = new Control(sound2, {
  max: 255,
  onChange: (value) => {
    sound2.style = `width:500px;background:rgb(0,${value},0)`;
    rgb.green = value;
    mixPalette(rgb);
  },
});
let soundlBlue = new Control(sound3, {
  max: 255,
  onChange: (value) => {
    sound3.style = `width:500px;background:rgb(0,0,${value})`;
    rgb.blue = value;
    mixPalette(rgb);
  },
});
