PHPでHEXをHSLに変換する
PHPでHEXで指定されている色を下記のようにHSLに変換して出力する関数です。
#74ac53→hsl(98, 35%, 50%)
CSSで「HEXで指定された色に対して輝度や色相を一定のルールで自動的に調節した色を作りたい」という要望に応えるために作りました。最初からHSLで色指定したらよいのですがWordPressのカラーピッカーだとHEXになってしまうんですよね…
使いどころとしては「背景色とテキスト色を決めたら、ホバー時の色や枠線の色を自動的に調整する」といったことに使えます。
スポンサーリンク
プログラムの流れ
大まかな流れとしては、HEXからまずRGBに変換し、RGBの値を使ってHSLを計算します。
HEXからRGBへの変換
HEXからRGBへの変換はhexdec
というPHP関数を使います。この関数は16進数を10進数に変換する関数です。そもそもHEXはRGBの各数値(10進数)を16進数に変換したものなのでその逆を行うわけですね。
ポイントとしてはHEXでは省略形(#FFFFFFは#FFFと書ける)があるのでそのことを考慮したコードになっています。
下記サイトのコードを参考(というかほぼそのまま)にさせて頂きました。
RGBからHSLへの変換
コードを見るとわかりますが、何やら複雑なことをしています。参考にしたのはこちら。
各式の意味は下記のサイトの説明が詳しいです。今回のコードではRGBの数値を正規化してるので数字が違う部分があることに気をつけてください。
RGBとHSLの相互変換ツールと変換計算式 – PEKO STEP
この関数では計算した色相(Hue)、彩度(Saturation)、輝度(Luminace)を、
- CSSで使える形に出力
- 配列で出力
の2種類から選べます。計算した数字を使っていろいろ計算したい場合は配列で出力してください。
コード
<?php function my_hex2hsl( $hex, $echo = 'false' ) { if ( substr( $hex, 0, 1 ) === '#' ) { // 先頭の#を削除 $hex = substr( $hex, 1 ); } else { // 先頭に#がないとカラーでないと判断して処理を中止 return; } if ( strlen( $hex ) === 3 ) { // 3桁の場合6桁に直す. $hex = substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) . substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) . substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ); } // hexdecで10進数に変換. $rgb = array_map( 'hexdec', [ substr( $hex, 0, 2 ), substr( $hex, 2, 2 ), substr( $hex, 4, 2 ) ] ); // RGBの数値を0~1の範囲に変換. $rgb = array_map( function( $part ) { return $part / 255; }, $rgb ); // ここからRGBをHSLに変換. // r,g,bの最大値と最小値を見つける. $min = min( $rgb ); $max = max( $rgb ); // 輝度は最大値と最小値を足して2で割って算出. $luminace = ( $min + $max ) / 2; if ( $max === $min ) { // 最大値=最小値の場合、色相と彩度は0. $hue = 0; $saturation = 0; } else { if ( $luminace < 0.5 ) { // 輝度が0.5以下の場合の彩度 $saturation = ( $max - $min ) / ( $max + $min ); } elseif ( $luminace > 0.5 ) { // 輝度が0.5以上の場合の彩度 $saturation = ( $max - $min ) / ( 2 - $max - $min ); } if ( $max === $rgb[0] ) { // Rが最大の場合の色相 $hue = ( $rgb[1] - $rgb[2] ) / ( $max - $min ); } elseif ( $max === $rgb[1] ) { // Gが最大の場合の色相 $hue = 2 + ( $rgb[2] - $rgb[0] ) / ( $max - $min ); } elseif ( $max === $rgb[2] ) { // Bが最大の場合の色相 $hue = 4 + ( $rgb[0] - $rgb[1] ) / ( $max - $min ); } // 色相を°にする. $hue = round( $hue * 60 ); if ( $hue < 0 ) { // 色相が負の値になった場合は360を足して正の値にする. $hue = $hue + 360; } // 彩度を%表記にして四捨五入. $saturation = round( $saturation * 100 ); } // 輝度を%表記にして四捨五入. $luminace = round( $luminace * 100 ); if ( $echo ) { // cssで使える形で出力. return 'hsl(' . $hue . ',' . $saturation . '%,' . $luminace . '%)'; } else { return array( $hue, $saturation, $luminace ); } } my_hex2hsl('#74ac53') // [ 98, 35, 50 ] my_hex2hsl('#74ac53',TRUE) // 'hsl(98, 35%, 50%)'
スポンサーリンク
コメント
この記事へのコメントはありません。
コメントをどうぞ