Огурцы стали зелёными, как всё остальное

· #игра #css #canvas

После смены палитры сайта на зелёную в «Ловись, рыбка» стало трудно отличать огурцы от рыбы: они стали почти одного цвета. Рыба брала акцентный салатовый, огурцы брали --ok, который теперь тоже зеленоватый. На тёмном фоне разница между ними была в паре оттенков.

Проблема оказалась в том, что игровые объекты красились общими цветами сайта. Пока сайт был коричнево-оранжевым, это работало случайно.

Отдельные цвета для игры

Я завёл в странице игры свои переменные, которые не зависят от палитры сайта:

:root {
    --cat: #f0a35e;   /* котик рыжий */
    --fish: #8ccbf2;  /* рыба голубая */
    --cuke: #5ccf62;  /* огурцы зелёные, и больше ничего зелёного на поле */
    --nip: #c3a0ff;   /* кошачья мята */
    --box: #c9a27a;   /* коробка */
    --red: #ff7f6e;   /* магнит */
}

Для светлой темы у каждой переменной своя, более тёмная пара, иначе голубая рыба на светлом фоне просто исчезает.

Главное правило, к которому я пришёл: опасное должно быть одного цвета, и этот цвет больше ни для чего не используется. Раньше зелёной была ещё и кошачья мята, а это бонус. Теперь она фиолетовая.

Как canvas узнаёт про тему

Игра рисует символы на canvas, а canvas про CSS ничего не знает. Поэтому цвета читаются из переменных при запуске и заново при каждой смене темы:

function readColors() {
    var css = getComputedStyle(document.documentElement);
    ['cat', 'fish', 'cuke', 'nip', 'box', 'red', 'gold', 'love', 'muted'].forEach(function (name) {
        colors[name] = css.getPropertyValue('--' + name).trim();
    });
}

document.addEventListener('themechange', function () { readColors(); draw(); });

Удобно: чтобы поменять цвет рыбы, достаточно поправить одну строку в CSS, а JavaScript трогать не нужно.

Котика сделал рыжим. Он и раньше был цвета акцента, но рыжий кот ловит голубую рыбу, а зелёные огурцы обходит. Так понятнее, кто есть кто.