Claude Skills Guide

Chrome Extension Eyedropper Tool: Complete Developer Guide

The Chrome extension eyedropper tool has become an essential utility for developers, designers, and power users who need to extract colors from any web page with precision. Whether you’re building a color palette extension, implementing a design system, or simply need to grab a color from a website, understanding how eyedropper tools work and how to implement them effectively can significantly improve your workflow.

Understanding the Eyedropper API

Chrome provides a native EyeDropper API that makes color sampling straightforward. This API is available in Chrome 95 and later, and it allows extensions (and web pages) to access the system’s color picker functionality directly.

The basic implementation involves creating an EyeDropper instance and calling its open() method:

const eyeDropper = new EyeDropper();

async function pickColor() {
  try {
    const result = await eyeDropper.open();
    console.log(result.sRGBHex); // Output: #ff5733
    return result.sRGBHex;
  } catch (error) {
    console.error('Color selection cancelled:', error);
  }
}

The API returns an object with sRGBHex property containing the selected color in hexadecimal format. This makes it simple to integrate with any color manipulation library or CSS variable system.

Building a Basic Eyedropper Extension

A minimal Chrome extension with eyedropper functionality requires three files: manifest.json, popup.html, and popup.js. Here’s a complete implementation:

manifest.json:

{
  "manifest_version": 3,
  "name": "Quick Color Pick",
  "version": "1.0",
  "permissions": ["activeTab"],
  "action": {
    "default_popup": "popup.html"
  }
}

popup.html:

<!DOCTYPE html>
<html>
<head>
  <style>
    body { padding: 16px; font-family: system-ui; }
    button { 
      padding: 8px 16px; 
      background: #4a90d9; 
      color: white; 
      border: none; 
      border-radius: 4px; 
      cursor: pointer;
    }
    #result { margin-top: 12px; }
    .color-swatch { 
      display: inline-block; 
      width: 24px; 
      height: 24px; 
      vertical-align: middle; 
      border: 1px solid #ccc;
    }
  </style>
</head>
<body>
  <button id="pickColor">Pick Color</button>
  <div id="result"></div>
  <script src="popup.js"></script>
</body>
</html>

popup.js:

document.getElementById('pickColor').addEventListener('click', async () => {
  const eyeDropper = new EyeDropper();
  
  try {
    const result = await eyeDropper.open();
    const color = result.sRGBHex;
    
    document.getElementById('result').innerHTML = `
      <span class="color-swatch" style="background: ${color}"></span>
      <code>${color}</code>
    `;
    
    // Copy to clipboard
    await navigator.clipboard.writeText(color);
  } catch (error) {
    console.error('Eyedropper error:', error);
  }
});

Advanced Features for Power Users

Beyond basic color picking, you can enhance your extension with additional features that developers and designers frequently need.

Color History and Storage

Store recently picked colors using Chrome’s storage.local API:

async function saveColorToHistory(hexColor) {
  const { colorHistory = [] } = await chrome.storage.local.get('colorHistory');
  
  const newHistory = [
    { color: hexColor, timestamp: Date.now() },
    ...colorHistory.filter(c => c.color !== hexColor)
  ].slice(0, 20); // Keep last 20 colors
  
  await chrome.storage.local.set({ colorHistory: newHistory });
}

Color Format Conversion

Users often need colors in different formats. Implement conversions for RGB, HSL, and CSS variables:

function hexToRgb(hex) {
  const r = parseInt(hex.slice(1, 3), 16);
  const g = parseInt(hex.slice(3, 5), 16);
  const b = parseInt(hex.slice(5, 7), 16);
  return `rgb(${r}, ${g}, ${b})`;
}

function hexToHsl(hex) {
  let r = parseInt(hex.slice(1, 3), 16) / 255;
  let g = parseInt(hex.slice(3, 5), 16) / 255;
  let b = parseInt(hex.slice(5, 7), 16) / 255;

  const max = Math.max(r, g, b), min = Math.min(r, g, b);
  let h, s, l = (max + min) / 2;

  if (max === min) {
    h = s = 0;
  } else {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch (max) {
      case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
      case g: h = ((b - r) / d + 2) / 6; break;
      case b: h = ((r - g) / d + 4) / 6; break;
    }
  }

  return `hsl(${Math.round(h * 360)}, ${Math.round(s * 100)}%, ${Math.round(l * 100)}%)`;
}

Integration with Design Systems

For teams using design tokens, automatically map picked colors to the nearest token:

const designTokens = {
  'primary': '#4a90d9',
  'secondary': '#6c757d',
  'success': '#28a745',
  'danger': '#dc3545',
  'warning': '#ffc107'
};

function findNearestToken(hexColor) {
  const target = hexToRgbValues(hexColor);
  
  let nearest = null;
  let minDistance = Infinity;

  for (const [name, tokenHex] of Object.entries(designTokens)) {
    const token = hexToRgbValues(tokenHex);
    const distance = Math.sqrt(
      Math.pow(target.r - token.r, 2) +
      Math.pow(target.g - token.g, 2) +
      Math.pow(target.b - token.b, 2)
    );
    
    if (distance < minDistance) {
      minDistance = distance;
      nearest = name;
    }
  }

  return { token: nearest, distance: minDistance };
}

Browser Compatibility and Fallbacks

The EyeDropper API is Chrome-specific. For extensions targeting multiple browsers, implement a fallback using canvas-based color sampling from a screenshot:

async function fallbackColorPick() {
  // Request screenshot capture permission first
  const stream = await navigator.mediaDevices.getDisplayMedia({
    video: { displaySurface: 'browser' }
  });
  
  const video = document.createElement('video');
  video.srcObject = stream;
  await video.play();

  const canvas = document.createElement('canvas');
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  
  const ctx = canvas.getContext('2d');
  ctx.drawImage(video, 0, 0);

  // Use a custom color picker overlay UI
  // ... implementation details

  stream.getTracks().forEach(track => track.stop());
}

Performance Considerations

When implementing color picking in your extension, consider these performance optimizations:

  1. Lazy loading: Only load color manipulation libraries when needed
  2. Debouncing: Prevent rapid-fire color selections from causing UI jank
  3. Web Workers: Offload color conversion calculations to keep the UI responsive
function debounce(func, wait) {
  let timeout;
  return function executedFunction(...args) {
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(this, args), wait);
  };
}

Security and Permissions

The EyeDropper API requires user activation and does not work in background scripts. Ensure your extension handles this correctly by triggering the eyedropper from a user-initiated action like a button click. The API also respects the user’s system-level color picker preferences.

For enterprise deployments, be aware that some organizations disable the eyedropper API through group policies. Always provide alternative workflows for users in restricted environments.

Conclusion

The Chrome extension eyedropper tool provides a powerful, native way to sample colors from any web page. By understanding the EyeDropper API and implementing proper fallbacks, you can build robust color picking functionality that serves both developers and designers effectively. The key is to focus on user experience—providing instant feedback, multiple color formats, and seamless integration with existing design workflows.

Built by theluckystrike — More at zovo.one