EyeDropper API を使用して画面上のピクセルの色を選択する

EyeDropper API を使用すると、作成者はブラウザ提供のスポイトを使用してカスタム カラー選択ツールを構築できます。

EyeDropper API とは何ですか?

多くのクリエイティブ アプリでは、ユーザーはアプリ ウィンドウの一部または画面全体から色を選択できます。通常はスポイトのメタファーが使用されます。

たとえば Photoshop では、ユーザーがキャンバスから色をサンプリングできるため、色を推測して間違いを犯す心配がなくなります。PowerPoint にはスポイトツールもあります。これは、シェイプの輪郭や塗りつぶしの色を設定するときに便利です。Chromium DevTools にも、CSS スタイルパネルで色を編集するときに使用できるアイドロッパーが用意されているため、色コードを覚えておく必要や、他の場所からコピーする必要はありません。

ウェブ技術を使用してクリエイティブなアプリを構築する場合は、ユーザーに同様の機能を提供できます。しかし、これをウェブ上で行うのは困難です。現在のブラウザタブだけでなく、デバイスの画面全体(たとえば、別のアプリからのもの)から色をサンプリングしたい場合は特にそうです。ウェブアプリが独自のニーズで使用できる、ブラウザ提供のスポイトツールはありません。

<input type="color"> 要素はそれに近いものです。デスクトップ デバイスで実行されている Chromium ベースのブラウザでは、カラー選択ツールのプルダウンに便利なスポイトが表示されます。ただし、この方法を使用すると、アプリを CSS でカスタマイズし、JavaScript でラップして、アプリの他の部分で使用できるようにする必要があります。また、このオプションを選択すると、他のブラウザはこの機能にアクセスできなくなります。

EyeDropper API は、画面から色をサンプリングする方法を提供することで、このギャップを埋めます。

Chromium のカラー選択ツール。

EyeDropper API を使用する方法

ブラウザ サポート

対応ブラウザ

  • Chrome: 95。
  • Edge: 95。
  • Firefox: サポートされていません。
  • Safari: サポートされていません。

ソース

機能の検出とブラウザのサポート

まず、API を使用する前に、API が使用可能であることを確認します。

if ('EyeDropper' in window) {
  // The API is available!
}

EyeDropper API は、バージョン 95 以降の Chromium ベースのブラウザ(Edge や Chrome など)でサポートされています。

API の使用

API を使用するには、EyeDropper オブジェクトを作成し、その open() メソッドを呼び出します。

const eyeDropper = new EyeDropper();

open() メソッドは、ユーザーが画面上のピクセルを選択した後に解決される Promise を返します。解決された値は、sRGBHex 形式(#RRGGBB)でピクセルの色へのアクセスを提供します。ユーザーが esc キーを押してスポイト モードを終了すると、Promise は拒否されます。

try {
  const result = await eyeDropper.open();
  // The user selected a pixel, here is its color:
  const colorHexValue = result.sRGBHex;
} catch (err) {
  // The user escaped the eyedropper mode.
}

アプリのコードでアイドロッパーのモードをキャンセルすることもできます。これは、アプリの状態が大幅に変化した場合に役立ちます。ポップアップ ダイアログが表示され、ユーザーの入力が必要になることもあります。この時点で、スポイト モードは停止します。

スポイトをキャンセルするには、AbortController オブジェクトのシグナルを使用して、open() メソッドに渡します。

const abortController = new AbortController();

try {
  const result = await eyeDropper.open({signal: abortController.signal});
  // ...
} catch (err) {
  // ...
}

// And then later, when the eyedropper mode needs to be stopped:
abortController.abort();

これらをすべて組み合わせると、再利用可能な非同期関数を次のように作成できます。

async function sampleColorFromScreen(abortController) {
  const eyeDropper = new EyeDropper();
  try {
    const result = await eyeDropper.open({signal: abortController.signal});
    return result.sRGBHex;
  } catch (e) {
    return null;
  }
}

試してみよう:

Windows または Mac で、Microsoft Edge または Google Chrome 95 以降を使用して、EyeDropper のデモのいずれかを開きます。

たとえば、カラーゲームのデモを試します。[再生] ボタンを押して、制限時間内に、上部にある色付きの正方形と一致する色を下部のリストからサンプリングします。

カラーゲームのデモ。

プライバシーとセキュリティに関する考慮事項

一見シンプルなこのウェブ API には、プライバシーとセキュリティに関する潜在的な懸念が隠れています。悪意のあるウェブサイトが画面のピクセルを読み取るようになったらどうなりますか?

この問題に対処するために、API 仕様では次の対策が必要です。

  • まず、この API では、ユーザーの意図なしにスポイト モードを開始することはできません。open() メソッドは、ユーザー操作(ボタンのクリックなど)に応じてのみ呼び出すことができます。
  • 2 つ目に、ユーザーの意図なしにピクセル情報を取得することはできなくなります。open() から返される Promise は、ユーザー アクション(ピクセルのクリック)に応答して色値に解決されます。そのため、ユーザーに気付かれることなく、バックグラウンドでスポイトを使用できません。
  • ユーザーがスポイト モードを簡単に認識できるように、ブラウザはモードを明確にする必要があります。そのため、通常のマウスカーソルは少し遅れて消え、代わりに専用のユーザー インターフェースが表示されます。また、ユーザーが拡大鏡を表示する時間を確保するため、スポイト モードの開始からピクセルを選択できるまでの間も遅延が発生します。
  • 最後に、ユーザーは(esc キーを押すことで)いつでもスポイト モードをキャンセルできます。

フィードバック

Chromium チームでは、EyeDropper API の感想をお聞かせください。

API 設計について教えてください

API が想定どおりに動作しない点はありますか?または、アイデアを実装するために必要なメソッドやプロパティが不足している場合はどうすればよいですか?セキュリティ モデルに関するご質問やご意見がございましたら、API の GitHub リポジトリで仕様に関する問題を報告するか、既存の問題にコメントを追加します。

実装に関する問題を報告する

Chromium の実装にバグが見つかりましたか?それとも、実装が仕様と異なるのでしょうか?new.crbug.com でバグを報告します。できるだけ詳細な情報を含め、再現手順を簡単に説明してください。[コンポーネント] ボックスに Blink>Forms>Color を入力します。Glitch は、すばやく簡単に再現を共有するのに最適です。

API のサポートを表示する

EyeDropper API を使用する予定ですか?公開サポートは、Chromium チームが機能に優先順位を付ける際に役立ちます。また、他のブラウザ ベンダーに、それらのサポートがいかに重要であるかを示すことができます。ハッシュタグ #EyeDropper を使用して @ChromiumDev にツイートを送信し、どこでどのように使用しているかをお知らせください。

関連情報

謝辞

EyeDropper API は、Microsoft Edge チームの Ionel Popescu によって仕様が定義され、実装されました。この投稿は Joe Medley が確認しました。