function Control(
    el, {
        value = 0,
        step = 1,
        max = 100,
        min = 0,
        maxAngle = 360,
        minAngle = 0
    } = {}
) {
    const img = document.createElement("img");
    img.src = "1@3x.png";
    img.width = "250";
    el.append(img);

    const ratio = (maxAngle - minAngle) / (max - min);

    const value2Deg = () => ratio * (value - min) + minAngle;

    const changeValue = (delta, fireEvent = false) => {
        let newValue = value + delta;
        if (newValue >= max) newValue = max;
        if (newValue <= min) newValue = min;

        value = newValue;

        if (fireEvent && this.onChange && typeof this.onChange === "function") {
            this.onChange(value);
        }

        img.style.transform = `rotate(${value2Deg()}deg)`;
    };

    const {
        top,
        left
    } = img.getBoundingClientRect();

    changeValue(0);

    console.log(img.width, top, left);

    img.onclick = (e) => {
        changeValue(e.clientX - left > img.width / 2 ? step : -step, true);
    };

    img.onmousewheel = (e) => {
        changeValue((e.deltaY * step) / 25, true);
        e.preventDefault();
    };

    let startDragAngle;

    const calcAngle = ({
        layerX,
        layerY
    }) => {
        const deltaX = layerX - img.width / 2;
        const deltaY = layerY - img.height / 2;
        return (Math.atan2(deltaY, deltaX) / Math.PI) * 180;
    };

    img.onmousedown = (e) => {
        startDragAngle = calcAngle(e);
        e.preventDefault();
    };

    img.onmousemove = (e) => {
        if (startDragAngle !== undefined) {
            const currentAngle = calcAngle(e);
            let deltaAngle = currentAngle - startDragAngle;

            // дальше идет коррекция перехода через +-180 градусов
            // но из-за функции onclick осталось иногда подергивание
            // при выкручивании в крайние положения
            // onclick пришлось отключить
            if (Math.abs(deltaAngle) >= 180) {
                deltaAngle += deltaAngle < 0 ? 360 : -360;
            } else {
                deltaAngle += deltaAngle < 0 ? -360 : 360;
            }
            deltaAngle = deltaAngle % 360;

            changeValue(deltaAngle / ratio, true);
            startDragAngle = currentAngle;
            e.preventDefault();
        }
    };

    img.onmouseup = img.onmouseout = (e) => {
        if (startDragAngle) {
            startDragAngle = undefined;
            e.preventDefault();
        }
    };

    this.setValue = (v) => changeValue(v - value);
    this.changeValue = changeValue;

    this.getValue = () => value;
}

const volumeControl = new Control(container1, {
    value: 50, max: 1, step: 0.01
});

let volumeMp3 = document.getElementById("audio");

// volumeControl.onChange = (value) => console.log("VOLUME", value);
volumeControl.onChange = (value) => volumeMp3.volume = value;

const redControl = new Control(color1, {
    maxAngle: 90,
    minAngle: -90,
    min: 0,
    max: 255,
    value: 0,
});

const greenControl = new Control(color2, {
    maxAngle: 90,
    minAngle: -90,
    min: 0,
    max: 255,
    value: 0,
});

const blueControl = new Control(color3, {
    maxAngle: 90,
    minAngle: -90,
    min: 0,
    max: 255,
    value: 0,
});

redControl.onChange = (x) => RGB.style.background = `rgb(${x}, ${greenControl.getValue()}, ${blueControl.getValue()})`;
greenControl.onChange = (x) => RGB.style.background = `rgb(${redControl.getValue()}, ${x}, ${blueControl.getValue()})`;
blueControl.onChange = (x) => RGB.style.background = `rgb(${redControl.getValue()}, ${greenControl.getValue()}, ${x})`;

// value = 0,
// step = 1,
// max = 100,
// min = 0,
// maxAngle = 360,
// minAngle = 0