Ho scelto di implementare la prima soluzione (calcolo del gradiente con JavaScript). Significa che non è necessario fare affidamento sul supporto per l'elemento canvas
, che potrebbe essere importante in base al supporto del browser.
L'utilizzo dei metodi canvas
sarebbe anche vantaggioso e più semplice. È possibile eseguire il rendering delle interruzioni di colore dal CSS e quindi utilizzare getImageData()
per determinare il colore del puntatore.
È possibile estrarre i colori CSS con una regex, e mappare eventuali umani quelli a RGB con ...
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]
});
}
È possibile utilizzare questa piccola funzione JavaScript per interpolare due colori se sono separati in i loro valori RGB.
var getStepColor = function(colorA, colorB, value) {
return colorA.map(function(color, i) {
return (color + value * (colorB[i] - color)) & 255;
});
};
È possibile combinare che per ottenere un codice che vi permetterà di fare questo ...
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.
Questo è solo un modo veloce per ottenere questo, probabilmente c'è un metodo migliore per estrarre i colori e per capire dove si trova il puntatore rispetto a quale segmento di gradiente.
Risposta molto buona e ottimo esempio. Molte grazie. – Zardoz
Nessun problema, grazie per aver fatto una bella domanda. Andrai con questa o una soluzione basata su tela? – alex
Ho due progetti in cui ne ho bisogno. Un progetto utilizza già alcune cose WebGL, quindi un altro canvas lo farà. Per l'altro progetto (senza alcuna tela utilizzata) userò la tua soluzione. – Zardoz