Skip to content

Instantly share code, notes, and snippets.

@lelandbatey
Created March 11, 2019 23:15
Show Gist options
  • Save lelandbatey/2599ac2314da478afc2a0885e200be95 to your computer and use it in GitHub Desktop.
Save lelandbatey/2599ac2314da478afc2a0885e200be95 to your computer and use it in GitHub Desktop.
A demonstration of the importance of correct RGB color interpolation
<!DOCTYPE html>
<html lang="en">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<body style="margin: 0;">
<div>
<canvas id='canvas1' width='800' height='200'></canvas>
</div>
<div>
<canvas id='canvas2' width='800' height='200'></canvas>
</div>
<div>
<canvas id='canvas3' width='800' height='200'></canvas>
</div>
</body>
<script>
// To run, download this file and serve it via some http server; I prefer
// `python -m SimpleHTTPServer` in this directory. Then you'd access
// `http://localhost:8000/` in your web browser.
/// Assumes an input string of "#ABCDEF"
function hex_to_rgb(hex) {
return [Number.parseInt(hex.slice(1, 3), 16), Number.parseInt(hex.slice(3, 5), 16), Number.parseInt(hex.slice(5, 7), 16)];
}
/// [255, 255, 255] -> "#FFFFFF"
function rgb_to_hex(rgb) {
var hex = "#";
for (var i = 0; i < rgb.length; i++) {
hex = hex + rgb[i].toString(16).padStart(2, '0');
}
return hex;
}
function _blend_colors(c1, c2, t, blendChannel) {
if (typeof c1 === 'string') {
c1 = hex_to_rgb(c1);
c2 = hex_to_rgb(c2);
}
let nc = [0, 0, 0];
for (var i = 0; i<3; i++) {
nc[i] = blendChannel(c1[i], c2[i], t);
}
return nc;
}
function blend_multi_colors(colors, t, blendChannel) {
let n = 1/(colors.length-1);
let tween_color_span = t/n % 1;
let c_strt_idx = Math.floor(t/n);
let c1 = colors[c_strt_idx];
let c2 = colors[c_strt_idx+1];
return _blend_colors(c1, c2, tween_color_span, blendChannel);
}
function blend_colors(colors, t) {
let blendChannel = (a, b, x) => {
return Math.sqrt((1-x) * Math.pow(a, 2) + x * Math.pow(b, 2));
}
return blend_multi_colors(colors, t, blendChannel);
}
function bad_blend(colors, t) {
let bc = (a, b, x) => {
return a + x * (b - a);
}
return blend_multi_colors(colors, t, bc);
}
function draw_gradient(canv, colorFunc, colors) {
var context = canv.getContext('2d');
context.fillStyle = 'grey';
context.fillRect(0, 0, canv.width, canv.height);
for (var x = 0; x < canv.width; x++) {
let colColor = colorFunc(colors, x/canv.width);
for (var y = 0; y < canv.height; y++) {
context.fillStyle = `rgba(${colColor[0]}, ${colColor[1]}, ${colColor[2]}, 1)`;
context.fillRect(x, y, 1, 1);
}
}
}
$(document).ready(() => {
var canv = document.getElementById('canvas1');
//let colors = ["#FF0000", "#00FF00", "#0000FF"];
// let colors = ["#49C209", "#312077", "#CD252B"];
let colors = ["#49C209", "#312077"];
draw_gradient(document.getElementById('canvas1'), blend_colors, colors);
draw_gradient(document.getElementById('canvas2'), bad_blend, colors);
});
</script>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment