Какого цвета Чак Норрис?

mychatik

Support
Команда форума
Регистрация
26.05.15
Сообщения
501
Реакции
425
Баллы
63
Веб-сайт
mychatik.ru
В ранних спецификациях W3C было определено всего 16 ключевых цветов.
В более поздних спецификациях дополнительно было определено ещё 130 различных названий цветов.

Некоторые названия содержат "многа букаф " и при их написании можно допустить ошибку, получив в результате совсем не тот цвет, который ожидался.
Кто-то скажет, что всё верно - неправильно написали название цвета - неправильный цвет и получили.
Но мы ведь написали несуществующий(!) цвет, а по логике, если цвет не определён - он должен стать "по умолчанию", или чёрным.

Разберёмся, почему так получается.
Для примера, возьмём цвет chucknorris. В W3C спецификации такого цвета, естественно, нет.

Так какой же цвет получим в браузере?

Правила такие:
  1. Неправильные цифры интерпретируется, как 0. Недостающие цифры тоже рассматриваются, как 0.
  2. Количество символов должно делиться на 3 без остатка.
  3. Дополняющие нули дописываются справа .
  4. Разделяем все символы на 3 равные группы.
  5. Отбрасываются все символы, кроме последних 8-и.
  6. Отбрасываются начальные нули один за другим, если все компоненты имеют начальный ноль (000F 00FF 0FFF = 00F 0FF FFF).
  7. Отбрасываются все символы, кроме первых 2-х.

Применив правила - мы получим:
  1. Заменяем все недействительные шестнадцатеричные символы на 0:
    Наш chucknorris теперь превращается в c00c0000000.

  2. Дополняем нулями до общего количества символов, делящихся на 3 (с 11 до 12):
    c00c00000000

  3. Делим на три равные группы, где каждый компонент представляет соответствующий компонент цвета цвета RGB:
    RGB (c00c, 0000, 0000)

  4. Обрезаем каждый из аргументов справа, оставив только два символа, что даёт следующий результат:
    chucknorris = RGB (c0, 00, 00) = #C00000

А какой же цвет будет, если мы возьмём набор случайных шестнадцатеричных чисел?
Например, <font color = "6db6ec49efd278cd0bc92d1e5e072d68">.
Можно было бы ожидать усечение справа - до #6db6ec, или слева - до #072d68. Но такого не произойдет.

Применяем правила:
  1. Дополняем справа нулями до 33 знаков:
    6db6ec49efd278cd0bc92d1e5e072d680

  2. Затем делим на три равные группы:
    RGB (6db6ec49efd, 278cd0bc92d, 1e5e072d680)

  3. Из этих групп оставляем справа по 8 цифр:
    RGB (6ec49efd, cd0bc92d, e072d680)

  4. И обрезаем всё справа, до двух значимых цифр:
    RGB (6e, cd, e0)

  5. В результате получаем, тот цвет, который будет реально отображаться в браузере:
    RGB (6e, cd, e0) = #6ECDE0

Программная реализация этого алгоритма:

HTML:
<!DOCTYPE HTML>

<html>
<head>

  <title>ChuckNorris</title>

  <meta charset="utf-8">

<style>

body { font: medium monospace; }

input { width: 20em; }

table { table-layout: fixed; width: 100%; }

</style>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

<script>

function parseColor(input) {

  // todo: return error if input is ""

  input = input.trim();

  // todo: return error if input is "transparent"

  // todo: return corresponding #rrggbb if input is a named color

  // todo: return #rrggbb if input matches #rgb

  // todo: replace unicode code points greater than U+FFFF with 00

  if (input.length > 128) {

    input = input.slice(0, 128);

  }

  if (input.charAt(0) === "#") {

    input = input.slice(1);

  }

  input = input.replace(/[^0-9A-Fa-f]/g, "0");

  while (input.length === 0 || input.length % 3 > 0) {

    input += "0";

  }

  var r = input.slice(0, input.length / 3);

  var g = input.slice(input.length / 3, input.length * 2 / 3);

  var b = input.slice(input.length * 2 / 3);

  if (r.length > 8) {

    r = r.slice(-8);

    g = g.slice(-8);

    b = b.slice(-8);

  }

  while (r.length > 2 && r.charAt(0) === "0" && g.charAt(0) === "0" && b.charAt(0) === "0") {

    r = r.slice(1);

    g = g.slice(1);

    b = b.slice(1);

  }

  if (r.length > 2) {

    r = r.slice(0, 2);

    g = g.slice(0, 2);

    b = b.slice(0, 2);

  }

  return "#" + r.padStart(2, "0") + g.padStart(2, "0") + b.padStart(2, "0");

}


$(function() {

  $("#input").on("change", function() {

    var input = $(this).val();

    var color = parseColor(input);

    var $cells = $("#result tbody td");

    $cells.eq(0).attr("bgcolor", input);

    $cells.eq(1).attr("bgcolor", color);


    var color1 = $cells.eq(0).css("background-color");

    var color2 = $cells.eq(1).css("background-color");

    $cells.eq(2).empty().append("bgcolor: " + input, "<br>", "getComputedStyle: " + color1);

    $cells.eq(3).empty().append("bgcolor: " + color, "<br>", "getComputedStyle: " + color2);

  });

});

</script>

</head>


<body>

<p><input id="input" placeholder="Enter color e.g. chucknorris"></p>

<table id="result">

  <thead>

    <tr>

      <th>Left Color</th>

      <th>Right Color</th>

    </tr>

  </thead>

  <tbody>

    <tr>

      <td>&nbsp;</td>

      <td>&nbsp;</td>

    </tr>

    <tr>

      <td>&nbsp;</td>

      <td>&nbsp;</td>

    </tr>

  </tbody>

</table>

</body>

</html>
 
Последнее редактирование:
Сверху Снизу