Farbschema ohne die Hilfe eines Designers


Sicherlich waren viele von Ihnen in einer Situation, in der Sie schnell die Farben für die Dekoration auswählen müssen, und der Designer ist mit wichtigeren Aufgaben beschäftigt, schlecht gelaunt oder im Urlaub. Die Aufgabe ist nicht schwierig, aber manchmal muss man mehrere Tage auf eine Antwort warten.

Mein Name ist Emil Frolov, ich bin Techlide im internen Serviceteam von DomKlik. In diesem Artikel werde ich Ihnen erzählen, wie die Idee einer Bibliothek entstanden ist, was jetzt viel Zeit bei der Auswahl von Farben spart. Die Lösung ist einfach, aber sehr nützlich. Nehmen Sie sie in Betrieb.

Vor allem, wenn Sie Farben für das dunkle Schema auswählen müssen.

Aufgabe


DomKlik verfügt über ein Unternehmensportal, von dem jeder Abschnitt ein eigenes Farbschema hat. Zuvor musste ich jedes Mal, um einen neuen Abschnitt zu erstellen, Designer quälen und sie bitten, einen neuen Satz von Farben aufzunehmen und sie auf die Benutzeroberfläche zu übertragen. Es stellte sich heraus, dass eine Menge zusätzlicher Code viel Zeit für Korrespondenz, Warten und Koordination aufgewendet wurde. Ich wollte den gesamten Prozess wirklich vereinfachen und beschleunigen.

Wir haben im Internet nach vorgefertigten Lösungen gesucht, aber nichts Passendes gefunden. Und dann haben sie beschlossen, eine Bibliothek zu schreiben: Sie geben die Farbe (Marke) ein, die der Designer angibt, und die Bibliothek wählt einige passendere Farben aus. Wir wollten auch, dass die Bibliothek auch dunkle Farbschemata generiert.
Dies ist kein Rezept für Glück, sondern eine Idee, die jeder im Rahmen seines Projekts entwickeln kann. Sie können hier eine kleine Demo sehen .

Idee und Lösung


Wir haben uns überlegt, wie es geht. Wir haben mit einem grundlegenden Algorithmus zur Farberzeugung begonnen. In Ihrem Internet wurde wieder nichts Fertiges gefunden. Sie haben jedoch eine Bibliothek gefunden , die verschiedene Farbeinstellungen ändern kann.

Viele Menschen wissen, dass es viele verschiedene Farbanpassungsalgorithmen gibt:



Ich sehe keinen Sinn darin, sie zu malen, sie haben dies bereits hunderte Male vor mir getan. Es gibt jedoch einige wichtige Punkte:

  1. Für uns sind sie überflüssig.
  2. Ich wollte Farben für mich selbst wählen.

Aus diesem Grund haben Designer und Entwickler, die zu einem einzigen Impuls zusammengefasst wurden, beschlossen, das Schema einmal manuell zu übernehmen.

Zunächst haben wir die Grundfarben beschrieben:

export const getColors = (projectColor, inverse) => {
  ...
  const BASE_SUCCESS = '#00985f';
  const BASE_WARNING = '#ff9900';
  const BASE_PROGRESS = '#fe5c05';
  const BASE_ALERT = '#ff3333';
  const BASE_SYSTEM = '#778a9b';
  const BASE_NORMAL = '#dde3e5';
  const BASE_WHITE = '#ffffff';
  const BASE_BLACK = '#000';
  const TYPO_BASE_BLACK = '#242629';
  const TYPO_LINK = '#33BDFF';
  ...
}

Auf dieser Grundlage können Sie mit dem Erstellen beginnen. Wir bekommen Objekte für die Arbeit mit Grundfarben.

  import color from 'color-js';

  export const getColors = (projectColor, inverse) => {
    ...
    const baseWhite = color(BASE_WHITE);
    const baseBlack = color(BASE_BLACK);
    const baseTypoBlack = color(TYPO_BASE_BLACK);
    ...
  }

Ich denke, es macht keinen Sinn, die gesamte Auswahl an Farben vollständig zu beschreiben, aber als Beispiel werde ich ein paar Zeilen geben:

export const getColors = (projectColor, inverse) => {
  ...
  const bgBrand = baseProject;
  const bgHard = baseColor.setLightness(0.4);
  const bgSharp = baseColor.setLightness(0.18);
  const bgStripe = baseColor.setLightness(0.1);
  const bgGhost = baseColor.setLightness(0.07);
  ...
}

Nachdem wir die Primärfarben ausgewählt hatten, hatten wir das folgende Problem.

Und in welcher Farbe wird der Text auf den Elementen angezeigt?

Die Aufgabe war nicht so schwierig, wie es schien. Um es aus dem Hex-Wert zu lösen, müssen wir die Helligkeit des Elements ermitteln. Wir haben dies mit zwei Hilfsfunktionen gemacht. Der erste übersetzt hex in RGB:

const hexToRgb = (hex) => {
  const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
  const newHex = hex.replace(shorthandRegex, (
    magenta,
    red,
    green,
    blue
  ) => red + red + green + green + blue + blue);

  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(newHex);

  return result ? {
    red: parseInt(result[1], 16),
    green: parseInt(result[2], 16),
    blue: parseInt(result[3], 16)
  } : null;
};

Die zweite Funktion von RGB ermittelt die Helligkeit des Hintergrunds und entscheidet, ob die Farbe dunkel oder hell ist:

export const getBgTextColor = (bgColor) => {
  const rgb = hexToRgb(bgColor);
  const light = (rgb.red * 0.8 + rgb.green + rgb.blue * 0.2) / 510 * 100;

  return light > 70 ? '#000000' : '#ffffff';
};

Sie könnten denken, dass jetzt alles für den nächsten Schritt bereit ist. Aber nein, wir wollen immer noch Unterstützung für ein dunkles Thema aus der Box? Ja! Wir wollen es!

Sie haben wahrscheinlich bemerkt, dass wir unserer Funktion eine Flagge übergeben inverse. Lassen Sie uns unseren Code unter Berücksichtigung dieses Flags ein wenig ändern:

import color from 'color-js';

export const getColors = (projectColor, inverse) => {
  ...
  const BASE_SUCCESS = '#00985f';
  const BASE_WARNING = '#ff9900';
  const BASE_PROGRESS = '#fe5c05';
  const BASE_ALERT = '#ff3333';
  const BASE_SYSTEM = '#778a9b';
  const BASE_NORMAL = '#dde3e5';
  const BASE_WHITE = '#ffffff';
  const BASE_BLACK = '#000';
  const TYPO_BASE_BLACK = '#242629';
  const TYPO_LINK = '#33BDFF';

  ...

  const baseWhite = color(BASE_WHITE);
  const baseBlack = color(BASE_BLACK);
  const baseTypoBlack = color(TYPO_BASE_BLACK);
  const baseColor = inverse ? baseWhite : baseBlack;
  const typoColor = inverse ? baseWhite : baseTypoBlack;

  ...

  const bgHard = inverse ? baseColor.setLightness(0.4) : baseColor.lightenByAmount(0.85);
  const bgSharp = inverse ? baseColor.setLightness(0.18) : baseColor.lightenByAmount(0.95);
  const bgStripe = inverse ? baseColor.setLightness(0.1) : baseColor.lightenByAmount(0.96);
  const bgGhost = inverse ? baseColor.setLightness(0.07) : baseColor.lightenByAmount(0.99);

  ...
}

Das ist alles. Wir können eine Liste von Farben geben:

return {
  ...
    // BG
    'color-bg-hard': bgHard.toString(),
    'color-bg-sharp': bgSharp.toString(),
    'color-bg-stripe': bgStripe.toString(),
    'color-bg-ghost': bgGhost.toString(),
    'color-bg-primary': bgDefault.toString(),
  ...
}

In zwei Tagen habe ich mit Hilfe unseres Designers eine Bibliothek erstellt, die am Ausgang eine Farbpalette für ein dunkles und helles Thema enthält.

Nächste Frage: Wie benutzt man es?

Sehr einfach. Um das generierte Farbschema zu implementieren, haben wir die Einfügung von CSS-Variablen durch den Stilblock verwendet. Dies vermeidet Konflikte mit CSS-Variablen, die andere CSS-Bibliotheken verwenden.

  const colors = getColors(color, themeKey === 'dark');
  const colorsVars = Object.keys(colors).map((key) => `--${key}: ${customColors[key]}`).join(';');
  
  const link = document.createElement('style');
  const headTag = document.getElementsByTagName('head')[0];

  link.type = 'text/css';
  link.id = 'project-theme-scope';
  const stylesBody = `:root {${colorsVars}}`;

  link.innerText = stylesBody;

  headTag.append(link);

Und jetzt das leckerste. Achtung! Achtung! Nun, mit ein paar Zeilen, wenn wir dunkle Themen für die Hälfte der Elemente unterstützen:

  body {
    background: var(--color-bg-ghost);
    color: var(--color-typo-primary);
  }

Das Ergebnis ist eine Bibliothek, in der wir die Hauptmarkenfarbe übergeben und eine Reihe von CSS-Variablen erhalten, die wir dann zum Kolorieren unseres Projekts verwenden.

Die meiste Zeit wurde für die Auswahl eines Farbschemas aufgewendet. Ich musste eine Reihe verschiedener Parameter manuell sortieren, damit die Farben miteinander kombiniert wurden. Bei jeder Wiederholung der Farbauswahl für die neuen Abschnitte des Portals sparen wir jetzt mehrere Tage.

Da der Designer an der Erstellung des Algorithmus beteiligt war, gab es immer noch keinen Fall, dass er mit den von der Bibliothek erzeugten Farben unzufrieden war. Ja, und die Farbschemata sind nicht zu groß. Es ist schwierig, Fehler zu machen.

Ich betone noch einmal, dass wir nicht behaupten, die einzig richtige Entscheidung zu sein. Diese Idee wird umgesetzt und funktioniert gut. Ich habe versucht, Ihnen die wichtigsten Punkte vorzustellen, und die Details und der Umfang der Implementierung hängen nur von Ihnen und Ihrem Projekt ab.

Vielen Dank für Ihre Aufmerksamkeit.

All Articles