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

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

EyeDropper API とは

多くのクリエイティブ アプリケーションでは、通常はスポイトのメタファーを使用して、アプリ ウィンドウの一部や画面全体から色を選択できます。

たとえば、Photoshop では、ユーザーがキャンバスから色をサンプリングできるため、色を推測して間違えるリスクを回避できます。PowerPoint にはスポイトツールもあります。これは、図形の枠線や塗りつぶしの色を設定する際に便利です。Chromium DevTools にも、CSS スタイル パネルで色を編集する際に使用できるスポイトツールがあります。このツールを使用すると、色コードを覚えておいたり、別の場所からコピーしたりする必要がなくなります。

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

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

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

Chromium のカラー選択ツール。

EyeDropper API の使用方法

ブラウザ サポート

Browser Support

  • Chrome: 95.
  • Edge: 95.
  • Firefox: not supported.
  • Safari: not supported.

Source

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

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

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

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

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 以降を使用して、スポイトのデモのいずれかを開きます。

たとえば、カラーゲームのデモをお試しください。[再生] ボタンを押し、限られた時間内に、上部の色付きの正方形と一致する色を、下部のリストから選択します。

色のゲームのデモ。

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

この一見シンプルなウェブ API の背後には、プライバシーとセキュリティに関する潜在的に有害な懸念が隠されています。悪意のあるウェブサイトが画面のピクセルを認識し始めたらどうなるでしょうか?

この懸念に対処するため、API 仕様では次の対策が求められています。

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

フィードバック

Chromium チームは、EyeDropper API の使用感について皆様のご意見をお待ちしています。

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

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

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

Chromium の実装でバグが見つかりましたか?それとも、実装が仕様と異なるのでしょうか?new.crbug.com でバグを報告します。できるだけ詳細な情報、再現手順を記載し、[Components](コンポーネント)ボックスに Blink>Forms>Color と入力してください。

API のサポートを表示する

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

関連情報

謝辞

スポイト API は、Microsoft Edge チームの Ionel Popescu によって仕様が策定され、実装されました。この投稿は Joe Medley によってレビューされました。