EyeDropper API: activación y privacidad del color
Usa EyeDropper con activación explícita, cancelación visible, contexto seguro y manejo privado de colores sRGB.
BotBrowser Team
Quieres la documentación estructurada de Plataforma?
Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.
EyeDropper API permite que una persona elija un color de la ventana tras una acción explícita. La interacción no entrega un flujo de píxeles en segundo plano, un perfil de calibración ni una forma de identificar una pantalla. La aplicación recibe un valor hexadecimal sRGB al terminar y debe mantener visibles la cancelación, el rechazo y la falta de soporte. Los contextos controlados de BotBrowser pueden ejecutar una página autorizada, invocar EyeDropper desde una acción declarada y registrar resultados visibles cuando el runtime expone la API; BotBrowser no puede fabricar activación transitoria, leer píxeles sin interacción, calibrar una pantalla ni garantizar el mismo selector nativo en todos los hosts. Consulta también gestión de color CSS y accesibilidad de pantalla y eventos de puntero y modalidades de entrada.
TL;DR
- Invoca
EyeDropper.open()directamente desde una acción mientras la activación transitoria siga válida. - Comprueba el contexto seguro y el constructor, y conserva un control de color normal si falta la API.
- Trata
sRGBHexcomo valor de la aplicación, no como medición de una pantalla física. - Usa
AbortControllerpara cancelar y distingue cierre del selector de una selección. - No guardes capturas, coordenadas, historial de ventana ni muestras más tiempo del necesario.
Contents
- Proteger el selector con activación
- Modelar selección, cancelación y alternativa
- Mantener el color dentro de un límite privado
- Verificar el ciclo con un fixture acotado
- Conclusión práctica
Proteger el selector con activación
La propuesta EyeDropper API describe un selector que permite muestrear un color después de una invocación intencional. La referencia MDN EyeDropper API documenta EyeDropper y open(). La API requiere contexto seguro y activación transitoria. El clic o comando de teclado debe ser el límite de propiedad de toda la solicitud.
No esperes una promesa ajena entre la acción y open(): una petición, un turno de renderizado o un callback en cola puede consumir la activación. Valida condiciones locales baratas en el manejador y deja el trabajo lento para después del resultado. Detecta el constructor y el contexto seguro; la ausencia es una capacidad no disponible, no permiso para muestrear otra superficie.
La guía de Chrome para EyeDropper muestra un flujo común, pero no promete la API en cada navegador o webview. Un worker no hereda la activación de la página. La página abre el selector y después envía al worker solo el valor elegido o la cancelación.
La activación pertenece a la persona. Usa un registro pequeño:
const pickerState = {
phase: 'idle',
outcome: 'unavailable',
sequence: 0,
};
phase describe el ciclo y outcome describe el resultado visible. sequence evita que una promesa antigua reemplace una paleta nueva. No guardes URL completa, cuenta ni captura. El control debe tener nombre accesible, activación por teclado, foco estable y una alternativa visible para quien no tenga la API.
Modelar selección, cancelación y alternativa
open() resuelve con sRGBHex cuando la persona selecciona. La selección termina el selector; otra muestra necesita otra acción visible. Cerrar, pulsar Escape, navegar o abortar con AbortController son cancelaciones normales. Distingue cancelled de rejected: la primera es decisión de la persona o del ciclo, la segunda es rechazo del runtime.
La alternativa debe ser una ruta de producto: <input type="color">, campo hexadecimal editable o paleta documentada. Conserva el mismo formato y validación. No inventes un significado para el valor vacío. La tabla separa capacidad y decisión:
| Resultado | Registro | Acción visible | Paso seguro |
|---|---|---|---|
| API ausente o contexto inseguro | unavailable, fallback | Mostrar control nativo o campo | Continuar con el valor alternativo |
| Acción abre selector | open, pending | Mostrar estado y cancelación | Esperar resultado terminal |
| Color elegido | selected, sRGBHex | Actualizar muestra y texto | Validar y guardar una vez |
| Persona cierra o aborta | cancelled, valor anterior | Indicar que no cambió | Volver a idle sin reintento oculto |
| Runtime rechaza | rejected, clase de causa | Explicar falta temporal | Ofrecer alternativa sin datos de píxel |
async function chooseColor(button, fallback, signal) {
if (!window.isSecureContext || !('EyeDropper' in window)) return fallback('unavailable');
const picker = new EyeDropper();
try {
const result = await picker.open({ signal });
return { outcome: 'selected', value: result.sRGBHex.toLowerCase() };
} catch (error) {
if (error?.name === 'AbortError') return fallback('cancelled');
return fallback('rejected');
}
}
Llama a chooseColor() desde el manejador de activación. No uses setTimeout, carga de página ni una continuación antigua. Conserva el valor anterior durante la espera, valida el texto devuelto y muestra un error local sin abrir de nuevo el selector.
Mantener el color dentro de un límite privado
Un color puede pertenecer a un documento privado o a un proyecto no publicado. Conserva el valor solo para la función que lo necesita. La API no entrega una captura: no pidas captura de pantalla, no uses canvas para sustituir un píxel arbitrario y no infieras el diseño de la pantalla por una secuencia de colores.
El valor sRGB sirve para un token, tema o anotación; no es calibración de luminancia ni garantiza la misma apariencia en otro monitor. CSS color management, perfiles, HDR y zoom cambian la apariencia. Si importa la coincidencia visual, pide confirmación y guárdala separada del color.
La página visible posee activación y ciclo. Un worker recibe { outcome: 'selected', value: '#aabbcc' } solo después de elegir; un iframe recibe el mínimo valor con origen y esquema validados. BotBrowser puede comparar resultados visibles autorizados, pero no fabrica activación, calibra pantalla ni garantiza el mismo selector nativo.
Verificar el ciclo con un fixture acotado
Usa una página sintética con botón, control nativo, texto y registro. Abre solo desde el evento, limpia el controlador al salir y no retengas capturas ni coordenadas.
const record = { phase: 'idle', outcome: 'unavailable', value: null, sequence: 0 };
const controller = new AbortController();
const button = document.querySelector('[data-pick-color]');
button.addEventListener('click', async () => {
record.sequence += 1;
record.phase = 'pending';
try {
if (!window.isSecureContext || !('EyeDropper' in window)) {
record.outcome = 'unavailable';
return showNativeColorControl();
}
const { sRGBHex } = await new EyeDropper().open({ signal: controller.signal });
record.value = sRGBHex.toLowerCase();
record.outcome = 'selected';
} catch (error) {
record.outcome = error?.name === 'AbortError' ? 'cancelled' : 'rejected';
} finally {
record.phase = 'idle';
}
});
function disposePicker() {
controller.abort();
button.replaceWith(button.cloneNode(true));
}
| Caso | Resultado esperado | Demuestra | No demuestra |
|---|---|---|---|
| Falta constructor o contexto seguro | unavailable, alternativa visible | Detección y continuidad | Que pantalla o navegador estén defectuosos |
| Activación abre selector | pending hasta resultado | Propiedad de la acción | Que un timer o worker pueda abrirlo |
| Persona elige color | selected, sRGBHex de seis dígitos | Una validación y commit | Calibración de pantalla |
| Cierre o aborto | cancelled, conserva valor | Cancelación reversible | Que deba reintentarse en silencio |
| Runtime rechaza | rejected, alternativa usable | Separación del rechazo | Causa fuera del límite documentado |
Registra solo browserVersion, runtimePath, secureContext, outcome, valuePresent, fixtureId y sequence. Repite tras cambios del navegador, pantalla, política o alternativa y compara el primer campo distinto. No uses el fixture para ordenar navegadores, reconstruir pantallas o inferir intención.
Public sources
- EyeDropper API proposal (WICG)
- MDN: EyeDropper API
- Chrome for Developers: EyeDropper API
- BotBrowser: Advanced features
Conclusión práctica
Abre EyeDropper solo desde una acción visible, conserva una alternativa nativa o escrita y separa selección, cancelación, rechazo y falta de soporte. Retén el valor sRGB solo para la decisión del producto, nunca como afirmación de pantalla o identidad. Repite el fixture después de cambios y parte del primer estado visible que cambió.
Este artículo forma parte de la guía: Superficies de la plataforma web: mapa de revisión
Artículos Relacionados
Gestión del color CSS y accesibilidad de la pantalla
PlataformaWindow Management API: límites entre varias pantallas
PlataformaWeb Share API: límites de permisos y respaldos seguros
PlataformaWeb Share API y uso compartido iniciado por la persona
PlataformaPreferencias de media queries y control del usuario
PlataformaPresentation API: límites de pantalla y sesión
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.