sassの彩度・明度の調整をphpで再現しました。
下記サイトの計算式を参考にしています。
http://www.peko-step.com/tool/hslrgb.html
ColorChanger.php
<?php
class ColorChanger
{
private $_r = 0, $_g = 0, $_b = 0, $_h = 0, $_s = 0, $_l = 0;
public function lighten ($color, $lightness)
{
$this->setColor($color);
$l = $this->_l;
$l += $lightness;
$this->_l = (100 < $l)?100:$l;
$this->_getRgb();
return $this->_decHex($this->_r) . $this->_decHex($this->_g) . $this->_decHex($this->_b);
}
public function darken ($color, $darkness)
{
$this->setColor($color);
$l = $this->_l;
$l -= $darkness;
$this->_l = (0 > $l)?0:$l;
$this->_getRgb();
return $this->_decHex($this->_r) . $this->_decHex($this->_g) . $this->_decHex($this->_b);
}
public function saturate ($color, $per)
{
$this->setColor($color);
$s = $this->_s;
$s += $per;
$this->_s = (100 < $s)?100:$s;
$this->_getRgb();
return $this->_decHex($this->_r) . $this->_decHex($this->_g) . $this->_decHex($this->_b);
}
public function desaturate ($color, $per)
{
$this->setColor($color);
$s = $this->_s;
$s -= $per;
$this->_s = (0 > $s)?0:$s;
$this->_getRgb();
return $this->_decHex($this->_r) . $this->_decHex($this->_g) . $this->_decHex($this->_b);
}
public function _decHex ($dec)
{
return sprintf('%02s', dechex($dec));
}
private function setColor ($color)
{
$this->_r = hexdec(substr($color, 0, 2));
$this->_g = hexdec(substr($color, 2, 2));
$this->_b = hexdec(substr($color, 4, 2));
$this->_maxRgb = max($this->_r, $this->_g, $this->_b);
$this->_minRgb = min($this->_r, $this->_g, $this->_b);
$this->_getHue();
$this->_getSaturation();
$this->_getLuminance();
}
private function _getHue ()
{
$r = $this->_r;
$g = $this->_g;
$b = $this->_b;
$max = $this->_maxRgb;
$min = $this->_minRgb;
if ($r === $g && $r === $b) {
$h = 0;
} else {
$mm = $max - $min;
switch ($max) {
case $r :
$h = 60 * ($mm?($g - $b) / $mm:0);
break;
case $g :
$h = 60 * ($mm?($b - $r) / $mm:0) + 120;
break;
case $b :
$h = 60 * ($mm?($r - $g) / $mm:0) + 240;
break;
}
if (0 > $h) {
$h += 360;
}
}
$this->_h = $h;
}
private function _getSaturation ()
{
$max = $this->_maxRgb;
$min = $this->_minRgb;
$cnt = round(($max + $min) / 2);
if (127 >= $cnt) {
$tmp = ($max + $min);
$s = $tmp?($max - $min) / $tmp:0;
} else {
$tmp = (510 - $max - $min);
$s = ($tmp)?(($max - $min) / $tmp):0;
}
$this->_s = $s * 100;
}
private function _getLuminance ()
{
$max = $this->_maxRgb;
$min = $this->_minRgb;
$this->_l = ($max + $min) / 2 / 255 * 100;
}
private function _getMaxMinHsl ()
{
$s = $this->_s;
$l = $this->_l;
if (49 >= $l) {
$max = 2.55 * ($l + $l * ($s / 100));
$min = 2.55 * ($l - $l * ($s / 100));
} else {
$max = 2.55 * ($l + (100 - $l) * ($s / 100));
$min = 2.55 * ($l - (100 - $l) * ($s / 100));
}
$this->_maxHsl = $max;
$this->_minHsl = $min;
}
private function _getRGB ()
{
$this->_getMaxMinHsl();
$h = $this->_h;
$s = $this->_s;
$l = $this->_l;
$max = $this->_maxHsl;
$min = $this->_minHsl;
if (60 >= $h) {
$r = $max;
$g = ($h / 60) * ($max - $min) + $min;
$b = $min;
} else if (120 >= $h) {
$r = ((120 - $h) / 60) * ($max - $min) + $min;
$g = $max;
$b = $min;
} else if (180 >= $h) {
$r = $min;
$g = $max;
$b = (($h - 120) / 60) * ($max - $min) + $min;
} else if (240 >= $h) {
$r = $min;
$g = ((240 - $h) / 60) * ($max - $min) + $min;
$b = $max;
} else if (300 >= $h) {
$r = (($h - 240) / 60) * ($max - $min) + $min;
$g = $min;
$b = $max;
} else {
$r = $max;
$g = $min;
$b = ((360 - $h) / 60) * ($max - $min) + $min;
}
$this->_r = round($r);
$this->_g = round($g);
$this->_b = round($b);
}
}
- 使い方
test.php
<?php
include('plugins/NjcCommon/Lib/Color/ColorChanger.php');
$colorChanger = new ColorChanger();
$color = 'ff7700';
$val = 10;
echo "sass の lighten(#{$color}, {$val}%); -> " . $colorChanger->lighten($color, $val) . "\n";
echo "sass の darken(#{$color}, {$val}%); -> " . $colorChanger->darken($color, $val) . "\n";
$val = 50;
$color = 'bf7b40';
echo "sass の saturate(#{$color}, {$val}%); -> " . $colorChanger->saturate($color, $val) . "\n";
$color = 'ff7700';
echo "sass の desaturate(#{$color}, {$val}%); -> " . $colorChanger->desaturate($color, $val) . "\n";
- 実行結果
$ php -f test.php
sass の lighten(#ff7700, 10%); -> ff9233
sass の darken(#ff7700, 10%); -> cc5f00
sass の saturate(#bf7b40, 50%); -> ff7600
sass の desaturate(#ff7700, 50%); -> bf7b40