MVP Complete
This commit is contained in:
150
app/utils/colorSchemes.ts
Normal file
150
app/utils/colorSchemes.ts
Normal file
@ -0,0 +1,150 @@
|
||||
type Color = string; // Hex color code
|
||||
type ColorScheme = {
|
||||
name: string;
|
||||
colors: {
|
||||
primary: { background: Color; foreground: Color };
|
||||
normal: {
|
||||
black: Color; red: Color; green: Color; yellow: Color;
|
||||
blue: Color; magenta: Color; cyan: Color; white: Color;
|
||||
};
|
||||
bright: {
|
||||
black: Color; red: Color; green: Color; yellow: Color;
|
||||
blue: Color; magenta: Color; cyan: Color; white: Color;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
import knownSchemesData from '../../formatted_themes.json';
|
||||
|
||||
const knownSchemes: ColorScheme[] = knownSchemesData;
|
||||
|
||||
function generateRandomColor(): Color {
|
||||
return '#' + Math.floor(Math.random()*16777215).toString(16).padStart(6, '0');
|
||||
}
|
||||
|
||||
function generateCreativeName(): string {
|
||||
const adjectives = ['Cosmic', 'Neon', 'Mystic', 'Retro', 'Cyber', 'Ethereal', 'Vibrant', 'Dreamy', 'Futuristic', 'Nostalgic'];
|
||||
const nouns = ['Sunset', 'Aurora', 'Galaxy', 'Ocean', 'Forest', 'Desert', 'Nebula', 'Horizon', 'Oasis', 'Metropolis'];
|
||||
return `${adjectives[Math.floor(Math.random() * adjectives.length)]} ${nouns[Math.floor(Math.random() * nouns.length)]}`;
|
||||
}
|
||||
|
||||
function generateRandomScheme(): ColorScheme {
|
||||
let x = {
|
||||
name: generateCreativeName(),
|
||||
colors: {
|
||||
primary: { background: generateRandomColor(), foreground: generateRandomColor() },
|
||||
normal: {
|
||||
black: generateRandomColor(), red: generateRandomColor(), green: generateRandomColor(), yellow: generateRandomColor(),
|
||||
blue: generateRandomColor(), magenta: generateRandomColor(), cyan: generateRandomColor(), white: generateRandomColor()
|
||||
},
|
||||
bright: {
|
||||
black: generateRandomColor(), red: generateRandomColor(), green: generateRandomColor(), yellow: generateRandomColor(),
|
||||
blue: generateRandomColor(), magenta: generateRandomColor(), cyan: generateRandomColor(), white: generateRandomColor()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
x.colors.primary.background = x.colors.normal.black;
|
||||
x.colors.primary.foreground = x.colors.bright.white;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
function crossTitles(title1: string, title2: string): string {
|
||||
const words1 = title1.split(' ');
|
||||
const words2 = title2.split(' ');
|
||||
const firstWord = Math.random() < 0.5 ? words1[0] : words2[1];
|
||||
const secondWord = Math.random() < 0.5 ? words2[0] : words1[1];
|
||||
return `${firstWord} ${secondWord}`;
|
||||
}
|
||||
|
||||
function crossSchemes(scheme1: ColorScheme, scheme2: ColorScheme): ColorScheme {
|
||||
const crossColor = (color1: Color, color2: Color): Color => {
|
||||
const r = Math.round((parseInt(color1.slice(1, 3), 16) + parseInt(color2.slice(1, 3), 16)) / 2);
|
||||
const g = Math.round((parseInt(color1.slice(3, 5), 16) + parseInt(color2.slice(3, 5), 16)) / 2);
|
||||
const b = Math.round((parseInt(color1.slice(5, 7), 16) + parseInt(color2.slice(5, 7), 16)) / 2);
|
||||
return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
||||
};
|
||||
|
||||
return {
|
||||
name: crossTitles(scheme1.name, scheme2.name),
|
||||
colors: {
|
||||
primary: {
|
||||
background: crossColor(scheme1.colors.primary.background, scheme2.colors.primary.background),
|
||||
foreground: crossColor(scheme1.colors.primary.foreground, scheme2.colors.primary.foreground)
|
||||
},
|
||||
normal: {
|
||||
black: crossColor(scheme1.colors.normal.black, scheme2.colors.normal.black),
|
||||
red: crossColor(scheme1.colors.normal.red, scheme2.colors.normal.red),
|
||||
green: crossColor(scheme1.colors.normal.green, scheme2.colors.normal.green),
|
||||
yellow: crossColor(scheme1.colors.normal.yellow, scheme2.colors.normal.yellow),
|
||||
blue: crossColor(scheme1.colors.normal.blue, scheme2.colors.normal.blue),
|
||||
magenta: crossColor(scheme1.colors.normal.magenta, scheme2.colors.normal.magenta),
|
||||
cyan: crossColor(scheme1.colors.normal.cyan, scheme2.colors.normal.cyan),
|
||||
white: crossColor(scheme1.colors.normal.white, scheme2.colors.normal.white)
|
||||
},
|
||||
bright: {
|
||||
black: crossColor(scheme1.colors.bright.black, scheme2.colors.bright.black),
|
||||
red: crossColor(scheme1.colors.bright.red, scheme2.colors.bright.red),
|
||||
green: crossColor(scheme1.colors.bright.green, scheme2.colors.bright.green),
|
||||
yellow: crossColor(scheme1.colors.bright.yellow, scheme2.colors.bright.yellow),
|
||||
blue: crossColor(scheme1.colors.bright.blue, scheme2.colors.bright.blue),
|
||||
magenta: crossColor(scheme1.colors.bright.magenta, scheme2.colors.bright.magenta),
|
||||
cyan: crossColor(scheme1.colors.bright.cyan, scheme2.colors.bright.cyan),
|
||||
white: crossColor(scheme1.colors.bright.white, scheme2.colors.bright.white)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function mutateColor(color: Color): Color {
|
||||
const r = parseInt(color.slice(1, 3), 16);
|
||||
const g = parseInt(color.slice(3, 5), 16);
|
||||
const b = parseInt(color.slice(5, 7), 16);
|
||||
|
||||
const mutateComponent = (component: number) => {
|
||||
const mutation = Math.floor(Math.random() * 51) - 25; // Random number between -25 and 25
|
||||
return Math.max(0, Math.min(255, component + mutation));
|
||||
};
|
||||
|
||||
const newR = mutateComponent(r);
|
||||
const newG = mutateComponent(g);
|
||||
const newB = mutateComponent(b);
|
||||
|
||||
return `#${newR.toString(16).padStart(2, '0')}${newG.toString(16).padStart(2, '0')}${newB.toString(16).padStart(2, '0')}`;
|
||||
}
|
||||
|
||||
function generateSchemeFromGeneticAlgorithm(likedSchemes: ColorScheme[], dislikedSchemes: ColorScheme[]): ColorScheme {
|
||||
if (likedSchemes.length === 0) {
|
||||
return generateRandomScheme();
|
||||
}
|
||||
|
||||
const parentScheme = likedSchemes[Math.floor(Math.random() * likedSchemes.length)];
|
||||
const newScheme: ColorScheme = JSON.parse(JSON.stringify(parentScheme)); // Deep copy
|
||||
|
||||
// Mutate colors
|
||||
Object.keys(newScheme.colors).forEach((colorGroup) => {
|
||||
Object.keys(newScheme.colors[colorGroup]).forEach((colorName) => {
|
||||
if (Math.random() < 0.3) { // 30% chance of mutation
|
||||
newScheme.colors[colorGroup][colorName] = mutateColor(newScheme.colors[colorGroup][colorName]);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Avoid similarities with disliked schemes
|
||||
dislikedSchemes.forEach(dislikedScheme => {
|
||||
Object.keys(newScheme.colors).forEach((colorGroup) => {
|
||||
Object.keys(newScheme.colors[colorGroup]).forEach((colorName) => {
|
||||
if (newScheme.colors[colorGroup][colorName] === dislikedScheme.colors[colorGroup][colorName]) {
|
||||
newScheme.colors[colorGroup][colorName] = mutateColor(newScheme.colors[colorGroup][colorName]);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
newScheme.name = generateCreativeName();
|
||||
return newScheme;
|
||||
}
|
||||
|
||||
export type { ColorScheme };
|
||||
export { knownSchemes, generateRandomScheme, crossSchemes, generateSchemeFromGeneticAlgorithm };
|
32
app/utils/yamlExport.ts
Normal file
32
app/utils/yamlExport.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { ColorScheme } from './colorSchemes';
|
||||
|
||||
export function generateYAML(scheme: ColorScheme): string {
|
||||
return `colors:
|
||||
# Default colors
|
||||
primary:
|
||||
background: '${scheme.colors.primary.background}'
|
||||
foreground: '${scheme.colors.primary.foreground}'
|
||||
|
||||
# Normal colors
|
||||
normal:
|
||||
black: '${scheme.colors.normal.black}'
|
||||
red: '${scheme.colors.normal.red}'
|
||||
green: '${scheme.colors.normal.green}'
|
||||
yellow: '${scheme.colors.normal.yellow}'
|
||||
blue: '${scheme.colors.normal.blue}'
|
||||
magenta: '${scheme.colors.normal.magenta}'
|
||||
cyan: '${scheme.colors.normal.cyan}'
|
||||
white: '${scheme.colors.normal.white}'
|
||||
|
||||
# Bright colors
|
||||
bright:
|
||||
black: '${scheme.colors.bright.black}'
|
||||
red: '${scheme.colors.bright.red}'
|
||||
green: '${scheme.colors.bright.green}'
|
||||
yellow: '${scheme.colors.bright.yellow}'
|
||||
blue: '${scheme.colors.bright.blue}'
|
||||
magenta: '${scheme.colors.bright.magenta}'
|
||||
cyan: '${scheme.colors.bright.cyan}'
|
||||
white: '${scheme.colors.bright.white}'
|
||||
`;
|
||||
}
|
Reference in New Issue
Block a user