Last active
April 5, 2019 11:09
-
-
Save siamak/aa1097e7f13c7544b0bc718bebc8a721 to your computer and use it in GitHub Desktop.
Steps in Gradient
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* GradientArray • Steps gradient. | |
* @author Siamak Mokhtari <[email protected]> | |
* @date 06/21/16. | |
*/ | |
class GradientArray { | |
// Convert a hex color to an RGB array e.g. [r,g,b] | |
// Accepts the following formats: FFF, FFFFFF, #FFF, #FFFFFF | |
hexToRgb(hex) { | |
let r, g, b, parts; | |
// Remove the hash if given | |
hex = hex.replace('#', ''); | |
// If invalid code given return white | |
if(hex.length !== 3 && hex.length !== 6){ | |
return [255,255,255]; | |
} | |
// Double up charaters if only three suplied | |
if(hex.length == 3){ | |
hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]; | |
} | |
// Convert to [r,g,b] array | |
r = parseInt(hex.substr(0, 2), 16); | |
g = parseInt(hex.substr(2, 2), 16); | |
b = parseInt(hex.substr(4, 2), 16); | |
return [r, g, b]; | |
} | |
// Converts an RGB color array e.g. [255,255,255] into a hexidecimal color value e.g. 'FFFFFF' | |
rgbToHex(color) { | |
// Set boundries of upper 255 and lower 0 | |
color[0] = (color[0] > 255) ? 255 : (color[0] < 0) ? 0 : color[0]; | |
color[1] = (color[1] > 255) ? 255 : (color[1] < 0) ? 0 : color[1]; | |
color[2] = (color[2] > 255) ? 255 : (color[2] < 0) ? 0 : color[2]; | |
return this.zeroFill(color[0].toString(16), 2) + this.zeroFill(color[1].toString(16), 2) + this.zeroFill(color[2].toString(16), 2); | |
} | |
// Pads a number with specified number of leading zeroes | |
zeroFill(number, width) { | |
width -= number.toString().length; | |
if (width > 0){ | |
return [width + (/\./.test(number) ? 2 : 1)].join('0') + number; | |
} | |
return number; | |
} | |
// Generates an array of color values in sequence from 'colorA' to 'colorB' using the specified number of steps | |
generateGradient(colorA, colorB, steps) { | |
const result = []; | |
let rInterval; | |
let gInterval; | |
let bInterval; | |
colorA = this.hexToRgb(colorA); // [r,g,b] | |
colorB = this.hexToRgb(colorB); // [r,g,b] | |
steps -= 1; // Reduce the steps by one because we're including the first item manually | |
// Calculate the intervals for each color | |
let rStep = (Math.max(colorA[0], colorB[0]) - Math.min(colorA[0], colorB[0])) / steps; | |
let gStep = (Math.max(colorA[1], colorB[1]) - Math.min(colorA[1], colorB[1])) / steps; | |
let bStep = (Math.max(colorA[2], colorB[2]) - Math.min(colorA[2], colorB[2])) / steps; | |
result.push(`#${this.rgbToHex(colorA)}`); | |
// Set the starting value as the first color value | |
let rVal = colorA[0], gVal = colorA[1], bVal = colorA[2]; | |
// Loop over the steps-1 because we're includeing the last value manually to ensure it's accurate | |
for (let i = 0; i < (steps-1); i++) { | |
// If the first value is lower than the last - increment up otherwise increment down | |
rVal = (colorA[0] < colorB[0]) ? rVal + Math.round(rStep) : rVal - Math.round(rStep); | |
gVal = (colorA[1] < colorB[1]) ? gVal + Math.round(gStep) : gVal - Math.round(gStep); | |
bVal = (colorA[2] < colorB[2]) ? bVal + Math.round(bStep) : bVal - Math.round(bStep); | |
result.push(`#${this.rgbToHex([rVal, gVal, bVal])}`); | |
} | |
result.push(`#${this.rgbToHex(colorB)}`); | |
return result; | |
} | |
gradientList(colorA, colorB, steps) { | |
const colorArray = this.generateGradient(colorA, colorB, steps); | |
for(let i in colorArray) { | |
console.log(colorArray[i]); | |
} | |
} | |
} | |
/** | |
* Colors extends from GradientArray | |
*/ | |
let colors = new GradientArray(); | |
/** | |
* Step by Step | |
* @param {String} "#FFF" | |
* @param {String} "#000" | |
* @param {Integer} 10 | |
*/ | |
colors.gradientList("#23e", "#111", 20); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi, I've noticed a mistake in your code. If the step is small than 0.5, your color value will not increase.
Instead use something like this (I changed the output to RGB):
generateGradient(colorA, colorB, steps) {
let result = [];
let rInterval;
let gInterval;
let bInterval;
colorA = hexToRgbArray(colorA); // [r,g,b]
colorB = hexToRgbArray(colorB); // [r,g,b]
steps = steps - 1; // we begin at zero
// Calculate the intervals for each color
let rStep = (colorB[0] - colorA[0]) / steps;
let gStep = (colorB[1] - colorA[1]) / steps;
let bStep = (colorB[2] - colorA[2]) / steps;
// Set the starting value as the first color value
let rVal = colorA[0], gVal = colorA[1], bVal = colorA[2];
for (let i = 0; i <= steps; i++) {
rVal = Math.round(colorA[0] + (rStep * i));
gVal = Math.round(colorA[1] + (gStep * i));
bVal = Math.round(colorA[2] + (bStep * i));
result.push(
rgb(${rVal}, ${gVal}, ${bVal})
);}
return result;
}