tinygradient
Advanced tools
Comparing version
{ | ||
"name": "tinygradient", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"authors": [{ | ||
@@ -5,0 +5,0 @@ "name": "Damien \"Mistic\" Sorel", |
@@ -24,2 +24,22 @@ module.exports = function(grunt) { | ||
} | ||
}, | ||
// jshint tests | ||
jshint: { | ||
lib: { | ||
files: { | ||
src: [ | ||
'tinygradient.js' | ||
] | ||
} | ||
} | ||
}, | ||
// mocha tests | ||
mochaTest: { | ||
unit: { | ||
src: [ | ||
'tests/*.js' | ||
] | ||
} | ||
} | ||
@@ -29,2 +49,4 @@ }); | ||
grunt.loadNpmTasks('grunt-contrib-uglify'); | ||
grunt.loadNpmTasks('grunt-contrib-jshint'); | ||
grunt.loadNpmTasks('grunt-mocha-test'); | ||
@@ -34,2 +56,7 @@ grunt.registerTask('default', [ | ||
]); | ||
grunt.registerTask('test', [ | ||
'mochaTest', | ||
'jshint' | ||
]); | ||
}; |
{ | ||
"name": "tinygradient", | ||
"version": "0.1.0", | ||
"version": "0.2.0", | ||
"authors": [{ | ||
@@ -18,3 +18,4 @@ "name": "Damien \"Mistic\" Sorel", | ||
"grunt-contrib-uglify": "~0.4.0", | ||
"mocha": "~1.20.1" | ||
"grunt-contrib-jshint": "~0.10.0", | ||
"grunt-mocha-test": "~0.11.0" | ||
}, | ||
@@ -33,4 +34,4 @@ "keywords": [ | ||
"scripts": { | ||
"test": "mocha tests/*.js" | ||
"test": "grunt test --force" | ||
} | ||
} |
TinyGradient | ||
============ | ||
## JavaScript color generator | ||
[](http://badge.fury.io/bo/tinygradient) | ||
[](http://badge.fury.io/js/tinygradient) | ||
## JavaScript gradients generator | ||
Easily generate color gradients with unlimited number of color stops and steps. | ||
@@ -14,12 +17,11 @@ | ||
The gradient can be generate using RGB interpolation or HSV interpolation. HSV usually produces brighter colors. | ||
The gradient can be generate using RGB or HSV interpolation. HSV usually produces brighter colors. | ||
### Initialize gradient | ||
The `tinygradient` constructor takes a list or an array of colors steps and a number of steps. | ||
> The generated gradients might have one more step in certain conditions. | ||
The `tinygradient` constructor takes a list or an array of colors stops. | ||
```javascript | ||
// using varargs | ||
var gradient = tinygradient('red', 'green', 'blue', 12); | ||
var gradient = tinygradient('red', 'green', 'blue'); | ||
@@ -31,3 +33,3 @@ // using array | ||
'#0000ff' | ||
], 12); | ||
]); | ||
``` | ||
@@ -44,36 +46,49 @@ | ||
'gold' // named color | ||
], 20); | ||
]); | ||
``` | ||
You can also specify the position of each color stop (between `0` and `1`). If no position is specified, stops are distributed equidistantly. | ||
```javascript | ||
var gradient = tinygradient([ | ||
{color: '#d8e0de', pos: 0}, | ||
{color: '#255B53', pos: 0.8}, | ||
{color: '#000000', pos: 1} | ||
]); | ||
``` | ||
### Generate gradient | ||
Each method takes at least the number of desired steps. | ||
> The generated gradients might have one more step in certain conditions. | ||
```javascript | ||
// RGB interpolation | ||
var colorsRgb = gradient.rgb(); | ||
var colorsRgb = gradient.rgb(9); | ||
``` | ||
 | ||
 | ||
```javascript | ||
// HSV clockwise interpolation | ||
var colorsHsv = gradient.hsv(); | ||
var colorsHsv = gradient.hsv(9); | ||
``` | ||
 | ||
 | ||
```javascript | ||
// HSV counter-clockwise interpolation | ||
var colorsHsv = gradient.hsv(true); | ||
var colorsHsv = gradient.hsv(9, true); | ||
``` | ||
 | ||
 | ||
There are also two methods which will automatically choose between and clockwise and counter-clockwise. | ||
There are also two methods which will automatically choose between clockwise and counter-clockwise. | ||
```javascript | ||
// HSV interpolation using shortest arc between colors | ||
var colorsHsv = gradient.hsv('short'); | ||
var colorsHsv = gradient.hsv(9, 'short'); | ||
// HSV interpolation using longest arc between colors | ||
var colorsHsv = gradient.hsv('long'); | ||
var colorsHsv = gradient.hsv(9, 'long'); | ||
``` | ||
Each function returns an array of TinyColor objects, [see available methods](https://github.com/bgrins/TinyColor/blob/master/README.md#methods). | ||
Each method returns an array of TinyColor objects, [see available methods](https://github.com/bgrins/TinyColor/blob/master/README.md#methods). | ||
@@ -80,0 +95,0 @@ ### Get CSS gradient string |
@@ -6,16 +6,25 @@ var tinygradient = require('../tinygradient.js'), | ||
it('should throw an error on invalid steps/colors number', function() { | ||
assert.throws(function() { tinygradient('red', 2) }); | ||
assert.throws(function() { tinygradient(['red'], 2) }); | ||
assert.throws(function() { tinygradient('red', 'blue', 1) }); | ||
assert.throws(function() { tinygradient('red', 'blue', 'green', 2) }); | ||
assert.throws(function() { | ||
tinygradient('red'); | ||
}); | ||
assert.throws(function() { | ||
tinygradient(['red']); | ||
}); | ||
assert.throws(function() { | ||
var grad = tinygradient('red', 'blue'); | ||
grad.rgb(1); | ||
}); | ||
assert.throws(function() { | ||
var grad = tinygradient('red', 'blue', 'green'); | ||
grad.rgb(2); | ||
}); | ||
}); | ||
it('should accept varargs and array', function() { | ||
var grad1 = tinygradient('red', 'green', 'blue', 'yellow', 'black', 20); | ||
var grad2 = tinygradient(['red', 'green', 'blue', 'yellow', 'black'], 20); | ||
var grad1 = tinygradient('red', 'green', 'blue', 'yellow', 'black'); | ||
var grad2 = tinygradient(['red', 'green', 'blue', 'yellow', 'black']); | ||
assert.equal(grad1.steps, grad2.steps); | ||
assert.deepEqual( | ||
grad1.colors.map(function(c) { return c.toRgb(); }), | ||
grad2.colors.map(function(c) { return c.toRgb(); }) | ||
grad1.stops.map(function(c) { return c.color.toRgb(); }), | ||
grad2.stops.map(function(c) { return c.color.toRgb(); }) | ||
); | ||
@@ -25,4 +34,4 @@ }); | ||
it('should generate 11 steps gradient from black to grey in RGB', function() { | ||
var grad = tinygradient({r:0,g:0,b:0}, {r:100,g:100,b:100}, 11); | ||
var res = grad.rgb(); | ||
var grad = tinygradient({r:0,g:0,b:0}, {r:100,g:100,b:100}); | ||
var res = grad.rgb(11); | ||
@@ -41,4 +50,4 @@ assert.equal(11, res.length); | ||
{h:0,s:1,v:1} | ||
], 13); | ||
var res = grad.hsv(); | ||
]); | ||
var res = grad.hsv(13); | ||
@@ -52,16 +61,10 @@ assert.equal(13, res.length); | ||
it('should generate CSS gradient command for 3 colors', function() { | ||
var grad = tinygradient('#f00', '#0f0', '#00f', 10); | ||
var grad = tinygradient('#f00', '#0f0', '#00f'); | ||
var res = grad.css(); | ||
assert.equal('linear-gradient(to right, rgb(255, 0, 0), rgb(0, 255, 0), rgb(0, 0, 255))', res, 'default'); | ||
assert.equal('linear-gradient(to right, rgb(255, 0, 0) 0%, rgb(0, 255, 0) 50%, rgb(0, 0, 255) 100%)', res, 'default'); | ||
grad = tinygradient('rgba(255,0,0,0.5)', 'rgba(0,255,0,0.5)', 'rgba(0,0,255,0.5)', 10); | ||
grad = tinygradient('rgba(255,0,0,0.5)', 'rgba(0,255,0,0.5)', 'rgba(0,0,255,0.5)'); | ||
res = grad.css('radial', 'ellipse farthest-corner'); | ||
assert.equal('radial-gradient(ellipse farthest-corner, rgba(255, 0, 0, 0.5), rgba(0, 255, 0, 0.5), rgba(0, 0, 255, 0.5))', res, 'radial with alpha'); | ||
assert.equal('radial-gradient(ellipse farthest-corner, rgba(255, 0, 0, 0.5) 0%, rgba(0, 255, 0, 0.5) 50%, rgba(0, 0, 255, 0.5) 100%)', res, 'radial with alpha'); | ||
}); | ||
it('should increase number add on step if necessary', function() { | ||
var grad = tinygradient('#f00', '#0f0', '#00f', 9); | ||
assert.equal(grad.steps, 10); | ||
}); | ||
}); |
@@ -46,3 +46,3 @@ /*! | ||
* @param {Object} step - rgba or hsva from `stepize` | ||
* @param {Object} start - rgba or hsva from `stepize` | ||
* @param {Object} start - rgba or hsva | ||
* @param {Integer} i - color index | ||
@@ -67,11 +67,11 @@ * @param {Object} max - rgba or hsva of maximum values for each channel | ||
* Generate gradient with RGBa interpolation | ||
* @param {tinycolor} color1 | ||
* @param {tinycolor} color2 | ||
* @param {Object} stop1 | ||
* @param {Object} stop2 | ||
* @param {Integer} steps | ||
* @param {tinycolor[]} color1 included, color2 excluded | ||
*/ | ||
rgb: function(color1, color2, steps) { | ||
var start = color1.toRgb(), | ||
end = color2.toRgb(), | ||
gradient = [color1], | ||
rgb: function(stop1, stop2, steps) { | ||
var start = stop1.color.toRgb(), | ||
end = stop2.color.toRgb(), | ||
gradient = [stop1.color], | ||
step = Utils.stepize(start, end, steps), | ||
@@ -90,12 +90,12 @@ color; | ||
* Generate gradient with HSVa interpolation | ||
* @param {tinycolor} color1 | ||
* @param {tinycolor} color2 | ||
* @param {Object} stop1 | ||
* @param {Object} stop2 | ||
* @param {Integer} steps | ||
* @param {Boolean} inverse - true to step in trigonometric order | ||
* @param {Boolean} trigonometric - true to step in trigonometric order | ||
* @param {tinycolor[]} color1 included, color2 excluded | ||
*/ | ||
hsv: function(color1, color2, steps, inverse) { | ||
var start = color1.toHsv(), | ||
end = color2.toHsv(), | ||
gradient = [color1], | ||
hsv: function(stop1, stop2, steps, trigonometric) { | ||
var start = stop1.color.toHsv(), | ||
end = stop2.color.toHsv(), | ||
gradient = [stop1.color], | ||
step = Utils.stepize(start, end, steps), | ||
@@ -105,6 +105,6 @@ diff, color; | ||
// recompute hue | ||
if ((start.h <= end.h && !inverse) || (start.h >= end.h && inverse)) { | ||
if ((start.h <= end.h && !trigonometric) || (start.h >= end.h && trigonometric)) { | ||
diff = end.h-start.h; | ||
} | ||
else if (inverse) { | ||
else if (trigonometric) { | ||
diff = 360-end.h+start.h; | ||
@@ -115,3 +115,3 @@ } | ||
} | ||
step.h = Math.pow(-1, inverse) * Math.abs(diff)*1.0 / steps; | ||
step.h = Math.pow(-1, trigonometric) * Math.abs(diff)*1.0 / steps; | ||
@@ -124,2 +124,45 @@ for (var i=1; i<steps; i++) { | ||
return gradient; | ||
}, | ||
/** | ||
* Compute substeps between each stops | ||
* @param {Object[]} stops | ||
* @param {Integer} steps | ||
* @return {Integer[]} | ||
*/ | ||
substeps: function(stops, steps) { | ||
var l = stops.length; | ||
// validation | ||
steps = parseInt(steps); | ||
if (isNaN(steps) || steps < 2) { | ||
throw new Error('Invalid number of steps (< 2)'); | ||
} | ||
if (steps < l) { | ||
throw new Error('Number of steps cannot be inferior to number of stops'); | ||
} | ||
// compute substeps from stop positions | ||
var substeps = []; | ||
for (var i=1; i<l; i++) { | ||
var step = (steps-1) * (stops[i].pos-stops[i-1].pos); | ||
substeps.push(Math.max(1, Math.round(step))); | ||
} | ||
// adjust number of steps | ||
var totalSubsteps = 1; | ||
for (var n=l-1; n--; ) totalSubsteps+= substeps[n]; | ||
if (totalSubsteps < steps) { | ||
var min = Math.min.apply(null, substeps); | ||
substeps[substeps.indexOf(min)]++; | ||
} | ||
else if (totalSubsteps > steps) { | ||
var max = Math.max.apply(null, substeps); | ||
substeps[substeps.indexOf(max)]--; | ||
} | ||
return substeps; | ||
} | ||
@@ -130,16 +173,14 @@ }; | ||
* @class tinygradient | ||
* @param {...String|...tinycolor|String[]|tinycolor[]} colors | ||
* @param {Integer} steps | ||
* @param {mixed} stops | ||
*/ | ||
var TinyGradient = function(colors, steps) { | ||
var TinyGradient = function(stops) { | ||
// varargs | ||
steps = parseInt(arguments[arguments.length-1]); | ||
if (arguments.length == 2) { | ||
if (arguments.length == 1) { | ||
if (!(arguments[0] instanceof Array)) { | ||
throw new Error('Colors is not an array'); | ||
throw new Error('"stops" is not an array'); | ||
} | ||
colors = arguments[0] | ||
stops = arguments[0]; | ||
} | ||
else { | ||
colors = Array.prototype.slice.call(arguments, 0, -1); | ||
stops = Array.prototype.slice.call(arguments); | ||
} | ||
@@ -149,44 +190,61 @@ | ||
if (!(this instanceof TinyGradient)) { | ||
return new TinyGradient(colors, steps); | ||
return new TinyGradient(stops); | ||
} | ||
// validation | ||
if (steps < 2 || steps == NaN) { | ||
throw new Error('Invalid number of steps (< 2)'); | ||
if (stops.length < 2) { | ||
throw new Error('Invalid number of stops (< 2)'); | ||
} | ||
if (colors.length < 2) { | ||
throw new Error('Invalid number of colors (< 2)'); | ||
} | ||
if (steps < colors.length) { | ||
throw new Error('Number of steps cannot be inferior to number of colors'); | ||
} | ||
this.colors = colors; | ||
this.steps = steps; | ||
this.substeps = []; | ||
var havingPositions = stops[0].pos !== undefined, | ||
l = stops.length, | ||
p = -1; | ||
// create tinycolor objects and clean positions | ||
this.stops = stops.map(function(stop, i) { | ||
var hasPosition = stop.pos !== undefined; | ||
if (havingPositions ^ hasPosition) { | ||
throw new Error('Cannot mix positionned and not posionned color stops'); | ||
} | ||
// create tinycolor objects | ||
this.colors = this.colors.map(function(color) { | ||
return tinycolor(color); | ||
if (hasPosition) { | ||
stop.color = tinycolor(stop.color); | ||
if (stop.pos < 0 || stop.pos > 1) { | ||
throw new Error('Color stops positions must be between 0 and 1'); | ||
} | ||
else if (stop.pos <= p) { | ||
throw new Error('Color stops positions are not ordered'); | ||
} | ||
p = stop.pos; | ||
} | ||
else { | ||
stop = { | ||
color: tinycolor(stop), | ||
pos: i/(l-1) | ||
}; | ||
} | ||
return stop; | ||
}); | ||
// compute substeps | ||
// we need even number of steps if odd number of colors (and reciprocally) | ||
if ((this.colors.length+this.steps)%2 == 0) { | ||
this.steps++; | ||
if (this.stops[0].pos !== 0) { | ||
this.stops.unshift({ | ||
color: this.stops[0].color, | ||
pos: 0 | ||
}); | ||
} | ||
var substep = Math.round(this.steps / (this.colors.length-1)); | ||
for (var i=0, l=this.colors.length; i<l-2; i++) { | ||
this.substeps.push(substep); | ||
if (this.stops[this.stops.length-1].pos !== 1) { | ||
this.stops.push({ | ||
color: this.stops[this.stops.length-1].color, | ||
pos: 1 | ||
}); | ||
} | ||
this.substeps.push(this.steps - substep * (l-2) - 1); | ||
}; | ||
/** | ||
* Return new instance with reversed colors | ||
* Return new instance with reversed stops | ||
* @return {tinygradient} | ||
*/ | ||
TinyGradient.prototype.reverse = function() { | ||
return new TinyGradient(this.colors.reverse(), this.steps); | ||
return new TinyGradient(this.stops.reverse()); | ||
}; | ||
@@ -196,12 +254,14 @@ | ||
* Generate gradient with RGBa interpolation | ||
* @param {Integer} steps | ||
* @return {tinycolor[]} | ||
*/ | ||
TinyGradient.prototype.rgb = function() { | ||
var gradient = []; | ||
TinyGradient.prototype.rgb = function(steps) { | ||
var substeps = Utils.substeps(this.stops, steps), | ||
gradient = []; | ||
for (var i=0, l=this.colors.length; i<l-1; i++) { | ||
gradient = gradient.concat(Utils.rgb(this.colors[i], this.colors[i+1], this.substeps[i])); | ||
for (var i=0, l=this.stops.length; i<l-1; i++) { | ||
gradient = gradient.concat(Utils.rgb(this.stops[i], this.stops[i+1], substeps[i])); | ||
} | ||
gradient.push(this.colors[l-1]); | ||
gradient.push(this.stops[l-1].color); | ||
@@ -213,4 +273,5 @@ return gradient; | ||
* Generate gradient with HSVa interpolation | ||
* @param {Boolean|String} mode | ||
* - false (default) to step in clockwise | ||
* @param {Integer} steps | ||
* @param {Boolean|String} [mode=false] | ||
* - false to step in clockwise | ||
* - true to step in trigonometric order | ||
@@ -221,4 +282,5 @@ * - 'short' to use the shortest way | ||
*/ | ||
TinyGradient.prototype.hsv = function(mode) { | ||
var inverse = !!mode, | ||
TinyGradient.prototype.hsv = function(steps, mode) { | ||
var substeps = Utils.substeps(this.stops, steps), | ||
trigonometric = mode === true, | ||
parametrized = typeof mode === 'string', | ||
@@ -228,15 +290,22 @@ gradient = [], | ||
for (var i=0, l=this.colors.length; i<l-1; i++) { | ||
for (var i=0, l=this.stops.length; i<l-1; i++) { | ||
start = this.stops[i].color.toHsv(); | ||
end = this.stops[i+1].color.toHsv(); | ||
if (parametrized) { | ||
start = this.colors[i].toHsv(); | ||
end = this.colors[i+1].toHsv(); | ||
trig = (start.h < end.h && end.h-start.h < 180) || (start.h > end.h && start.h-end.h > 180); | ||
} | ||
gradient = gradient.concat(Utils.hsv(this.colors[i], this.colors[i+1], this.substeps[i], | ||
(parametrized && mode=='long' && trig) ||(parametrized && mode=='short' && !trig) || (!parametrized && inverse) | ||
)); | ||
// rgb interpolation if one of the steps in grayscale | ||
if (start.s===0 || end.s===0) { | ||
gradient = gradient.concat(Utils.rgb(this.stops[i], this.stops[i+1], substeps[i])); | ||
} | ||
else { | ||
gradient = gradient.concat(Utils.hsv(this.stops[i], this.stops[i+1], substeps[i], | ||
(mode==='long' && trig) || (mode==='short' && !trig) || (!parametrized && trigonometric) | ||
)); | ||
} | ||
} | ||
gradient.push(this.colors[l-1]); | ||
gradient.push(this.stops[l-1].color); | ||
@@ -257,4 +326,4 @@ return gradient; | ||
var css = mode + '-gradient(' + direction; | ||
this.colors.forEach(function(color) { | ||
css+= ', ' + color.toRgbString(); | ||
this.stops.forEach(function(stop) { | ||
css+= ', ' + stop.color.toRgbString() + ' ' + (stop.pos*100) + '%'; | ||
}); | ||
@@ -267,3 +336,3 @@ css+= ')'; | ||
// export | ||
return TinyGradient | ||
return TinyGradient; | ||
})); |
/*! | ||
* jQuery TinyGradient 0.1.0 | ||
* jQuery TinyGradient 0.2.0 | ||
* Copyright 2014 Damien "Mistic" Sorel (http://www.strangeplanet.fr) | ||
* Licensed under MIT (http://opensource.org/licenses/MIT) | ||
*/ | ||
!function(a,b){"undefined"!=typeof module&&module.exports?module.exports=b(require("tinycolor2")):"function"==typeof define&&define.amd?define(["tinycolor"],b):a.tinygradient=b(a.tinycolor)}(this,function(a){"use strict";var b={rgba_max:{r:256,g:256,b:256,a:1},hsva_max:{h:360,s:1,v:1,a:1},stepize:function(a,b,c){var d={};for(var e in a)a.hasOwnProperty(e)&&(d[e]=(b[e]-a[e])/c);return d},interpolate:function(a,b,c,d){var e={};for(var f in b)b.hasOwnProperty(f)&&(e[f]=a[f]*c+b[f],e[f]=e[f]<0?e[f]+d[f]:1!=d[f]?e[f]%d[f]:e[f]);return e},rgb:function(c,d,e){for(var f,g=c.toRgb(),h=d.toRgb(),i=[c],j=b.stepize(g,h,e),k=1;e>k;k++)f=b.interpolate(j,g,k,b.rgba_max),i.push(a(f));return i},hsv:function(c,d,e,f){var g,h,i=c.toHsv(),j=d.toHsv(),k=[c],l=b.stepize(i,j,e);g=i.h<=j.h&&!f||i.h>=j.h&&f?j.h-i.h:f?360-j.h+i.h:360-i.h+j.h,l.h=Math.pow(-1,f)*Math.abs(g)*1/e;for(var m=1;e>m;m++)h=b.interpolate(l,i,m,b.hsva_max),k.push(a(h));return k}},c=function(b,d){if(d=parseInt(arguments[arguments.length-1]),2==arguments.length){if(!(arguments[0]instanceof Array))throw new Error("Colors is not an array");b=arguments[0]}else b=Array.prototype.slice.call(arguments,0,-1);if(!(this instanceof c))return new c(b,d);if(2>d||0/0==d)throw new Error("Invalid number of steps (< 2)");if(b.length<2)throw new Error("Invalid number of colors (< 2)");if(d<b.length)throw new Error("Number of steps cannot be inferior to number of colors");this.colors=b,this.steps=d,this.substeps=[],this.colors=this.colors.map(function(b){return a(b)}),(this.colors.length+this.steps)%2==0&&this.steps++;for(var e=Math.round(this.steps/(this.colors.length-1)),f=0,g=this.colors.length;g-2>f;f++)this.substeps.push(e);this.substeps.push(this.steps-e*(g-2)-1)};return c.prototype.reverse=function(){return new c(this.colors.reverse(),this.steps)},c.prototype.rgb=function(){for(var a=[],c=0,d=this.colors.length;d-1>c;c++)a=a.concat(b.rgb(this.colors[c],this.colors[c+1],this.substeps[c]));return a.push(this.colors[d-1]),a},c.prototype.hsv=function(a){for(var c,d,e,f=!!a,g="string"==typeof a,h=[],i=0,j=this.colors.length;j-1>i;i++)g&&(c=this.colors[i].toHsv(),d=this.colors[i+1].toHsv(),e=c.h<d.h&&d.h-c.h<180||c.h>d.h&&c.h-d.h>180),h=h.concat(b.hsv(this.colors[i],this.colors[i+1],this.substeps[i],g&&"long"==a&&e||g&&"short"==a&&!e||!g&&f));return h.push(this.colors[j-1]),h},c.prototype.css=function(a,b){a=a||"linear",b=b||("linear"==a?"to right":"ellipse at center");var c=a+"-gradient("+b;return this.colors.forEach(function(a){c+=", "+a.toRgbString()}),c+=")"},c}); | ||
!function(a,b){"undefined"!=typeof module&&module.exports?module.exports=b(require("tinycolor2")):"function"==typeof define&&define.amd?define(["tinycolor"],b):a.tinygradient=b(a.tinycolor)}(this,function(a){"use strict";var b={rgba_max:{r:256,g:256,b:256,a:1},hsva_max:{h:360,s:1,v:1,a:1},stepize:function(a,b,c){var d={};for(var e in a)a.hasOwnProperty(e)&&(d[e]=(b[e]-a[e])/c);return d},interpolate:function(a,b,c,d){var e={};for(var f in b)b.hasOwnProperty(f)&&(e[f]=a[f]*c+b[f],e[f]=e[f]<0?e[f]+d[f]:1!=d[f]?e[f]%d[f]:e[f]);return e},rgb:function(c,d,e){for(var f,g=c.color.toRgb(),h=d.color.toRgb(),i=[c.color],j=b.stepize(g,h,e),k=1;e>k;k++)f=b.interpolate(j,g,k,b.rgba_max),i.push(a(f));return i},hsv:function(c,d,e,f){var g,h,i=c.color.toHsv(),j=d.color.toHsv(),k=[c.color],l=b.stepize(i,j,e);g=i.h<=j.h&&!f||i.h>=j.h&&f?j.h-i.h:f?360-j.h+i.h:360-i.h+j.h,l.h=Math.pow(-1,f)*Math.abs(g)*1/e;for(var m=1;e>m;m++)h=b.interpolate(l,i,m,b.hsva_max),k.push(a(h));return k},substeps:function(a,b){var c=a.length;if(b=parseInt(b),isNaN(b)||2>b)throw new Error("Invalid number of steps (< 2)");if(c>b)throw new Error("Number of steps cannot be inferior to number of stops");for(var d=[],e=1;c>e;e++){var f=(b-1)*(a[e].pos-a[e-1].pos);d.push(Math.max(1,Math.round(f)))}for(var g=1,h=c-1;h--;)g+=d[h];if(b>g){var i=Math.min.apply(null,d);d[d.indexOf(i)]++}else if(g>b){var j=Math.max.apply(null,d);d[d.indexOf(j)]--}return d}},c=function(b){if(1==arguments.length){if(!(arguments[0]instanceof Array))throw new Error('"stops" is not an array');b=arguments[0]}else b=Array.prototype.slice.call(arguments);if(!(this instanceof c))return new c(b);if(b.length<2)throw new Error("Invalid number of stops (< 2)");var d=void 0!==b[0].pos,e=b.length,f=-1;this.stops=b.map(function(b,c){var g=void 0!==b.pos;if(d^g)throw new Error("Cannot mix positionned and not posionned color stops");if(g){if(b.color=a(b.color),b.pos<0||b.pos>1)throw new Error("Color stops positions must be between 0 and 1");if(b.pos<=f)throw new Error("Color stops positions are not ordered");f=b.pos}else b={color:a(b),pos:c/(e-1)};return b}),0!==this.stops[0].pos&&this.stops.unshift({color:this.stops[0].color,pos:0}),1!==this.stops[this.stops.length-1].pos&&this.stops.push({color:this.stops[this.stops.length-1].color,pos:1})};return c.prototype.reverse=function(){return new c(this.stops.reverse())},c.prototype.rgb=function(a){for(var c=b.substeps(this.stops,a),d=[],e=0,f=this.stops.length;f-1>e;e++)d=d.concat(b.rgb(this.stops[e],this.stops[e+1],c[e]));return d.push(this.stops[f-1].color),d},c.prototype.hsv=function(a,c){for(var d,e,f,g=b.substeps(this.stops,a),h=c===!0,i="string"==typeof c,j=[],k=0,l=this.stops.length;l-1>k;k++)d=this.stops[k].color.toHsv(),e=this.stops[k+1].color.toHsv(),i&&(f=d.h<e.h&&e.h-d.h<180||d.h>e.h&&d.h-e.h>180),j=j.concat(0===d.s||0===e.s?b.rgb(this.stops[k],this.stops[k+1],g[k]):b.hsv(this.stops[k],this.stops[k+1],g[k],"long"===c&&f||"short"===c&&!f||!i&&h));return j.push(this.stops[l-1].color),j},c.prototype.css=function(a,b){a=a||"linear",b=b||("linear"==a?"to right":"ellipse at center");var c=a+"-gradient("+b;return this.stops.forEach(function(a){c+=", "+a.color.toRgbString()+" "+100*a.pos+"%"}),c+=")"},c}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
27765
16.81%447
24.51%120
14.29%4
33.33%