Получить данные изображения на холсте Click с точными координатами

Ссылка на скрипт JS

Я пытаюсь щелкнуть холст (с линейным градиентом) и получить данные изображения в точке щелчка.

Также я хочу разместить относительный желтый (выборщик) в этой точке (щелкнуть)

Проблема 1: Когда я нажимаю на нижнюю часть (белую), это дает мне неправильное значение цвета.

Проблема 2: желтый (выборщик) не расположен точно в точке щелчка

Примечание. Холст выглядит круглым из-за радиуса границы: 50%

Важная часть кода, указанная в (выше ссылки на скрипку),

$(wheel_canvas).click(function(e)
{
    dragging = false;
    x = e.pageX;
    y = e.pageY;

    can_p = $('#wheel_canvas').offset();
    x = x - $(document).scrollLeft() - can_p.left;
    x = y - $(document).scrollTop() - can_p.top;

    $('#wheel_picker').css({'left':x+'px','top':y+'px'});
    var data=wheel_context.getImageData(x,y,1,1).data;
    pixelData = data;
    rgbString = 'rgb('+pixelData[0]+', '+pixelData[1]+', '+pixelData[2]+')';
    hex = rgb2hex(rgbString);

    $('#color').val(hex);
    $('#color').css('background',hex);

    $('#feedback').html("Coordinates : "+x+","+y+"  Color: "+hex);
});

Изменить Ответ, включая скрипку, был бы лучше :)


person Sami    schedule 29.05.2014    source источник


Ответы (2)


Основная проблема в том, что ваш холст имеет радиус границы. С радиусом границы почему-то путаются координаты мыши. Вместо этого я использовал квадратный холст, но использовал метод arc() для рисования круга.

wheel_context.fillStyle = wheel_grd;
wheel_context.beginPath();
wheel_context.arc(centerX, centerY, LARGE_RADIUS, 0, 2 * Math.PI);
wheel_context.fill();

Затем я снял меньший серебряный холст. Проблема заключалась в том, что предполагалось, что события мыши не будут всплывать (т. е. если вы нажмете на серебристую часть, она не будет регистрироваться как цвет), однако это также останавливало события мыши рядом с ней (потому что, даже с радиусом границы это был фактически квадрат согласно браузеру). Вместо этого я использовал тот же метод круга (arc), чтобы нарисовать серебряный круг меньшего размера.

wheel_context.fillStyle = "silver";
wheel_context.beginPath();
wheel_context.arc(centerX, centerY, SMALL_RADIUS, 0, 2 * Math.PI);
wheel_context.fill();

(Сейчас LARGE_RADIUS равно 150, а SMALL_RADIUS равно 110. Вы можете настроить их, если хотите). Чтобы проверить, была ли мышь в серебряной части или в цветной части, я вычислил расстояние от центра. Если он был меньше радиуса серебряного круга, вы знаете, что он был в серебряном круге.

if (Math.sqrt(
            (x - centerX) * (x - centerX) + // Square of x difference
            (y - centerY) * (y - centerY)  // Square of y difference
            ) < SMALL_RADIUS) return;

Я также исправил несколько опечаток, которые мешали точной регистрации местоположения мыши.

Готовый продукт: http://jsfiddle.net/kNTVZ/.

Примечание. Многие ваши переменные не были определены должным образом. Вам нужен var, чтобы они не были глобальными.

person soktinpk    schedule 29.05.2014
comment
Sooperb Отличные усилия привели к отличному ответу. Большое спасибо. - person Sami; 29.05.2014

pageX и pageY иногда ненадежны для разных браузеров.

Поскольку вы уже используете jQuery, попробуйте использовать его для нормализации вашего события:

$(wheel_canvas).click(function(e)
{
    e = e || window.event;
    e = jQuery.event.fix(e);    

    dragging = false;    
    x = e.pageX;
    y = e.pageY;

    // ... rest of code
}
person Robusto    schedule 29.05.2014