Gradients 6, 7, 8 and 10 have visible gaps just after their initial color. Is there a way to fill that gap in?
I assume that once the range is partitioned, the sum of the integer partitions is less than the original if they are not divisible by the width of the canvas.
Info
render1()
- Interpolates values by generating a range of colors between two colors.render2()
- JavaScript'screateLinearGradient()
with n-number of even stops.
$(document).ready(function () {
function addCanvas(ol) {
var canvas = $('<canvas>', {
"width": 240,
"height": 10
}).addClass('grd')
.appendTo($('<li>').appendTo(ol));
return canvas[0];
}
var ol = $('<ol>').appendTo($('body'));
var c1 = '#FF0000';
var c2 = '#00FF00';
var canvas;
for (var i = 1; i <= 30; i+=3) {
canvas = addCanvas(ol);
var colors = generateColors(c1, c2, i);
render(canvas, colors);
}
canvas = addCanvas(ol);
render2(canvas, [c1, c2]);
});
function toHex(c) {
return (function (hex) {
return hex.length == 1 ? "0" + hex : hex;
})(c.toString(16));
}
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
} : null;
}
function rgbToHex(rgb) {
var r = 0,
g = 0,
b = 0;
if (arguments.length === 1) {
r = rgb.r || 0;
g = rgb.g || 0;
b = rgb.b || 0;
} else if (arguments.length === 3) {
r = arguments[0];
g = arguments[1];
b = arguments[2];
}
return "#" + toHex(r) + toHex(g) + toHex(b);
}
function render(canvas, colors) {
var ctx = canvas.getContext("2d");
var n = colors.length;
var x = 0;
var subWidth = canvas.width / n;
for (var i = 0; i < n; i++) {
var start = i * subWidth;
var end = start + subWidth;
ctx.fillStyle = colors[i];
ctx.fillRect(x + start, 0, x + end, canvas.height);
}
}
function render2(canvas, colors) {
var ctx = canvas.getContext("2d");
var x = canvas.x;
var y = canvas.y;
var width = canvas.width;
var height = canvas.height;
ctx.fillStyle = createGradient(ctx, colors, x, y, width, height)
ctx.fillRect(0, 0, width, height);
}
function generateColors(color1, color2, n) {
function partition(a, b, n) {
function magnitude(a, b) {
if (a === b) return 0;
else if (a > b) return -1 * (a - b);
else return b - a;
}
return magnitude(a, b) / n;
}
var c1 = hexToRgb(color1);
var c2 = hexToRgb(color2);
var rd = partition(c1.r, c2.r, n);
var gd = partition(c1.g, c2.g, n);
var bd = partition(c1.b, c2.b, n);
var colors = [];
var i, r, g, b, h = n/2;
for (i = 0; i < h; i++) {
r = Math.floor(c1.r + rd * i);
g = Math.floor(c1.g + gd * i);
b = Math.floor(c1.b + bd * i);
colors.push(rgbToHex(r, g, b));
}
for (var j = 0; i < n; j++, i++) {
var k = h-j-1;
r = Math.floor(c2.r - rd * k);
g = Math.floor(c2.g - gd * k);
b = Math.floor(c2.b - bd * k);
colors.push(rgbToHex(r, g, b));
}
return colors;
}
function createGradient(ctx, colors, x, y, width, height) {
var h = height / 2;
var grd = ctx.createLinearGradient(0, h, width, h);
var n = Math.max(colors.length - 1, 1);
for (var i = 0; i < colors.length; i++) {
grd.addColorStop(i / n, colors[i]);
}
return grd;
}
canvas.grd {
display: inline-block;
margin: 1px 0;
}
ol {
padding-left: 32px;
list-style-type:decimal;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>