2013-03-27 4 views
7

Я создал градиентный колобар с стилями CSS3 (fiddle) и теперь хочу, чтобы в этом цветовом баре было значение цвета определенного места (по координатам x и y). Насколько я знаю, нет прямого способа сделать это.Получить цветное значение конкретной позиции в цветовой панели с градиентом

Я вижу два варианта:

  1. Реализовать алгоритм градиента в JavaScript и вычислить значение с нуля. Есть ли точное определение того, как этот алгоритм работает для нескольких цветов? Градиент выглядит одинаково в каждом браузере?

  2. Используйте метод canvas и createLinearGradient для рисования градиента и доступа к холсту непосредственно, чтобы получить значение цвета.

Любые другие варианты?

ответ

7

Я решил реализовать свое первое решение (выведите градиент с помощью JavaScript). Это означает, что вам не нужно полагаться на поддержку элемента canvas, что может быть важно в зависимости от поддержки вашего браузера.

Использование методов canvas было бы также круто, а проще. Вы можете отобразить остановки цвета из CSS, а затем использовать getImageData(), чтобы выяснить, какой цвет указателя был закончен.

Вы можете извлечь CSS цвета с регулярным выражением, и отображать любые человека одни к RGB с ...

var background = window.getComputedStyle(element).getPropertyValue("background"); 

var colorStops = []; 
var matchColorStops = /,\s*(\w+)\s+(\d+)%/g; 
var match; 

var humanToHex = { 
    "red": [255, 0, 0], 
    "green": [0, 128, 0], 
    "blue": [0, 0, 255] 
}; 

while (match = matchColorStops.exec(background)) { 
    if (humanToHex[match[1]]) { 
     match[1] = humanToHex[match[1]]; 
    } 
    colorStops.push({ 
     percentage: match[2], 
     color: match[1] 
    }); 
} 

Вы можете использовать эту небольшую функцию JavaScript, чтобы интерполировать два цвета, если они разделены на их значения RGB.

var getStepColor = function(colorA, colorB, value) { 
    return colorA.map(function(color, i) { 
     return (color + value * (colorB[i] - color)) & 255; 
    }); 
}; 

Вы можете комбинировать, что, чтобы получить код, который позволит вам сделать это ...

var getStepColor = function (colorA, colorB, value) { 
    return colorA.map(function (color, i) { 
     return (color + value * (colorB[i] - color)) & 255; 
    }); 
}; 

var gradient = document.querySelector("#gradient"); 
var preview = document.querySelector("#preview"); 

var background = window.getComputedStyle(gradient).getPropertyValue("background"); 

var colorStops = []; 
var matchColorStops = /,\s*(\w+)\s+(\d+)%/g; 
var match; 

var humanToHex = { 
    "red": [255, 0, 0], 
    "green": [0, 128, 0], 
    "blue": [0, 0, 255] 
}; 

while (match = matchColorStops.exec(background)) { 
    // If colour is *human-readable*, then 
    // substitute it for a RGB value. 
    if (humanToHex[match[1]]) { 
     match[1] = humanToHex[match[1]]; 
    } 
    colorStops.push({ 
     percentage: match[2], 
     color: match[1] 
    }); 
} 

gradient.addEventListener("mousemove", function (event) { 

    var x = event.pageX - gradient.offsetTop; 
    var y = event.pageY - gradient.offsetLeft; 
    var percentage = (x/this.offsetWidth) * 100; 

    var i; 
    for (i = 0; i < colorStops.length; i++) { 
     if (colorStops[i].percentage > percentage) { 
      break; 
     }; 
    } 

    var lowerIndex = i == 1 ? 0 : i - 1; 
    var upperIndex = lowerIndex + 1; 
    var value = x/(gradient.offsetWidth/(colorStops.length - 1)) % 1; 

    color = getStepColor(colorStops[lowerIndex].color, colorStops[upperIndex].color, value); 

    preview.style.backgroundColor = "rgb(" + color.join() + ")"; 
    preview.textContent = preview.style.backgroundColor; 

}); 

jsFiddle.

Это просто быстрый способ взломать этот способ, возможно, есть лучший надежный способ извлечения цветов и для выяснения, где указатель относится к тому сегменту градиента.

+0

Очень хороший ответ и отличный пример. Большое спасибо. – Zardoz

+0

Не беспокойтесь, спасибо, что задали большой вопрос. Вы пойдете с этим или на основе холста? – alex

+0

У меня есть два проекта, в которых я нуждаюсь. Один проект уже использует некоторые материалы WebGL, поэтому другой холст сделает это. Для другого проекта (без использования холста) я буду использовать ваше решение. – Zardoz

Смежные вопросы