UNPKG

gradient

Version:

A class for generating gradients.

110 lines (94 loc) 3.65 kB
var sets = function(xs) { var loop = function(acc, i) { if (i == xs.length || !xs[i+1]) { return acc; } acc.push([xs[i], xs[i+1]]); return loop(acc, i + 1); } return loop([], 0); }; // ------------------------------------------------------------------------ // var Color = require('color') , Gradient = function(/* [color1, color2, steps] -or- [[array], steps] */) { var args = arguments[0]; this.stops = []; this.steps = 2; // Slice up arguments if (Object.prototype.toString.call(args[0]) === '[object Array]') { for (var i = 0; i < (args[0].length); i++) { this.stops.push(Color(args[0][i])); } this.steps = args[1]; } else { for (var i = 0; i < (args.length - 1); i++) { this.stops.push(Color(args[i])); } this.steps = args[args.length - 1]; } }; (function(obj){ // Build given number of steps, including start and end var buildSteps = function(start, end, span) { var steps = [start]; if (span < 0) { steps.push(end); for (var i = 0; i < Math.abs(span); i++) { steps.pop(); } } else { var base = { h: start.hue(), s: start.saturation(), l: start.lightness(), a: start.alpha() }; var delta = { h: (base.h - end.hue()) / span, s: (base.s - end.saturation()) / span, l: (base.l - end.lightness()) / span, a: (base.a - end.alpha()) / span }; for (var i = 1; i <= span; i++) { var h = base.h - (delta.h * i); var s = base.s - (delta.s * i); var l = base.l - (delta.l * i); var a = base.a - (delta.a * i); // Round out values if (h > 360) { h -= 360; } else if (h < 0) { h += 360; } if (s > 100) { s = 100; } else if (s < 0) { s = 0; } if (l > 100) { l = 100; } else if (l < 0) { l = 0; } if (a > 1) { a = 1; } else if (a < 0) { a = 0; } // Build new color object var c = Color().hue(h).saturation(s).lightness(l).alpha(a); steps.push(c); } steps.push(end); } return steps; }; // To array obj.toArray = function(format) { // Generate gradient steps if (typeof this.__cache === 'undefined') { var stops = this.stops; var steps = this.steps; var overflow = Math.floor(stops.length / 2); var cs = []; sets(stops).forEach(function(x){ // Determine step span for set var span; if (stops.length === 2) { span = steps; } else { span = Math.floor(steps / (stops.length - 1)); if (overflow > 0 && steps % (stops.length - 1) != 0) { span += 1; overflow--; } } // Don't double count the start/end span -= 2; // Generate colors for this set cs = cs.concat(buildSteps(x[0], x[1], span)); }); this.__cache = cs; } // Return in specified format if (typeof format !== 'undefined') { return this.__cache.map(function(x){ return x[format](); }); } else { return this.__cache; } }; }(Gradient.prototype)); module.exports = function() { return new Gradient(Array.prototype.slice.call(arguments,0)); };