Как мне сделать математику с такими цветами, как SASS, но в Ruby? - PullRequest
3 голосов
/ 26 апреля 2010

В SASS я могу сделать:

!pink = #ff43a7
!darker_pink = !pink - #333333

Я бы хотел того же в Ruby.

Ответы [ 5 ]

4 голосов
/ 26 апреля 2010

Шестнадцатеричный код можно представить в Ruby, добавив префикс к 0x:

pink = 0xff43a7
darker_pink = pink - 0x333333

цветной помощник

def color(hex)
  "#%06x" % hex
end

Использование в шаблоне ERb

.container {
  color: <%= color pink %>;
  border: 1px solid <%= color darker_pink %>;
}

выход

.container {
  color: #ff43a7;
  border: 1px solid #cc1074;
}
2 голосов
/ 28 декабря 2011

Использовать модуль Sass

Если у вас уже есть библиотека Sass, вы можете создавать экземпляры и работать с ее объектами.

Например:

red  = Sass::Script::Color.new([255, 0, 0])
gray = Sass::Script::Color.new([128, 128, 128])
red.lightness < gray.lightness # => true

Должен быть встроенный способ превращения шестнадцатеричных строк, таких как #00FF00, в Color объекты, но не видя их, я написал эту функцию:

# @param color_string - hex string, like '#22FF22'. MUST be 6 characters,
# because I don't feel like dealing with the use-case for 3. :)
def color_from_hex_string(color_string)
  # Drop the leading '#', if any
  color_string = color_string[1..-1] if color_string.start_with?('#')
  raise ArgumentError.new('Hex string must be 6 characters') unless color_string.length == 6

  # Turn into array of 2-digit decimal numbers. 
  # Eg, '808080' becomes [128, 128, 128]; '#ff0000' becomes [255, 0, 0]
  rgb_array = color_string.split('').each_slice(2).map do |slice|
    slice.join('').to_i(16).to_s(10)
  end

  # Use that to build a new Color object
  color = Sass::Script::Color.new(rgb_array)

  # Set this option so it won't complain (?)
  color.options = {:style => :compressed}

  return color
end
2 голосов
/ 16 мая 2010

Основной подход добавления / вычитания цветов в Sass - это бессмыслица, и он действительно работает только при использовании настройки серого. Вот почему в Sass 3 у нас теперь есть полная поддержка операций в области HSL, которая тесно связана с тем, как люди думают о цветах.

Поскольку Sass написан на Ruby, вы можете по крайней мере прочитать наш код, чтобы увидеть, что происходит.

Вот класс Color и функции , которые работают с ними .

Это действительно нетривиальный код. Почему бы просто не использовать Sass?

0 голосов
/ 22 декабря 2012

Я только что наткнулся на то, где я хотел распределить цвета для набора по разным оттенкам. Источник SASS мало помог, потому что я не видел способа получить RGB от HSV.

Цветной камень имел то, что мне было нужно.

Я написал этот помощник:

def region_color(index, size)
  h = (index.to_f / (size - 1).to_f)
  Color::HSL.from_fraction(h, 0.95, 0.3).html
end
0 голосов
/ 04 ноября 2010

Чтобы уточнить ответ @ macek, следуя пожеланиям @ drawnownward и @ lpsquiggle:

Вы можете сделать двух помощников, вот так:

  def color(color)
    "#%06x" % color
  end

  def darker_color(color)
    x = color.match(/0x(..)(..)(..)/)
    r = x[1].sub(/[0-3]/, '5')
    g = x[2].sub(/[0-3]/, '5')
    b = x[3].sub(/[0-3]/, '5')
    rgb = "0x#{r}#{g}#{b}"
    "#%06x" % (rgb.hex - 0x444444)
  end

Преимущество: если вы определили цветной гекс с низкими значениями (здесь от 0 до 3), они будут увеличены до вычитания, так что они будут заканчиваться 0 после, вместо того, чтобы оборачиваться и становиться c, d, e или f (что даст вам цвет, которого вы не ожидали). Он делает это только для первого значения в каждой паре #rrggbb, поэтому # 313131 становится # 0d0d0d, что технически некорректно, но гораздо лучше, чем #fdfdfd, так что это кажется достаточно хорошим компромиссом, так как вы захотите сохранить эти вторые значения в других случаях.

В вашем шаблоне Erb вы бы написали:

.container {
  color: <%= color pink %>;
  border: 1px solid <%= darker_color pink %>;
}

Вместо:

.container {
  color: <%= color pink %>;
  border: 1px solid <%= color darker_pink %>;
}

Надеюсь, это кому-нибудь поможет.

...