Чтобы сделать это, вам нужно иметь возможность считывать пиксельные данные вашего изображения.
Элемент canvas и его 2D- и webgl-контексты являются единственными веб-API, способными сделать это, но чтобы это работало, вы должны обслуживать свое изображение в соответствии с тем же источником происхождения (то есть вы не можете сделать это с изображением, полученным с другого сервера).
Если Вы можете выполнить это требование, тогда это относительно просто:
- нарисуйте свое изображение на холсте
- захватите данные пикселей
- в обработчике события мыши, преобразуйте координаты, поэтому они относятся к координатам изображения
- проверить, является ли пиксель в координатах этого события прозрачным (
0
)
Вот простая демонстрация с использованием 2D-контекста и событие mousemove, вы также можете изменить его на щелчок:
onload = (evt) => { // wait for the resource to be fully loaded
const img = document.getElementById('img');
// we create a canvas element
const canvas = document.createElement('canvas');
// set the canvas the same size as the image
const width = canvas.width = img.naturalWidth;
const height = canvas.height = img.naturalHeight;
// the 2D context
const ctx = canvas.getContext('2d');
// we draw the image on the canvas
ctx.drawImage(img,0,0);
// we get the ImageData out of it
const img_data = ctx.getImageData( 0, 0, width, height );
// the pixel data is an Uint8Array as [r,g,b,a,r,g,b,a...]
// since we only want transparency, we can make an Uint32Array of it
// this way one pixel takes one slot
const pixels = new Uint32Array( img_data.data.buffer );
// now we can start listening to mouse events
img.onmousemove = (evt) => {
// get the current BoundingBox of our element
const bbox = img.getBoundingClientRect();
// transform the event's coords
const { x, y } = getRelativeCoords( evt, bbox, width, height );
// the index in our linear array
const px_index = (y * width) + x;
// if this pixel is transparent, then it would be 0
const over_color = pixels[ px_index ] !== 0;
img.classList.toggle( 'over-color', over_color );
};
};
function getRelativeCoords( mouseevt, bbox, original_width, original_height ) {
// the position relative to the element
const elem_x = mouseevt.clientX - bbox.left;
const elem_y = mouseevt.clientY - bbox.top;
// the ratio by which the image is shrinked/stretched
const ratio_x = original_width / bbox.width;
const ratio_y = original_height / bbox.height;
// the real position in the the image's data
const x = Math.round(elem_x * ratio_x);
const y = Math.round(elem_y * ratio_y);
return { x, y };
}
.over-color {
cursor: pointer;
}
img { border: 1px solid; width: 300px }
<img id="img"
src="https://upload.wikimedia.org/wikipedia/commons/4/47/PNG_transparency_demonstration_1.png"
crossorigin>