Kilroy 365

Microsoft365 主にPowerPlatformについての備忘録

PowerAppsでHSLAカラーピッカーコンポーネントを作ってみました。 その1

f:id:KilroyWaaasHere:20210914034532p:plain

はじめに

Twitterを流し読みしていると、こんなツイートが流れてきました。

いつもPower Pointを中心にいろいろなデザイン関連のツイートをされているネスコプラズムさんのツイートでした。HSL、便利そう!

 

Power Appsでの色指定

Power Appsでの色指定は、Color列挙体(組み込み色の名前で指定)、ColorValue(16進数値で指定)、RGBA(Red,Green,Blueの3原色ブレンド+不透明度で指定)の3種類のやり方があります(以下参照)。

docs.microsoft.com

僕は上記のdocsを参照し、代表的な色を色名で直接指定するか、その色のRGBAを取ってきて微調整するか、というやりかたがほとんどでしたが、微妙な色の調整やトーンの統一など、とてもやりにくいというのが本音でした。


HSLAの利点

HSLAは上記のツイートにあるように、Hue(色相)をまず選び、Saturation(彩度)、Lightness(輝度)を調整して同系色で異なるトーンの色を作ったり、その逆でトーンを固定し、同じトーンの異なる色味の色を作るなど、直感的に色を作る、調整することがとても簡単です。これをPower Appsで利用できたらいいのに!ということで、実装できる方法はないのか調べてみました。

調べると、HSL➡RGBの計算式があるようで、沢山ヒットしますし、他言語でのコードサンプルも結構出てきます。
単純に計算式そのものが載っているこちらのページの情報を参考に、実装していくことにしました。

www.peko-step.com

 

HSLA→RGBAの計算

With関数を使えば、ほぼそのまんま記述できます。

H、S、L、Aそれぞれの値をスライダーで調整することとし、場合分けをちょっと整理して、コードはこんな感じです。

  RGBA(
        Round(
            With(
                {
                    MAX: If(
                        sldL.Value <= 49,
                        2.55 * (sldL.Value + sldL.Value * sldS.Value / 100),
                        sldL.Value >= 50,
                        2.55 * (sldL.Value + (100 - sldL.Value) * sldS.Value / 100)
                    ),
                    MIN: If(
                        sldL.Value <= 49,
                        2.55 * (sldL.Value - sldL.Value * sldS.Value/100),
                        sldL.Value >= 50,
                        2.55 * (sldL.Value - (100 - sldL.Value) * sldS.Value/100)
                    )
                },
                If(
                    sldH.Value <= 59 || sldH.Value >= 300,
                    MAX,
                    sldH.Value >= 60 && sldH.Value <= 119,
                    (120 - sldH.Value) / 60 * (MAX - MIN) + MIN,
                    sldH.Value >= 120 && sldH.Value <= 239,
                    MIN,
                    sldH.Value >= 240 && sldH.Value <= 299,
                    (sldH.Value - 240) / 60 * (MAX - MIN) + MIN
                )
            ),
            0
        ),
        Round(
            With(
                {
                    MAX: If(
                        sldL.Value <= 49,
                        2.55 * (sldL.Value + sldL.Value * sldS.Value / 100),
                        sldL.Value >= 50,
                        2.55 * (sldL.Value + (100 - sldL.Value) * sldS.Value / 100)
                    ),
                    MIN: If(
                        sldL.Value <= 49,
                        2.55 * (sldL.Value - sldL.Value * sldS.Value/100),
                        sldL.Value >= 50,
                        2.55 * (sldL.Value - (100 - sldL.Value) * sldS.Value/100)
                    )
                },
                If(
                    sldH.Value <= 59,
                    sldH.Value / 60 * (MAX - MIN) + MIN,
                    sldH.Value >= 60 && sldH.Value <= 179,
                    MAX,
                    sldH.Value >= 180 && sldH.Value <= 239,
                    (240 - sldH.Value) / 60 * (MAX - MIN) + MIN,
                    sldH.Value >= 240,
                    MIN
                )
            ),
            0
        ),
        Round(
            With(
                {
                    MAX: If(
                        sldL.Value <= 49,
                        2.55 * (sldL.Value + sldL.Value * sldS.Value / 100),
                        sldL.Value >= 50,
                        2.55 * (sldL.Value + (100 - sldL.Value) * sldS.Value / 100)
                    ),
                    MIN: If(
                        sldL.Value <= 49,
                        2.55 * (sldL.Value - sldL.Value * sldS.Value/100),
                        sldL.Value >= 50,
                        2.55 * (sldL.Value - (100 - sldL.Value) * sldS.Value/100)
                    )
                },
                If(
                    sldH.Value <= 119,
                    MIN,
                    sldH.Value >= 120 && sldH.Value <= 179,
                    (sldH.Value - 120) / 60 * (MAX - MIN) + MIN,
                    sldH.Value >= 180 && sldH.Value <= 299,
                    MAX,
                    sldH.Value >= 300,
                    (360 - sldH.Value) / 60 * (MAX - MIN) + MIN
                )
            ),
            0
        ),
        sldA.Value / 100
    )

※sld~はスライダー。
RGBの値をそれぞれ整数にするのに、Roundを入れていますが、なくてもOKです。

不透明度のAはRGBA、HSLAどちらも同じなのでそのまま。Sliderの値が整数なので、0~100のスライダー値を100で割って出してます。
HSLAとRGBAの比較は以下のような感じ。

今日はここまで、次回に続きます。