Skip to content

Commit

Permalink
Merge pull request #45 from mll-lab/feat-add-stringToHslaColor
Browse files Browse the repository at this point in the history
  • Loading branch information
simbig authored Aug 20, 2024
2 parents d8abb2c + 48fea4d commit 0fb2320
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
34 changes: 34 additions & 0 deletions src/stringToColor.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { uniq } from 'lodash';

import { randomString, stringToHslaColor } from './stringToColor';

describe('stringToHslaColor', () => {
it.each(['test', 'test'])(
'is a pure function returning the same hsla for the same string',
(testString) => {
expect(stringToHslaColor(testString)).toStrictEqual(
'hsla(58, 98%, 48%, 1)',
);
},
);

it('returns various hsla colors for various inputs', () => {
const testStrings = ['t', 'te', 'tes', 'test'];
expect(uniq(testStrings.map(stringToHslaColor)).length).toBe(
testStrings.length,
);
});

it('returns a valid color for a random string', () => {
expect(isValidColor(stringToHslaColor(randomString()))).toBe(true);
});
});

function isValidColor(color: string): boolean {
// Use the browser's validation. Create a dummy HTML element, assign the color and check if it's set.
const element = document.createElement('div');
element.style.borderColor = '';
element.style.borderColor = color;

return element.style.borderColor.length !== 0;
}
42 changes: 42 additions & 0 deletions src/stringToColor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
function hashCode(string: string): number {
let hash = 0;
// eslint-disable-next-line no-plusplus
for (let i = 0; i < string.length; i++) {
// eslint-disable-next-line no-bitwise
hash = string.charCodeAt(i) + ((hash << 5) - hash);
}

return hash;
}

function getHslColor(hash: number): string {
const h = range(hash, 0, 360);
const s = range(hash, 50, 100);
const l = range(hash, 20, 50);

return `hsla(${h}, ${s}%, ${l}%, 1)`;
}

function range(hash: number, min: number, max: number): number {
const diff = max - min;
const x = ((hash % diff) + diff) % diff;

return x + min;
}

export function stringToHslaColor(string: string): string {
return getHslColor(hashCode(string));
}

/**
* Generates a random string with a length of 1-11 chars.
*/
export function randomString(): string {
// Cut off the constant 0. from the beginning
const fractionStart = 2;

// Unequal distribution at the edges, but sufficiently random for the purposes of this function
const randomLengthEnd = Math.round(Math.random() * 11) + 3;

return Math.random().toString(36).substring(fractionStart, randomLengthEnd);
}

0 comments on commit 0fb2320

Please sign in to comment.