image map not working on iOS devices, with large images that get rescaled by the device - iphone

I'm developing an internal web app on our company intranet using PHP. One section of the app displays a couple of high resolution images to the user. These images are in the region of 5000x3500 pixels. Each image has an image map (using rectangular areas), and all works fine in the desktop browsers I've tried.
The problem I'm finding, is that when users access the site via their iOS devices, the images are being rescaled by safari on the device, however the image map coordinates are not being adjusted to match.
An example of the HTML being generated by my PHP is as follows:
<img src="largeimage.jpg" width="5000" height="3500" usemap="#examplemap">
<map name="examplemap">
<area shape="rect" coords="0,0,5000,500" href="blah1"/>
<area shape="rect" coords="0,500,2500,3500" href="blah2"/>
<area shape="rect" coords="2500,500,5000,3500" href="blah3"/>
</map>
(The actual rectangle coordinates in the image map are calculated as a percentage of the image size).
I know that safari is resizing the image due to memory constraints on the device, but I need to either find a way of scaling the image map to suit, or replacing the image map with something else that will do the same job. Can anyone offer any advise?

This topic was solved here on stackoverflow: jquery-image-map-alternative
The best idea is to use absolutely positioned anchors (also as suggested by steveax) instead of imagemap.
Update
As this is an old question, you might consider using SVG maps these days. They are supported in all modern browsers, works responsively and are as easy to use as image maps. (thanks to user vladkras for reminder)

Why don't you use Responsive Image Maps instead. This way you can still use poly maps for oddly shaped items.
http://mattstow.com/experiment/responsive-image-maps/rwd-image-maps.html
It's as easy as adding the script. And one line of javascript:
$('img[usemap]').rwdImageMaps();

Nathan's comment is correct. You need to fix the viewport to prevent scaling. Basically, either specify a fixed pixel width, or set the scale to 1.0 and set user-scalable=no
See this document for reference:
http://developer.apple.com/library/ios/#DOCUMENTATION/AppleApplications/Reference/SafariWebContent/UsingtheViewport/UsingtheViewport.html
An alternative to using the area tag is to use javascript with events x/y & bounds for your hit areas.

I ran into this limitation recently on a project where we needed to be able to zoom and this is what I did to solve it:
Split the image up into 4 quadrants
Placed the 4 images into divs with width and height set to 50% and position: absolute;
Absolutely positioned <a> elements within the quadrant's parent element using
percentage values and a high z-index
Like this:
CSS
#map-frame { position: relative; }
.map {
display: block;
position: absolute;
width: 5%;
height: 3%;
z-index: 99;
}
.q {
position: absolute;
width: 50%;
height: 50%;
}
.q img {
display: block;
max-width: 100%;
}
.q1 {
top: 0;
left: 0;
}
.q2 {
top: 0;
right: 0;
}
.q3 {
bottom: 0;
left: 0;
}
.q4 {
bottom: 0;
right: 0;
}
HTML
<div id="map-frame">
<a class="map" href="foo.html" style="top: 20%; left: 20%;">
<a class="map" href="foo.html" style="top: 40%; left: 20%;">
<a class="map" href="foo.html" style="top: 20%; left: 40%;">
<a class="map" href="foo.html" style="top: 40%; left: 40%;">
<div id="q1" class="q">
<img alt="" src="q1.jpg" />
</div>
<div id="q2" class="q">
<img alt="" src="q2.jpg" />
</div>
<div id="q3" class="q">
<img alt="" src="q3.jpg" />
</div>
<div id="q4" class="q">
<img alt="" src="q4.jpg" />
</div>
</div>

Put all the content INSIDE A TABLE. Set to 100% width. The iphone doesnt seem to scale tables... I was struggling with this problem as i had my images just lose, or inside a div.
none of the rect coords links were working. But when i put the whole lot inside a table... Well, just try it and see :)

I dig out this post because I've just found a solution to get image map working on iOS.
Put your map within an anchor and listen click/tap events on it, to check if the target element matches with a map's area.
HTML
<a id="areas" href="#">
<img src="example.jpg" usemap="#mymap" width="1024" height="768">
<map name="mymap">
<area id="area1" shape="poly" coords="X1,Y1,X2,Y2...">
<area id="area2" shape="poly" coords="X1,Y1,X2,Y2...">
<area id="area3" shape="poly" coords="X1,Y1,X2,Y2...">
</map>
</a>
JAVASCRIPT
$("#areas").on("click tap", function (evt) {
evt.preventDefault();
if (evt.target.tagName.toLowerCase() == "area") {
console.log("Shape " + evt.target.id.replace("area", "") + " clicked!");
}
});
Tested on iPad4 with mobile safari 6.0

Do not use Default <img usemap="#map"> and <map name="map"> change it. Like <img usemap="#mapLink"> and <map name="mapLink">. It's working !!!

Simply using a # in the usemap attribute appears to solve the problem on iPhone.
For example <img usemap="#mapLink"> and <map name="mapLink">

My solution was easy. I just assigned a height and width in the DIV's css to match the size of the image and everything worked fine. Original image size was 825 x 1068, so
<div style= width: 825px; height: 1068px;">
...
</div>
Hope it helps.

I solved this with only 1 line of code, no JavaScript. Only CSS, you need to use zoom property to scale your image and everything will work fine, just like this
img {
zoom: 0.3;
}

<img src="largeimage.jpg" width="5000" height="3500" usemap="#examplemap">
<map name="examplemap">
<area shape="rect" coords="0,0,100%,10%" href="blah1"/>
<area shape="rect" coords="0,10%,50%,70%" href="blah2"/>
<area shape="rect" coords="50%,10%,100%,70%" href="blah3"/>
</map>
please try using percentage values inside coordinates

Related

JSSOR: Image is smaller than slide and should not be centered

first of all: GREAT STUFF!!
SITUATION: The image loaded in my slider are smaller than the slides container. Using "$FillMode: 5" I can make sure that images have the right size to display within the slides-container, but they are centered.
Q: Is there a way to have them align to the right, so that i can display the caption to the left of it.
TRIED: using CSS to align the image: neither
#slides img { float: left !important };
nor
#slides img {
position: absolute !important;
right: 0px !important;
}
did the job.
A:
After some fiddling and around analyzing the actual sourcecode generated by the script i found out that
using #slides results in a coding error as the tag "" is duplicated (for whatever reason) and would therefor give 2 identical IDs, so better use ".slides" / ""
the following CSS does the job an aligns a smaller image to the right of the slide
.slides {
div {
img {
right: 0px !important;
left: auto !important;
}
}
Jssor slider will fill and align image (in following format) automatically according to $FillMode,
<img u="image" src="url" />
To fill image manually by your self, please remove u="image",
<img src="url" />

YUI pure css fixed width

Can someone show me an example of how I might use purecss.io to implement a fixed width/responsive design, similar to the 960 grid like bootstrap, etc???
The fluid width simply won't work for my particular design, here is what I currently have:
<nav class="pure-u" id="menu">
<div class="pure-menu pure-menu-open">
<a class="pure-menu-heading" href="/">HOME</a>
<ul>
<li class="pure-menu-selected">Clients</li>
<li>Company</li>
<li>Portfolio</li>
<li>Service</li>
<li>Contact</li>
</ul>
</div>
</nav>
<div class="pure-u-1" id="main">
This is the main content area
</div>
</div>
</body>
I need the above wrapped in a containing DIV which centers and has a fixed width of 960 but adjusts responsively as required...
Any ideas???
Regards,
Alex
hope this helps: http://jsfiddle.net/pX7bD/.
The idea is to wrap everything in a div that has a fixed max-width and auto horizontal margins (so it's centered).
#wrapper {
max-width: 960px;
margin: 0 auto;
}

Centering divs in HTML and CSS but cut-off on mobile screens

I have been having some real issues with CSS!
I have the following set up to centre the #Box div, which works perfectly on everything but mobile browsers. Because the screen size of the mobile browser is so narrow the left hand side keeps getting cut-off. I asked something similar previously and have tried to no avail to adjust it.
I have put the container and layout divs in since last time, but still the same problem occurs. Is there any way that I can adjust the code so that the left hand side doesn't keep getting chopped off?
.pageContainer {
margin-left: auto;
margin-right: auto;
width: 100%;
height: auto;
padding-left: 1.82%;
padding-right: 1.82%;
position:relative; }
#LayoutDiv1 {
clear: both;
margin: auto;
width: 100%;
display: block;
text-align:center;
position: relative; }
#Box {
width: 487px;
height: 181px;
position: absolute;
left: 50%;
top: 236px;
margin-left: -244px;
z-index:6; }
The html:
<body>
<div class="pageContainer">
<div id="LayoutDiv1">
<div id="Twitter">
<img src="images/TwitterNORMAL.png" onmouseover="this.src='images/TwitterHOVER.png'" onmouseout="this.src='images/TwitterNORMAL.png'"/>
</div>
<div id="Facebook">
<img src="images/fbNORMAL.png" onMouseOver="this.src='images/fbHOVER.png'" onMouseOut="this.src='images/fbNORMAL.png'"/>
</div>
<div>
<img id="Box" src="images/BOX.png" width="487" height="181">
</div>
</div>
</div>
</body>
The smarter way in 2012 to do this is to use Media Queries, some inspiration here
You basically create another style sheet which is loaded only for smaller screens. It might seem like an overkill now, but as your website grows, you will thank me for suggesting this (or you cannot ;))
Also, don't do margin-left: -244px;, its hacky and can cause cross browser issues. Show us some HTML and we shall show you a cleaner way.
Are you including a viewport meta tag? It should eliminate any scaling issues you may be having in mobile.
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
To you CSS: <div>s are block elements, and their default behavior is to expand the width of their parent (100%). Those CSS declarations aren't necessary.
From your code, and layout, it doesn't look like you need #LayoutDiv1 or to use positioning.
This simpler code takes care of the left-side-cutoff (here's a fiddle):
.pageContainer {
margin:0 auto;
}
#LayoutDiv1 {
margin: auto;
text-align:center;
}
#Box {
width: 487px;
height: 181px;
top: 236px;
margin:236px auto 0;
}
And like a prev poster mentioned, you could add a #media query to load a smaller image for #Box on mobile (you can simply add a line or two [or 200] to your existing CSS file):
#media only screen and (max-width: 767px) {
#Box { background:url('imgs/mobile-hero.jpg'); }
}

jQuery UI Sortable, how to fix the list height?

I'm using jQuery UI "sortable" plugin to be able to select and sort items.
I set up the plugin to have two lists, one for "available" items, the second for "selected" items.
The plugin works as expected, I can move items from one list to the other.
However, when I remove one item from the list, the height of the list is lowered. Is there any way to fix it?
In fact, i'd like to set the outer border of both list to the initial height of the left items (at the beginning, all items are in the first list)
This picture describe what I want to do:
The red lines are what I'd like. I want both lists to have this size, fixed.
Here is my code (generated from an asp.net webpage actually) :
<script type="text/javascript">
$(function () {
$("#sourceItems").sortable({
connectWith: "#targetItems",
update: function (event, ui) {
$("#selectedUserIDs").val(
$("#targetItems").sortable('toArray')
);
},
placeholder: "ui-state-highlight"
});
$("#targetItems").sortable({
connectWith: "#sourceItems",
placeholder: "ui-state-highlight"
});
$("#sourceItems, #targetItems").disableSelection();
});
</script>
<style type="text/css">
#sourceItems, #targetItems { list-style-type: none; margin: 0; padding: 0; margin-right: 10px; background: #eee; padding: 5px; width: 230px; border:solid 1px black; }
#sourceItems li, #targetItems li { margin: 5px; padding: 5px; width: 200px; height: 12px; }
</style>
<div style="float: left; display: inline-block; width:fill-available">
<p>Available :</p>
<ul id="sourceItems" class="droptrue">
<li class="ui-state-default" id='i1'>item1</li>
<li class="ui-state-default" id='i32'>item2</li>
<li class="ui-state-default" id='i47'>item3</li>
<li class="ui-state-default" id='i46'>item4</li>
</ul>
</div>
<div style="float: left; display: inline-block;">
<p>Selected :</p>
<ul id="targetItems" class="droptrue">
</ul>
</div>
<div style="display: none">
<input name="selectedUserIDs" type="text" id="selectedUserIDs" />
</div>
The hidden input field is my container for storing selected items (posted with the form).
I've tried by adding .height($("#sourceItems).outerHeight()); to both lists, but this does not works.
I came here looking for a similar, but more generalized solution to the same problem. The solution here didn't help me, but I figured it out on my own and thought it might be helpful to share it.
I didn't want the two sortable lists to be fixed, I just wanted them to stay the same height. When you are dealing with a large number of items, having two dynamically sized boxes around the list can make it hard to work with, as the one box is so much smaller than the other. Making both boxes a fixed height is also less than optimal, as then you end up with scrollbars once your number of items in one list exceeds that height. I wanted both boxes to dynamically expand using the built-in functionality of the JQuery sortable, connectWith code, but I also wanted them to both just be set to the larger of the two. To do this I found that you can modify the padding on the lists, and that area will still be an interactable area for purposes of drag-and-drop.
So, to make two connectWith, sortable lists keep the same height, you can add the following handler for the over event:
over: function(event, ui) {
var heightDiff = $("#sourceItems").height() - $("#targetItems").height();
$("#sourceItems").css('padding-bottom', (Math.abs(heightDiff) - heightDiff) / 2 + 'px');
$("#targetItems").css('padding-bottom', (Math.abs(heightDiff) + heightDiff) / 2 + 'px');
}
Here's a fiddler example extending the other example with this event handler: http://jsfiddle.net/TLrn7/
Edit:
$(document).ready(function(){
$("#targetItems").height($("#sourceItems").height());
$("#sourceItems").height($("#sourceItems").height());
});
http://jsfiddle.net/JEY4U/1/
Old Answer:
Use a 'helper' function, which makes sure the dragged elements have proper width and height.
Something like this:
helper: function(event, ui) {
$(ui).width($(ui).width());
$(ui).height($(ui).height());
ui.children().each(function() {
$(this).width($(this).width());
});
return ui;
}
You use it like this:
$(SOME_OBJECT).sortable({
connectWith: ...,
placeholder: ...,
......
helper: function....
});
Of course you can write any costume helper function you'd like.
The jQuery UI list height is set to a specific height using CSS. Example for 300px height.
.ui-autocomplete {
max-height: 300px;
overflow-y: auto;
/* prevent horizontal scrollbar */
overflow-x: hidden;
}
/* IE 6 doesn't support max-height
* we use height instead, but this forces the menu to always be this tall
*/
* html .ui-autocomplete {
height: 300px;
}
Read the documentation here: https://jqueryui.com/autocomplete/#maxheight

GWT: Positioning DIV on top of image using getAbsoluteTop/Left - FF off by a few pixels?

I'm working on some Google Web Toolkit Code that places an AbsolutePanel on top of an image. The way I'm doing this is to:
wait until the image is loaded (i.e. width/height are >0)
get the absolute coordinates of the image in the viewport using image.getAbsoluteLeft() and image.getAbsoluteTop
Set the position of the AbsolutePanel (a direct child of the RootPanel) to the same coordinates using RootPanel.get().setWidgetPosition(myPanel, imageAbsLeft, imageAbsTop);
This works in Chrome and IE. Strangely, though, Firefox always positions the AbsolutePanel "a few" pixels (I'd say between 1 and approx 10? But it varies from page load to page load) above the image. I'm clueless as to what's causing this. Any hints much appreciated!
A live example of this is here: http://yuma-js.github.com. If you click the "Add Annotation" there's a draggable box, which movement is constrained by the AbsolutePanel. You'll notice that the constraining works perfect for Chrome, but is off for FireFox.
Morning,
well, I did some research how I could overlay an image with a another object too, and found this article: How to overlay one div over another div.
Based on that I made a similar example using SVG and drawing example, where I draw a rectangle around a space station. What I can tell you is, that you don't want to mix pixel and percentage positioning, and if you can, you should use percentage positioning!
Hope this helps somehow.
Here is my example:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<title>SVG Example</title>
<style>
html, body {
margin: 0px;
padding: 0px;
}
#container {
width: 100%;
height: 100%;
position: relative;
}
#navi,
#infoi {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
#infoi {
z-index: 10;
}
#navi img {
}
</style>
</head>
<body>
<div id="container">
<div class="navi"><img src="http://www.bing.com/fd/hpk2/SpaceStation_ROW1605701719.jpg" width="100%" height="100%"/></div>
<div id="infoi"><svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<rect x="65%" y="40%" width="20%" height="30%"
fill="none" stroke="red" stroke-width="2"/>
</svg>
</div>
</div>
<p>This example draws a fullscreen image and places a fullscreen svg element above it. The svg element then draws a rectangle based on percentage sizes,
which is around the space Station. If the browser window resizes, the size of the drawn rectanlge changes as well, to always be on top of the space
station.</p>
<p>Resources for this example where the following links:</p>
<ul>
<li><a href="https://stackoverflow.com/questions/2941189/how-to-overlay-one-div-over-another-div" >How to overlay one div over another div</a>
<li><a href="http://de.wikipedia.org/wiki/Svg" >Wikipedia: Scalable Vector Graphics</a>
<li><a href="http://www.w3.org/TR/SVG/shapes.html" >W3C Recommendation: 9 Basic Shapes</a>
</ul>
<p>Image from: Bing.com, © StockTrek/White/Photolibrary</p>
</html>