Skip to content

Instantly share code, notes, and snippets.

@rmkane
Last active October 8, 2015 22:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmkane/b285ad9d17ef7c9df1bb to your computer and use it in GitHub Desktop.
Save rmkane/b285ad9d17ef7c9df1bb to your computer and use it in GitHub Desktop.
Gradient Generator

Gradient generator using color interpolation.

function decToHex(dec) {
return (function (hex) {
return hex.length == 1 ? "0" + hex : hex;
})(dec.toString(16));
}
function hexToRgb(hex) {
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
if (result) {
return {
r: parseInt(result[1], 16),
g: parseInt(result[2], 16),
b: parseInt(result[3], 16)
}
}
result = /^#?([a-f\d])([a-f\d])([a-f\d])$/i.exec(hex);
return result ? {
r: parseInt(result[1], 16) << 4,
g: parseInt(result[2], 16) << 4,
b: parseInt(result[3], 16) << 4
} : 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 "#" + decToHex(r) + decToHex(g) + decToHex(b);
}
function render(canvas, colors) {
var ctx = canvas.getContext("2d"),
n = colors.length,
r = canvas.width % n,
a = Math.floor(r / 2),
b = n - r + a,
subWidth = Math.floor(canvas.width / n) + 1,
start = 0;
for (var i = 0; i < n; i++) {
if (i == a) {
subWidth -= 1;
}
if (i == b) {
subWidth += 1;
}
ctx.fillStyle = colors[i];
ctx.fillRect(start, 0, subWidth, canvas.height);
start += subWidth;
}
}
function render2(canvas, colors) {
var ctx = canvas.getContext("2d"),
x = canvas.x,
y = canvas.y,
width = canvas.width,
height = canvas.height;
ctx.fillStyle = createGradient(ctx, colors, x, y, width, height)
ctx.fillRect(0, 0, width, height);
}
function magnitude(a, b) {
if (a === b) return 0;
else if (a > b) return -1 * (a - b);
else return b - a;
}
function lerp(c1, c2, w) {
return Math.floor(c1 + (magnitude(c1, c2) * w));
}
function interpolate(color1, color2, r, g, b) {
if (arguments.length == 3) {
g = r;
b = r;
}
return rgbToHex({
r: lerp(color1.r, color2.r, r),
g: lerp(color1.g, color2.g, g),
b: lerp(color1.b, color2.b, b)
});
}
function generateColorsBetween(c1, c2, n) {
if (n === 1) {
return [rgbToHex(c1)];
}
var stops = [];
for (var i = 0; i < n; i++) {
stops.push(interpolate(c1, c2, i / (n - 1)));
}
return stops;
}
function generateColors(colors, n) {
if (colors.length === 1) {
return colors[0];
} else if (colors.length === 2) {
return generateColorsBetween(
hexToRgb(colors[0]), hexToRgb(colors[1]), n);
}
var stops = [],
pct = (colors.length - 1) / (n - 1);
for (var i = 0; i < n; i++) {
var p = n == 1 ? 0 : i * pct;
if (p % 1 === 0) {
stops.push(colors[p]);
} else {
var p1 = Math.floor(p),
p2 = Math.ceil(p),
c1 = hexToRgb(colors[p1]),
c2 = hexToRgb(colors[p2]);
stops.push(interpolate(c1, c2, p - p1));
}
}
return stops;
}
function createGradient(ctx, colors, x, y, width, height) {
var h = height / 2,
grd = ctx.createLinearGradient(0, h, width, h),
n = Math.max(colors.length - 1, 1);
for (var i = 0; i < colors.length; i++) {
grd.addColorStop(i / n, colors[i]);
}
return grd;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<style type="text/css">
canvas {
display: block;
margin: 0;
padding: 0;
}
</style>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
<script type="text/javascript" src="GradientGeneratorLib.js"></script>
<script type="text/javascript">
$(function() {
function addCanvas() {
return $('<canvas>', {
width: 320,
height: 10
}).appendTo($('body'))[0];
}
function renderGradients(colors, n) {
for (var i = 1; i <= n; i += 1) {
render(addCanvas(), generateColors(colors, i));
}
render2(addCanvas(), colors);
}
renderGradients(['#F08', '#FF0', '#1F2', '#07D'], 40);
});
</script>
</head>
<body></body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment