Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I know if I am clicking on a transparent or non-transparent part of a png on a web page?

We have a quiz that we developed in Flash years ago that used hit areas to determine whether someone clicked on the appropriate portion of an image (think 'Anatomy Quiz'). These hit areas were very tedious to outline and there is no way to reuse the outline coordinate data...

Now, we're trying to re-do the thing in HTML -- So, we have a background image of a femur and a png which sits higher in the Z-order which has a portion of it completely transparent, while the other portions have 50% grey. This is used to teach the student WHERE something is on the background femur image.

I'd love to be able to use the data from that png mask layer in a 'quizzing mode' to determine whether the student correctly clicked on a specific portion of the femur... I was thinking to set the masking png to 100% transparency (so the student doesn't see it), but if the browser knew that they were clicking in the correct area of the image (that is 100% transparent on the mask), that they clicked correctly.

Any ideas on how to accomplish this with HTML, CSS, and/or jQuery?

like image 516
Chris Brandt Avatar asked Apr 12 '11 23:04

Chris Brandt


People also ask

Does a PNG have a transparent background?

If you are using a screenshot or a PNG image, it will default to have a transparent background.


2 Answers

var imgData,
     width = 200,
    height = 200;

$('#mask').bind('mousemove', function(ev){
    if(!imgData){ initCanvas(); }
    var imgPos = $(this).offset(),
      mousePos = {x : ev.pageX - imgPos.left, y : ev.pageY - imgPos.top},
      pixelPos = 4*(mousePos.x + width*mousePos.y),
         alpha = imgData.data[pixelPos+3];

    $('#opacity').text('Opacity = ' + ((100*alpha/255) << 0) + '%');
});

function initCanvas(){
    var canvas = $('<canvas width="'+width+'" height="'+height+'" />')[0],
           ctx = canvas.getContext('2d');

    ctx.drawImage($('#mask')[0], 0, 0);
    imgData = ctx.getImageData(0, 0, width, height);
}

This code loads the base64 image into a canvas, and uses getImageData to obtain a 2d RGBA representation of the image. It then uses the mouse's position to find the Alpha value (opacity) at that point in the image. Canvas ImageData is stored in a 2d array in groups of 4 (RGBA). What you're after is the "A", so every fourth value in the array. You can see this reflected in the code when discovering the pixel position, it multiplies the mouse's position by 4, and then to get at the alpha value it adds 3 (adding 0 would get you R, 1 would get you G, 2 would get you B).

https://jsfiddle.net/ey1d5vgr/

As of 2011, this didn't work in IE. Also, the image has to be on the same domain as the site, so no external images which is why this example used a data URI.

like image 157
Nobody Avatar answered Oct 01 '22 21:10

Nobody


I think you'll need to either process that server-side, or find a javascript library that can decode the image pixel by pixel.

A click event on a transparent part of a PNG still gets captured by the PNG. This is fairly unintuitive for a semi-transparent PNG which is z-indexed above something else, but that's standard behavior.

like image 34
Leopd Avatar answered Oct 01 '22 20:10

Leopd