Edited at

RubyでSassのlighten, darkenを使ってカラーコードを変換する

More than 1 year has passed since last update.


何のため?

Sassの lighten, darken は手軽に元の色から同じ系統の色を生成でき、便利です。

これを単なるsass, scss ファイル上の記述のみではなく、Rubyから直接呼べるようにすれば、Ruby上で動的なカラーコード生成ができます。これは、例えばRailsアプリケーションのテーマカラーを動的に切り変えるような場合に便利です。


ゴール

カラーコードの文字列(例えば'FF4747')を入力とし、Sassのlighten, darkenの処理をかけた後のカラーコードの文字列を返すようなヘルパーメソッドを作る。


どうやるか

Sassのコンパイラ自体がRubygemsなのでRubyから呼びだすこと自体は比較的簡単にできそうです。

ドキュメントを見ていった結果、

http://sass-lang.com/documentation/Sass/Script/Functions.html#lighten-instance_method

ここを参考にしてSass::Script::Value::Color クラスのインスタンスをModule: Sass::Script::Functions モジュールのlighten, darken メソッドにわたせばよさそう、ということがわかりました。


実装例

以下のようなコードで実現できました

# Railsのhelperとして定義する想定です。

class ColorHelper
def darken(hex_color, amount=10)
color = Sass::Script::Value::Color.from_hex(hex_color)
darkened_color = ctx.darken(color, Sass::Script::Value::Number.new(amount, ['%'], []))
darkened_color.options = {}
darkened_color.to_s
end

def lighten(hex_color, amount=10)
color = Sass::Script::Value::Color.from_hex(hex_color)
lightened_color = ctx.lighten(color, Sass::Script::Value::Number.new(amount, ['%'], []))
lightened_color.options = {}
lightened_color.to_s
end

def ctx
# 特に変更する必要はないのでクラス変数でキャッシュしておきます
@@sass_ctx ||= Sass::Script::Functions::EvaluationContext.new(Sass::Environment.new)
end
end


出力例

helper.darken('FF4747', 10)

#=> '#ff1414'
helper.lighten('FF4747', 10)
#=> "#ff7a7a"

うまく動いてそうです。

もっと手軽にできる方法をご存知の方がいたら是非おしえてください!