Skip to content

Commit

Permalink
add adjustment functions
Browse files Browse the repository at this point in the history
  • Loading branch information
meodai committed Jan 20, 2024
1 parent 3aaa5ff commit ca916e8
Show file tree
Hide file tree
Showing 10 changed files with 131 additions and 35 deletions.
22 changes: 17 additions & 5 deletions dist/index.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,23 @@ __export(exports, {
colorToCSS: () => colorToCSS,
generateColorRamp: () => generateColorRamp,
generateColorRampParams: () => generateColorRampParams,
harveyHue: () => harveyHue,
lerp: () => lerp,
scaleSpreadArray: () => scaleSpreadArray,
shuffleArray: () => shuffleArray,
uniqueRandomHues: () => uniqueRandomHues
});
function harveyHue(h) {
if (h === 1 || h === 0)
return h;
h = 1 + h % 1;
const seg = 1 / 6;
const a = h % seg / seg * Math.PI / 2;
const [b, c] = [seg * Math.cos(a), seg * Math.sin(a)];
const i = Math.floor(h * 6);
const cases = [c, 1 / 3 - b, 1 / 3 + c, 2 / 3 - b, 2 / 3 + c, 1 - b];
return cases[i % 6];
}
function generateColorRamp({
total = 9,
hStart = Math.random() * 360,
Expand All @@ -27,6 +39,7 @@ function generateColorRamp({
sEasing = (x) => Math.pow(x, 2),
lRange = [Math.random() * 0.1, 0.9],
lEasing = (x) => Math.pow(x, 1.5),
adjustmentsFn = ([h, s, l]) => [h, s, l],
hueList
} = {}) {
const lDiff = lRange[1] - lRange[0];
Expand All @@ -35,11 +48,10 @@ function generateColorRamp({
return Array.from({ length }, (_, i) => {
const relI = i / (length - 1);
const fraction = 1 / length;
return [
hueList ? hueList[i] : (360 + hStart + (1 - hEasing(relI, fraction) - hStartCenter) * (360 * hCycles)) % 360,
sRange[0] + sDiff * sEasing(relI, fraction),
lRange[0] + lDiff * lEasing(relI, fraction)
];
const hue = hueList ? hueList[i] : (360 + hStart + (1 - hEasing(relI, fraction) - hStartCenter) * (360 * hCycles)) % 360;
const saturation = sRange[0] + sDiff * sEasing(relI, fraction);
const lightness = lRange[0] + lDiff * lEasing(relI, fraction);
return adjustmentsFn([hue, saturation, lightness]);
});
}
function shuffleArray(array, rndFn = Math.random) {
Expand Down
10 changes: 9 additions & 1 deletion dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,25 @@ export declare type lightnessArguments = {
};
declare type BaseGenerateColorRampArgument = {
total?: number;
adjustmentsFn?: (hsl: Vector3) => Vector3;
} & hueArguments & saturationArguments & lightnessArguments;
export declare type GenerateColorRampArgument = BaseGenerateColorRampArgument & {
hueList?: never;
};
export declare type GenerateColorRampArgumentFixedHues = BaseGenerateColorRampArgument & presetHues;
/**
* Get a more evenly distributed spectrum without the over abundance of green and ultramarine
* https://twitter.com/harvey_rayner/status/1748159440010809665
* @param h
* @returns h
*/
export declare function harveyHue(h: number): number;
/**
* Generates a color ramp based on the HSL color space.
* @param {GenerateColorRampArgument} args - The arguments to generate the ramp.
* @returns {Array<number>} - The color ramp.
*/
export declare function generateColorRamp({ total, hStart, hStartCenter, hEasing, hCycles, sRange, sEasing, lRange, lEasing, hueList, }?: GenerateColorRampArgument | GenerateColorRampArgumentFixedHues): Vector3[];
export declare function generateColorRamp({ total, hStart, hStartCenter, hEasing, hCycles, sRange, sEasing, lRange, lEasing, adjustmentsFn, hueList, }?: GenerateColorRampArgument | GenerateColorRampArgumentFixedHues): Vector3[];
/**
* shuffles an array in place using the Fisher-Yates algorithm.
* @param {Array} array - The array to shuffle.
Expand Down
18 changes: 17 additions & 1 deletion dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -1152,6 +1152,7 @@ <h2>Color Properties</h2>
colorHarmonies,
scaleSpreadArray,
colorToCSS,
harveyHue,
} from "./index.mjs";

console.clear();
Expand Down Expand Up @@ -1218,8 +1219,15 @@ <h2>Color Properties</h2>
relativeRandom50: (x, fr) => x + (-fr + Math.random() * fr * 2) * .5,
random: x => Math.random(),
};

const adjustmentFunctions = {
none: (hsl) => hsl,
harveyHue: ([h,s,l]) => [harveyHue(h/360) * 360, s, l],
muted: ([h,s,l]) => [h, s * .5, l],
};

const easingFunctionsKeys = Object.keys(easingFunctions);
const adjustmentFunctionsKeys = Object.keys(adjustmentFunctions);

const newOptions = (overwrites = {}) => {
const lPow = .1 + Math.random() * .9;
Expand All @@ -1242,6 +1250,7 @@ <h2>Color Properties</h2>
Math.pow(1 - Math.random() * .15, lPow)
],
lEasing: easingFunctions['easeInOutSine'],
adjustmentsFn: adjustmentFunctions['none'],
}, ...overwrites};
};

Expand Down Expand Up @@ -1534,6 +1543,12 @@ <h2>Color Properties</h2>
options: easingFunctionsKeys
},
},
adjustmentsFn: {
default: 'none',
props: {
options: adjustmentFunctionsKeys
},
},
};

Object.keys(defaultParams).forEach((key) => {
Expand All @@ -1554,6 +1569,7 @@ <h2>Color Properties</h2>
hueList,
sRange: [PARAMS.minSaturation, PARAMS.maxSaturation],
lRange: [PARAMS.minLight, PARAMS.maxLight],
adjustmentsFn: adjustmentFunctions[PARAMS.adjustmentsFn],
}));

colors = hslToColorObj(colors)
Expand Down Expand Up @@ -1745,7 +1761,6 @@ <h2>Color Properties</h2>
hueList = uniqueRandomHues({
startHue: PARAMS.hStart,
total: totalRandomHues,
minDistance: PARAMS.hMinDiffAngle,
});
}

Expand All @@ -1766,6 +1781,7 @@ <h2>Color Properties</h2>
lRange: [PARAMS.minLight, PARAMS.maxLight],
lEasing: typeof PARAMS.lEasing === 'string' ? easingFunctions[PARAMS.lEasing] : PARAMS.lEasing,
hueList: hueList,
adjustmentsFn: adjustmentFunctions[PARAMS.adjustmentsFn],
});

document.documentElement.style.setProperty('--total', colors.length);
Expand Down
22 changes: 17 additions & 5 deletions dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,23 @@ var rampensau = (() => {
colorToCSS: () => colorToCSS,
generateColorRamp: () => generateColorRamp,
generateColorRampParams: () => generateColorRampParams,
harveyHue: () => harveyHue,
lerp: () => lerp,
scaleSpreadArray: () => scaleSpreadArray,
shuffleArray: () => shuffleArray,
uniqueRandomHues: () => uniqueRandomHues
});
function harveyHue(h) {
if (h === 1 || h === 0)
return h;
h = 1 + h % 1;
const seg = 1 / 6;
const a = h % seg / seg * Math.PI / 2;
const [b, c] = [seg * Math.cos(a), seg * Math.sin(a)];
const i = Math.floor(h * 6);
const cases = [c, 1 / 3 - b, 1 / 3 + c, 2 / 3 - b, 2 / 3 + c, 1 - b];
return cases[i % 6];
}
function generateColorRamp({
total = 9,
hStart = Math.random() * 360,
Expand All @@ -29,6 +41,7 @@ var rampensau = (() => {
sEasing = (x) => Math.pow(x, 2),
lRange = [Math.random() * 0.1, 0.9],
lEasing = (x) => Math.pow(x, 1.5),
adjustmentsFn = ([h, s, l]) => [h, s, l],
hueList
} = {}) {
const lDiff = lRange[1] - lRange[0];
Expand All @@ -37,11 +50,10 @@ var rampensau = (() => {
return Array.from({ length }, (_, i) => {
const relI = i / (length - 1);
const fraction = 1 / length;
return [
hueList ? hueList[i] : (360 + hStart + (1 - hEasing(relI, fraction) - hStartCenter) * (360 * hCycles)) % 360,
sRange[0] + sDiff * sEasing(relI, fraction),
lRange[0] + lDiff * lEasing(relI, fraction)
];
const hue = hueList ? hueList[i] : (360 + hStart + (1 - hEasing(relI, fraction) - hStartCenter) * (360 * hCycles)) % 360;
const saturation = sRange[0] + sDiff * sEasing(relI, fraction);
const lightness = lRange[0] + lDiff * lEasing(relI, fraction);
return adjustmentsFn([hue, saturation, lightness]);
});
}
function shuffleArray(array, rndFn = Math.random) {
Expand Down
2 changes: 1 addition & 1 deletion dist/index.min.cjs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
var x=Object.defineProperty;var T=e=>x(e,"__esModule",{value:!0});var f=(e,t)=>{T(e);for(var n in t)x(e,n,{get:t[n],enumerable:!0})};f(exports,{colorHarmonies:()=>M,colorToCSS:()=>H,generateColorRamp:()=>C,generateColorRampParams:()=>k,lerp:()=>y,scaleSpreadArray:()=>S,shuffleArray:()=>b,uniqueRandomHues:()=>A});function C({total:e=9,hStart:t=Math.random()*360,hStartCenter:n=.5,hEasing:m=o=>o,hCycles:s=1,sRange:r=[.4,.35],sEasing:a=o=>Math.pow(o,2),lRange:p=[Math.random()*.1,.9],lEasing:l=o=>Math.pow(o,1.5),hueList:u}={}){let o=p[1]-p[0],c=r[1]-r[0],i=u&&u.length>0?u.length:e;return Array.from({length:i},(w,g)=>{let d=g/(i-1),h=1/i;return[u?u[g]:(360+t+(1-m(d,h)-n)*(360*s))%360,r[0]+c*a(d,h),p[0]+o*l(d,h)]})}function b(e,t=Math.random){let n=e.length,m;for(;n!=0;)m=Math.floor(t()*n),n--,[e[n],e[m]]=[e[m],e[n]];return e}var M={complementary:e=>[(e+360)%360,(e+540)%360],splitComplementary:e=>[(e+360)%360,(e+510)%360,(e+570)%360],triadic:e=>[(e+360)%360,(e+480)%360,(e+600)%360],tetradic:e=>[(e+360)%360,(e+450)%360,(e+540)%360,(e+630)%360],monochromatic:e=>[(e+360)%360],doubleComplementary:e=>[(e+360)%360,(e+540)%360,(e+390)%360,(e+630)%360],compound:e=>[(e+360)%360,(e+540)%360,(e+420)%360,(e+600)%360],analogous:e=>[(e+360)%360,(e+390)%360,(e+420)%360,(e+450)%360,(e+480)%360,(e+510)%360]};function A({startHue:e=0,total:t=9,minHueDiffAngle:n=60,rndFn:m=Math.random}={}){n=Math.min(n,360/t);let s=e||m()*360,r=Array.from({length:Math.round(360/n)},(p,l)=>(s+l*n)%360),a=b(r,m);return a.length>t&&(a=a.slice(0,t)),a}var F={oklch:e=>[e[2]*100+"%",e[1]*100+"%",e[0]],lch:e=>[e[2]*100+"%",e[1]*100+"%",e[0]],hsl:e=>[e[0],e[1]*100+"%",e[2]*100+"%"]},H=(e,t="oklch")=>`${t}(${F[t](e).join(" ")})`,y=(e,t,n)=>t+e*(n-t),S=(e,t,n=y)=>{if(e.length===0)throw new Error("Initial array must not be empty.");if(t<e.length)throw new Error("Target size must be greater than or equal to the initial array length.");let m=t-e.length,s=e.map(r=>[r]);for(let r=0;r<m;r++)s[r%(e.length-1)].push(null);for(let r=0;r<s.length-1;r++){let a=s[r],p=s[r+1],l=a[0],u=p[0];for(let o=1;o<a.length;o++){let c=o/a.length;a[o]=n(c,l,u)}}return s.flat()},k={total:{default:5,props:{min:4,max:50,step:1}},hStart:{default:0,props:{min:0,max:360,step:.1}},hCycles:{default:1,props:{min:-2,max:2,step:.001}},hStartCenter:{default:.5,props:{min:0,max:1,step:.001}},minLight:{default:Math.random()*.2,props:{min:0,max:1,step:.001}},maxLight:{default:.89+Math.random()*.11,props:{min:0,max:1,step:.001}},minSaturation:{default:Math.random()<.5?.4:.8+Math.random()*.2,props:{min:0,max:1,step:.001}},maxSaturation:{default:Math.random()<.5?.35:.9+Math.random()*.1,props:{min:0,max:1,step:.001}}};
var b=Object.defineProperty;var A=e=>b(e,"__esModule",{value:!0});var F=(e,t)=>{A(e);for(var n in t)b(e,n,{get:t[n],enumerable:!0})};F(exports,{colorHarmonies:()=>V,colorToCSS:()=>E,generateColorRamp:()=>S,generateColorRampParams:()=>G,harveyHue:()=>H,lerp:()=>y,scaleSpreadArray:()=>R,shuffleArray:()=>f,uniqueRandomHues:()=>k});function H(e){if(e===1||e===0)return e;e=1+e%1;let t=1/6,n=e%t/t*Math.PI/2,[o,a]=[t*Math.cos(n),t*Math.sin(n)],r=Math.floor(e*6);return[a,1/3-o,1/3+a,2/3-o,2/3+a,1-o][r%6]}function S({total:e=9,hStart:t=Math.random()*360,hStartCenter:n=.5,hEasing:o=m=>m,hCycles:a=1,sRange:r=[.4,.35],sEasing:s=m=>Math.pow(m,2),lRange:p=[Math.random()*.1,.9],lEasing:l=m=>Math.pow(m,1.5),adjustmentsFn:i=([m,d,c])=>[m,d,c],hueList:u}={}){let m=p[1]-p[0],d=r[1]-r[0],c=u&&u.length>0?u.length:e;return Array.from({length:c},(I,x)=>{let h=x/(c-1),g=1/c,T=u?u[x]:(360+t+(1-o(h,g)-n)*(360*a))%360,M=r[0]+d*s(h,g),C=p[0]+m*l(h,g);return i([T,M,C])})}function f(e,t=Math.random){let n=e.length,o;for(;n!=0;)o=Math.floor(t()*n),n--,[e[n],e[o]]=[e[o],e[n]];return e}var V={complementary:e=>[(e+360)%360,(e+540)%360],splitComplementary:e=>[(e+360)%360,(e+510)%360,(e+570)%360],triadic:e=>[(e+360)%360,(e+480)%360,(e+600)%360],tetradic:e=>[(e+360)%360,(e+450)%360,(e+540)%360,(e+630)%360],monochromatic:e=>[(e+360)%360],doubleComplementary:e=>[(e+360)%360,(e+540)%360,(e+390)%360,(e+630)%360],compound:e=>[(e+360)%360,(e+540)%360,(e+420)%360,(e+600)%360],analogous:e=>[(e+360)%360,(e+390)%360,(e+420)%360,(e+450)%360,(e+480)%360,(e+510)%360]};function k({startHue:e=0,total:t=9,minHueDiffAngle:n=60,rndFn:o=Math.random}={}){n=Math.min(n,360/t);let a=e||o()*360,r=Array.from({length:Math.round(360/n)},(p,l)=>(a+l*n)%360),s=f(r,o);return s.length>t&&(s=s.slice(0,t)),s}var w={oklch:e=>[e[2]*100+"%",e[1]*100+"%",e[0]],lch:e=>[e[2]*100+"%",e[1]*100+"%",e[0]],hsl:e=>[e[0],e[1]*100+"%",e[2]*100+"%"]},E=(e,t="oklch")=>`${t}(${w[t](e).join(" ")})`,y=(e,t,n)=>t+e*(n-t),R=(e,t,n=y)=>{if(e.length===0)throw new Error("Initial array must not be empty.");if(t<e.length)throw new Error("Target size must be greater than or equal to the initial array length.");let o=t-e.length,a=e.map(r=>[r]);for(let r=0;r<o;r++)a[r%(e.length-1)].push(null);for(let r=0;r<a.length-1;r++){let s=a[r],p=a[r+1],l=s[0],i=p[0];for(let u=1;u<s.length;u++){let m=u/s.length;s[u]=n(m,l,i)}}return a.flat()},G={total:{default:5,props:{min:4,max:50,step:1}},hStart:{default:0,props:{min:0,max:360,step:.1}},hCycles:{default:1,props:{min:-2,max:2,step:.001}},hStartCenter:{default:.5,props:{min:0,max:1,step:.001}},minLight:{default:Math.random()*.2,props:{min:0,max:1,step:.001}},maxLight:{default:.89+Math.random()*.11,props:{min:0,max:1,step:.001}},minSaturation:{default:Math.random()<.5?.4:.8+Math.random()*.2,props:{min:0,max:1,step:.001}},maxSaturation:{default:Math.random()<.5?.35:.9+Math.random()*.1,props:{min:0,max:1,step:.001}}};
2 changes: 1 addition & 1 deletion dist/index.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ca916e8

Please sign in to comment.