Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript "Jigsaw puzzle" with irregular .png shapes

Soooo, what I'm trying to do is essentially a jigsaw puzzle. On the left side is an area with a stack of a dozen or so overlapping .png files of "ripped" paper pieces (all different irregular shapes with alpha) that when put together, in order on the right side, form a sheet of paper with notes on it. A visual (disregard rotated pieces):

enter image description here Nothing new I know, but my two main caveats in developing this are that it has to work in ie8+ and on touch devices. So this means no flash (where this would of been very easy) and no canvas (stupid ie); which leaves me with js and maybe svg?

The drag and drop part in js is easy enough but the issue I'm having is that, as I'm sure you know, the alpha channel is ignored and the irregular ripped piece is actually a rectangle. Which makes this unusable given that pieces are a stack with pieces overlapping each other.

I can do granular hit detection on the drop by using an image map and setting a variable on rollover.

I've looked around a lot (here + google) and tried some ideas but I'm unable to solve the irregular shape select/drag issue. Any ideas?

Thanks for your time.

like image 818
Erich Boyer Avatar asked Nov 04 '22 02:11

Erich Boyer


2 Answers

Low-tech solution

Nested elements with absolute position

If you're willing to spend a little extra time, there's a way to achieve this fairly closely, without having to use Flash, Canvas, SVG, or even image maps. And unlike an image map, it allows you to nest related content inside each hotspot if needed (e.g., pop-ups).

In the simplest case, you could use a single rectangular hyperlink hotspot for each piece of the puzzle. Obviously that greatly limits the range of shapes you can support (without interfering with overlapping elements).

But, if you take that hyperlink tag and give it a number of span tag children, and give each one absolute position (relative to the hyperlink), and apply the appropriate portion of the image to the background, then you can "construct" irregular image shapes that occupy a single irregular hotspot, with relatively-little interference with overlapping elements.

In effect, the image (with areas of transparency) is treated as a sprite file, with the hyperlink tag and the child span tags each occupying one portion of the "sprite file". Most of the transparent parts of the image will not be occupied by the hyperlink tag or the span tags.

Most shapes can probably be built using a hyperlink tag and 4 - 10 spans. Granted, the more irregular the shapes are, the more spans it will tend to require.

I've done this before, to create hotspots for each of the states on a US map, without using an image map (or Flash, Canvas, SVG), and it wasn't nearly as problematic as you'd think. It just requires a bit of time to figure out the details of how to break up each shape into the right number of rectangles.

The catch

Rounding error on mobile devices

Here's the catch, and it's a doozy. When a web page is scaled on mobile devices (and a regular page is almost always scaled on smaller devices), that introduces a rounding error that causes the px placement of the hyperlink tag and the span tags to possibly vary by at least 1 pixel horizontally and/or vertically. This also happens if desktop browsers are scaled; it's just that desktop browsers are not often scaled.

What would happen is that you would tend to wind up with 1 pixel or so of separation (or overlap) between the different parts of each shape. In many cases, that will tend to be very obvious and not acceptable visually. And depending on the implementation, the locations can vary by as much as 2px or 3px. When it occurs it's difficult to solve, and there are limits to how much of it can be solved.

Last I checked, Firefox is the only browser that's smart enough about rounding px values on scaled pages to avoid this problem. Hopefully other browsers will eventually support it better, as even simple pages often suffer from rounding errors.

The solution

Separate the images from the hotspots

The rounding error isn't much of a problem with hotspots (where precision isn't important). Where it really causes problems is with images (when you see an image not lining up where it should).

It may be possible to avoid the worst of the image rounding errors by doing the following:

  • Have one set of HTML code for the hotspots, same as described above, except don't display any part of the images in the hotspots. Give them all transparent backgrounds.
  • Have another set of HTML code for the images. Each one would be a single rectangular element that displays all of the image.
  • Place each image at the same position as the related hotspot.
  • Make sure the set of hotspots and the set of images both have the same z-index order. All of the hotspots will be on top of all of the images, but within the hotspots and within the images the order needs to be consistent.
  • When the hotspot for a piece is dragged, update the position of the related image to keep them at the same location. In effect, the image shadows the hotspot while it's being dragged.
like image 87
11 revs Avatar answered Nov 15 '22 06:11

11 revs


Isn't ExplorerCanvas an option for you? I would think that that would allow you to create a canvas-based solution. That will be much better than anything done with plain html element manipulation through javascript

like image 22
Achilles Avatar answered Nov 15 '22 05:11

Achilles