LoginSignup
0
2

More than 1 year has passed since last update.

[CSS+Javascript] CMYの減法混色をmix-blend-modeを使ってシミュレートするためのベースロジック

Last updated at Posted at 2021-02-28

はじめに

以前に書いた記事の続きに当たります。あるWEBアプリケーションのデモ開発を行った後、UIの一部、表題内容の処理部分をパーツとして分解し、JSFiddleCodePenで公開しましたので、本記事はその詳細という位置づけとなります。

目的

C、M、Y、それぞれのカラーブロックを重ね、実際に混色した際の色をシミュレートします。ベースロジックのデモのため、それぞれの色成分初期値は濃度100%とし、濃度の調整はスライダーにより、3色同比率で増減させます。

つまり、結果的には単に見た目が黒から白への濃度変化するものになるのですが、その表現方法の構築が本記事でのメインとなります。1

以下が今回の完成形です。

See the Pen stCMYblend by STSHISHO (@STSHISHO) on CodePen.

CSS設定

1-カラーブロックの定義

<div class="container">
  <div class="box box-1"></div>
  <div class="box box-2"></div>
  <div class="box box-3"></div>
</div>
.container {
  width: 100%;
}
.box {
  width: 300px;
  height: 300px;
}
.box-1 {
  /* cyan */
  background: rgba(0, 255, 255, 1);
}
.box-2 {
  /* magenta */
  background: rgba(255, 0, 255, 1);
}
.box-3 {
  /* yellow */
  background: rgba(255, 255, 0, 1);
}

上記コードの結果、以下のようになります。
cmy-01.png

2-センター揃えで横に並べる

.container {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center; /* if you need */
  height: 400px;
  position: relative; /* 中央揃えの場合は指定しなくても意図通りに表示 */
}
.box {
  width: 300px;
  height: 300px;
}

.containerの修正。以前ならfloatを使用していましたが、display: flex;で横並びにします。justify-content: center;で中央揃えになります。必要に応じてalign-itemsを指定します。今回は上下左右中央揃えにしています。
cmy-02-flex.png

3-カラーブロックを重ねる

これは単純です。.boxposition: absolute;を追加するだけです。一番最後に記述された要素が最前面になりますので、デモではYellowのカラーブロックが前面に表示されます。
cmy-03-abslt.png

4-mix-blend-modeを使う

CSSでPhotoshopのような乗算効果は再現可能か調べていたところ、こちらの記事を見つけ、MDNで仕様を確認しました。.boxmix-blend-mode: multiply;を追加して、設定完了。
cmy-04-mltply.png

スライダーを設置し、イベントリスナーを設定

<div class="slider">
  <span class="rowHead">濃度</span><input type="range" id="slider_all" min="0" max="100" step="1" value="100"><span class="rowTail">100%</span>
</div>

カラーブロックの直下にスライダーを設置し、イベントリスナーを設定します。

window.onload = () => {
  const t = document.querySelector('.container') //container全体を取得
  const s = document.querySelector('#slider_all')
  //スライダーにイベントリスナー設定
  s.addEventListener('input', e => t.style.opacity = e.target.value * 0.01, false)
}

inputで、リアルタイムに濃度が変わります。スライダーの値が0から100までなので、0.01を乗算することでそのままopacity値となり、.container全体のopacityを変更します。

最後に

上記を元に、スライダーをカラーごとに設置し、ターゲットをカラーブロックに変更することで、個別の濃度調整が可能になります。

なお、元になったWEBアプリケーションの詳細についてはいずれまとめる予定でいます。

[追記]

今回はあくまでも実際のケースに沿った表現方法の一例として、mix-blend-modeを使った方法を紹介しています。そのため、タイトルも少し修正しました。シンプルにRGB→CMY変換、減法混色をしたい場合には、@il9437さんのコメントおよびコードの方がロジックとして王道ですし、参考になると思います。

[参考]

  1. 当該のアプリケーションではC、M、Y、個別の濃度調整スライダーを実装しています。また、それぞれの色成分初期値が、例えば、シアンの初期値(濃度100%)はRGB(0, 255, 255)ではなく、RGB(65,225,210)という具合にクライアントによって変更できるようになっています。

0
2
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2