CSS interactive map - css

I am not a clean CSS coder, so this may be the crux of my problem... but...I've cobbled together an interactive map from this tutorial: http://www.noobcube.com/tutorials/html-css/css-image-maps-a-beginners-guide-/.
My solution: http://www.paideiaschool.org/testing/barb_map.htm
I think I have the initial "rollovers" of the map working-- (I've only coded the first two buildings in the upper left of the map) and am happy with that.
My problem is I want the legend of the map to do the same things as the rollovers of the map. I've come up with a clumsy solution that works (labeled '1509'), but not well in all browsers, and that tells me I have gone wrong somewhere.
I'm trying to avoid javascript as well.
What is the main problem?

Here's an updated jsFiddle for part one
Here's the basics:
<div id="city-map">
<div class="pop-up">...</div>
<div class="pop-up">...</div>
...
</div>
We use an image map with anchor tags as "hot spots". We use CSS to absolutely position these "hot spots" in the proper location and we do the basic background image sprite "trick", the same you did in your original code.
However, I updated your sprite image to have two "hover" images. When making an image hover map with none-square image spots (like buildings overlapping each-other), a single hover state runs into problems with a "neighbor" icon showing up in the hot spot slice. This is due to due HTML blocks being square and not being able to draw odd shapes. We solve this by having extra images states so you can make the neighbors still look un-highlighted.
Pop-up box
<div class="pop-up">
<h1 class="title">Mac</h1>
<div class="content">Some Content</div>
</div>
All the pop-up boxes have this HTML format. I position: absolute; them off to the side with the standard left:-999em; trick. I crafted the CSS to give them a standard pop-up location with a slight space between the hot-spot box and the pop-up box. This helps ensure your mouse will "hover out" of the hot-spot when reaching for a new hot-spot. Otherwise, you'll hover over the pop-up box and it won't go away until you over off both.
<div id="city-map-legend">
<div id="glamour-photo">
<img src="..." id="mac-img" />
<img src="..." id="admin-img"/>
...
</div>
<div id="cml-list">
<h2>Around Campus</h2>
<ul>
<li><a id="mac-list" href="#">Mac</a></li>
...
</ul>
</div>
</div>
For the "map legend", I have a group of "glamour images" and a list of links. Pretty standard stuff. The key is how they're all tied together with their ID's. JavaScript will use this to swap images and CSS states as we tie the three elements (map, glamour image, and list of links) together.
ID's in the map are the straight up ID name like "mac". ID's in the glamour images are "[id]-img" (ie. "mac-img"). And ID's in the list are "[id]-list" (ie. "mac-list").
<script type="text/javascript" src="*"></script>
* = http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js
I recommend using jQuery to help do easy JavaScript-ing and loading it from Google API for easy Content Delivery Network benefits.
All that's really left is the JavaScript event.
$(document).ready(function() {
// highlight map when legend link is hovered
$('#cml-list a').hover(
// hover over
function(){
// get id code
var id = $(this).attr('id');
// tokenize string to get main id code
var tokens = id.split('-');
id = '#' + tokens[0];
// add active class to map id
$(id).addClass('active');
},
// hover out
function(){
// clear all .active classes from map
$('#city-map a').removeClass('active');
}
);
});
What happens above is we tell JavaScript to trigger anytime someone hovers a list link. There are two events when hovering, in and out.
When someone hovers into a link, we get the base ID value from it and all we do is apply a CSS class "active" to the map "hot spot".
".active" class will basically "turn on" the map item as if it was hovered (if you notice in the CSS, all the :hover selector styles are also shared with a '.active' class).
When we hover out, we simply tell jQuery to remove all 'active' classes. All that's left to do is swap also write some code that does the same thing for the "glamour" images. Simply turning them on (display:block) or off (display:none). The one catch is that there should probably be a default image that we always turn back on if nothing else is selected unless we just want the previously activated glamour image to stay active, that works too.
I've not gotten to that bit of code yet. I'll see I can update it later and maybe leave a little bit for you to play around with.
update
I developed it mostly in Chrome and a little Firefox. I just checked
it in IE7/8/9 and it seemed to work fine.
I updated the jsFiddle to include glamour image swapping. I also had a small CSS bug where I placed the float in the wrong spot. So, work off the latest one.
NOTE I did not do the CSS for all the locations. I did several with some examples, but left the rest for you. =)
Btw, I updated your map image and uploaded it on imgur.com => http://i.imgur.com/n7spM.png

Related

CSS animation (greeting card open/close)

I want to make CSS animation, based on this example. It fits me perfectly, however there are 2 things that I couldn't make. First - I want customize inner side of greeting card with two jpg files (inner-left, inner-right). Second - I want card open on click, and not click and hold.
I have tried to make it myself with trials and errors but was unsuccessful. If I include third file (inner-left) and make backface-visibility: hidden it's still not giving me required outcome. I have also tried to edit this example but still couldn't make it. For css animation savvys it should be simple, I guess, so please can anyone help me out.
This is html that I am using,
<section class="container">
<div id="card">
<figure class="front"><img src="img_card/1.jpg"></figure>
<figure class="inner-left"><img src="img_card/1-2.jpg"></figure>
<figure class="inner-right"><img src="img_card/1-3.jpg"></figure>
</div>
</section>
and the css part is in jsfiddle link.
It is possible to do this without JavaScript by using a hidden checkbox, a label and the :checked and sibling (+) selectors.
Take a look at this fiddle which also has the inner-left and inner-right images.
I had a quick look at something like this before and I think that might need to be achieved with either a javascript event that adds in a class on click to move your card to its open state.
https://davidwalsh.name/css-flip
The above link goes to an example that shows a single card flipping but it should be close to the concept you are looking for
I hope that helps

angular animation on ng-click

I am using angular and I need to add an animation that will increase the size of the image.
<div class="card">
<div class="item images-parent">
<img src="img/carryout-icon.jpg" class="left-image"></img>
<img src="img/or.jpg" class="center-image"></img>
<img src="img/delivery-icon.jpg" class="right-image"></img>
</div>
</div>
demo:
http://play.ionic.io/app/933b5926b6da
I want to add same animation/transition to first and third image when the user clicks on it and should be removed when user clicks on the other one i.e if I click on first image, it increases in size, then if I click on the other one, first one goes back to normal and second one has that animation.
Also, I have tried doing it but I am just not able to get ngAnimate, I am not a CSS person either. Also, Any resources to help someone like me would be appreciated.
I see events such as ngView , ng if e.t.c But I do not really want these animations on such events. Only when user clicks on the image. Am I even supposed to use ngAnimate here?
I do not know which particular image you intend to increase it's size on click, but here's one way to go about it.
You can create a css class that increases the image, and you toggle on or off with NgClass, A tutorial Scotch.io
That is to make sure it changes class, but if you want to toggle on/off the class when you click CodePen snippet below
$scope.isActive = false;
$scope.activeButton = function() {
$scope.isActive = !$scope.isActive;
}

links under iframe /span cannot be clicked

I've developed a static advert ticker that sits at the bottom of the window. This is in an <iframe> to make it easier for other people to place the unit on their sites. Another <span> around the <iframe> keeps it fixed to the bottom of the screen. The script has a help window which is within a tag - within the <iframe> and uses the visible / hidden property to show or hide text.
Now since the code is in an <iframe>, the help text would not appear on main window. To get around this, I made the <iframe> larger,and set it to transparent.
Visually, everything is fine. When the user clicks a button on the ticker, the help menu appears over the data in the background. However, I've just discovered that if there is a link on the main page that passes under the <span><iframe> section, it cannot be clicked. I've tried CSS pointer-events, but can't get that to work, (links within the <iframe> must also remain clickable)
Not sure which is causing the "fault", ie the <iframe> or the tag around it. Is it a security thing to stop "click jacking" (??) or more to the point, is there a work around.
If push came to shove, I COULD reduce the size of the <iframe> and use a javascript pop-up window to display help text, but those windows show the URL and status windows, and are not exactly elegant!
Here is the code before anyone asks:
This span covers the entire screen to the height of the underlying <iframe> I did this so the data could be centred
<span style="position:fixed;bottom:10px;display:inline;width:100%">
<center>
<iframe src="http://www.xxx.com/cgi-bin/ticker/run_tick.pl?s=xzy" frameborder=0 align=top width=800px height=330px marginwidth=0 marginheight=0 hspace=0 vspace=0 scrolling=no allowtransparency=true></iframe>
</center>
</span>
Set a height to the span the same as the iframe (330px)
Let me know how that goes
Oh boy, what FUN I've had getting this to work!! (Twelve hours on Wed 23rd, and about three hours today)
Originally, I had an <iframe> that filled virtually 3/4 of screen, (so that I could display the help window to uses in a '' rather than use a modal popup. But, for security reasons, the browsers will not let you click through text that covers links underneath.
I had to literally redesign the whole layout.
Now, I have the help file in a separate <span> window which has its visibility set to hidden till user needs it. But that still left the ticker code at the bottom.
I had to divide that into three <divs> one on either side of the main ticker. But again, the ones on the side are effectively masking the page underneath, so I had to set both <divs> so that they used "pointer-events:none" meaning the <div> was not clickable, and mouse events would pass through to the code underneath. The mid section for the ticker was set to the opposite, namily "pointer-events:auto" so that the TOP window got the clicks, but not the page underneath.
Next problem: Because the ticker shows graphics that extend into the main text, that left a 1/2" area where clicks on main page couldn't be accessed. Another span was added to the code which covered the area with a transparent gif. When the user places their mouse over this graphic, a swap takes place and displays a semi transparent checkerboard. They can then read what this means in the help file.
Finally, when user's click the minimize button, the <div> holding the ticker code is hidden (giving accesss to all the links on the page) and ANOTHER <div> displays "Restore" graphic. When they click that, it gets hidden whilst the main ticker window - and the two <divs> on either side are made visible again.
And it was only meant to be a simple script!! (Oh, and don't check the website or my blog 'cos I won't be uploading the changes till eve of Sat 26th)

Replace Markers by html content

I have been searching on the Google Map API V3 documentation but I could not find any way to use my own html content instead of an image to create a custom icon on the map.
I would like to display a dynamic marker that can display text or anything I want.
For exemple :
<div class="marker">Dynamic text</div>
I have seen this thread google map api v3: can I use a div instead of an image to create the custom icon? where someone advice to use "Custom Overlays" but in the documentation it only displays an image... I don't see the point of explaning how to display an image with "Custom Overlays" if it is done to display html content.
http://code.google.com/apis/maps/documentation/javascript/overlays.html#CustomOverlays
How should I proceed then ? Should I use Custom Overlays ? There is not anything that seem easier to do that ?
Mano's got the right answer if you're looking to position something on the map that isn't bounded geographically, like a menu or titlebar.
If you're looking to display something geographically-bound, like a city name (pretending for a second that the API doesn't already do this) than you'll be headed the CustomOverlay route. While all the examples use images, that's not a requirement by any means. If you look at the simple overlay example and view the source code around line 62 you'll see the exact lines adding the <img> object to the <div>. You could just as easily add text to the div instead of an image.
Actually you can use float the div over your map using CSS. You have to be careful about the positioning. Check out this post:
div on top of div with Google Maps API
Go to this demo purpose website: http://easysublease.org/mapcoverjs/
On the map, right Click on map, and you will see a context menu. Within this context menu, there is a input, you can just input some text on the input. Then next generated Marker will have the text you entered there.
To see how it works, you can go to its github: https://github.com/bovetliu/mapcover.
Mapcover.js is one javascript gadget enabling Developers to Write HTML/CSS to create customized elements on Google Map.

Click through div to underlying elements

I have a div that has background:transparent, along with border. Underneath this div, I have more elements.
Currently, I'm able to click the underlying elements when I click outside of the overlay div. However, I'm unable to click the underlying elements when clicking directly on the overlay div.
I want to be able to click through this div so that I can click on the underlying elements.
Yes, you CAN do this.
Using pointer-events: none along with CSS conditional statements for IE11 (does not work in IE10 or below), you can get a cross browser compatible solution for this problem.
Using AlphaImageLoader, you can even put transparent .PNG/.GIFs in the overlay div and have clicks flow through to elements underneath.
CSS:
pointer-events: none;
background: url('your_transparent.png');
IE11 conditional:
filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='your_transparent.png', sizingMethod='scale');
background: none !important;
Here is a basic example page with all the code.
Yes, you CAN force overlapping layers to pass through (ignore) click events.
PLUS you CAN have specific children excluded from this behavior...
You can do this, using pointer-events
pointer-events influences the reaction to click-, tap-, scroll- und hover events.
In a layer that should ignore / pass-through mentioned events you set
pointer-events: none;
Children of that unresponsive layer that need to react mouse / tap events again need:
pointer-events: auto;
That second part is very helpful if you work with multiple overlapping div layers (probably some parents being transparent), where you need to be able to click on child elements and only that child elements.
Example usage:
.parent {
pointer-events:none;
}
.child {
pointer-events:auto;
}
<div class="parent">
I'm unresponsive
I'm clickable again, wohoo !
</div>
Allowing the user to click through a div to the underlying element depends on the browser. All modern browsers, including Firefox, Chrome, Safari, and Opera, understand pointer-events:none.
For IE, it depends on the background. If the background is transparent, clickthrough works without you needing to do anything. On the other hand, for something like background:white; opacity:0; filter:Alpha(opacity=0);, IE needs manual event forwarding.
See a JSFiddle test and CanIUse pointer events.
I'm adding this answer because I didn’t see it here in full. I was able to do this using elementFromPoint. So basically:
attach a click to the div you want to be clicked through
hide it
determine what element the pointer is on
fire the click on the element there.
var range-selector= $("")
.css("position", "absolute").addClass("range-selector")
.appendTo("")
.click(function(e) {
_range-selector.hide();
$(document.elementFromPoint(e.clientX,e.clientY)).trigger("click");
});
In my case the overlaying div is absolutely positioned—I am not sure if this makes a difference. This works on IE8/9, Safari Chrome and Firefox at least.
Hide overlaying the element
Determine cursor coordinates
Get element on those coordinates
Trigger click on element
Show overlaying element again
$('#elementontop').click(e => {
$('#elementontop').hide();
$(document.elementFromPoint(e.clientX, e.clientY)).trigger("click");
$('#elementontop').show();
});
I needed to do this and decided to take this route:
$('.overlay').click(function(e){
var left = $(window).scrollLeft();
var top = $(window).scrollTop();
//hide the overlay for now so the document can find the underlying elements
$(this).css('display','none');
//use the current scroll position to deduct from the click position
$(document.elementFromPoint(e.pageX-left, e.pageY-top)).click();
//show the overlay again
$(this).css('display','block');
});
I currently work with canvas speech balloons. But because the balloon with the pointer is wrapped in a div, some links under it aren't click able anymore. I cant use extjs in this case.
See basic example for my speech balloon tutorial requires HTML5
So I decided to collect all link coordinates from inside the balloons in an array.
var clickarray=[];
function getcoo(thatdiv){
thatdiv.find(".link").each(function(){
var offset=$(this).offset();
clickarray.unshift([(offset.left),
(offset.top),
(offset.left+$(this).width()),
(offset.top+$(this).height()),
($(this).attr('name')),
1]);
});
}
I call this function on each (new) balloon. It grabs the coordinates of the left/top and right/down corners of a link.class - additionally the name attribute for what to do if someone clicks in that coordinates and I loved to set a 1 which means that it wasn't clicked jet. And unshift this array to the clickarray. You could use push too.
To work with that array:
$("body").click(function(event){
event.preventDefault();//if it is a a-tag
var x=event.pageX;
var y=event.pageY;
var job="";
for(var i in clickarray){
if(x>=clickarray[i][0] && x<=clickarray[i][2] && y>=clickarray[i][1] && y<=clickarray[i][3] && clickarray[i][5]==1){
job=clickarray[i][4];
clickarray[i][5]=0;//set to allready clicked
break;
}
}
if(job.length>0){
// --do some thing with the job --
}
});
This function proofs the coordinates of a body click event or whether it was already clicked and returns the name attribute. I think it is not necessary to go deeper, but you see it is not that complicate.
Hope in was enlish...
Another idea to try (situationally) would be to:
Put the content you want in a div;
Put the non-clicking overlay over the entire page with a z-index higher,
make another cropped copy of the original div
overlay and abs position the copy div in the same place as the original content you want to be clickable with an even higher z-index?
Any thoughts?
I think the event.stopPropagation(); should be mentioned here as well. Add this to the Click function of your button.
Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
Just wrap a tag around all the HTML extract, for example
<a href="/categories/1">
<img alt="test1" class="img-responsive" src="/assets/photo.jpg" />
<div class="caption bg-orange">
<h2>
test1
</h2>
</div>
</a>
in my example my caption class has hover effects, that with pointer-events:none; you just will lose
wrapping the content will keep your hover effects and you can click in all the picture, div included, regards!
An easier way would be to inline the transparent background image using Data URIs as follows:
.click-through {
pointer-events: none;
background: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
}
I think that you can consider changing your markup. If I am not wrong, you'd like to put an invisible layer above the document and your invisible markup may be preceding your document image (is this correct?).
Instead, I propose that you put the invisible right after the document image but changing the position to absolute.
Notice that you need a parent element to have position: relative and then you will be able to use this idea. Otherwise your absolute layer will be placed just in the top left corner.
An absolute position element is positioned relative to the first parent
element that has a position other than static.
If no such element is found, the containing block is html
Hope this helps. See here for more information about CSS positioning.
You can place an AP overlay like...
#overlay {
position: absolute;
top: -79px;
left: -60px;
height: 80px;
width: 380px;
z-index: 2;
background: url(fake.gif);
}
<div id="overlay"></div>
just put it over where you dont want ie cliked. Works in all.
This is not a precise answer for the question but may help in finding a workaround for it.
I had an image I was hiding on page load and displaying when waiting on an AJAX call then hiding again however...
I found the only way to display my image when loading the page then make it disappear and be able to click things where the image was located before hiding it was to put the image into a DIV, make the size of the DIV 10x10 pixels or small enough to prevent it causing an issue then hiding the containing div. This allowed the image to overflow the div while visible and when the div was hidden, only the divs area was affected by inability to click objects beneath and not the whole size of the image the DIV contained and was displaying.
I tried all the methods to hide the image including CSS display=none/block, opacity=0, hiding the image with hidden=true. All of them resulted in my image being hidden but the area where it was displayed to act like there was a cover over the stuff underneath so clicks and so on wouldn't act on the underlying objects. Once the image was inside a tiny DIV and I hid the tiny DIV, the entire area occupied by the image was clear and only the tiny area under the DIV I hid was affected but as I made it small enough (10x10 pixels), the issue was fixed (sort of).
I found this to be a dirty workaround for what should be a simple issue but I was not able to find any way to hide the object in its native format without a container. My object was in the form of etc. If anyone has a better way, please let me know.
I couldn't always use pointer-events: none in my scenario, because I wanted both the overlay and the underlying element(s) to be clickable / selectable.
The DOM structure looked like this:
<div id="outerElement">
<div id="canvas-wrapper">
<canvas id="overlay"></canvas>
</div>
<!-- Omitted: element(s) behind canvas that should still be selectable -->
</div>
(The outerElement, canvas-wrapper and canvas elements have the same size.)
To make the elements behind the canvas act normally (e.g. selectable, editable), I used the following code:
canvasWrapper.style.pointerEvents = 'none';
outerElement.addEventListener('mousedown', event => {
const clickedOnElementInCanvas = yourCheck // TODO: check if the event *would* click a canvas element.
if (!clickedOnElementInCanvas) {
// if necessary, add logic to deselect your canvas elements ...
wrapper.style.pointerEvents = 'none';
return true;
}
// Check if we emitted the event ourselves (avoid endless loop)
if (event.isTrusted) {
// Manually forward element to the canvas
const mouseEvent = new MouseEvent(event.type, event);
canvas.dispatchEvent(mouseEvent);
mouseEvent.stopPropagation();
}
return true;
});
Some canvas objects also came with input fields, so I had to allow keyboard events, too.
To do this, I had to update the pointerEvents property based on whether a canvas input field was currently focused or not:
onCanvasModified(canvas, () => {
const inputFieldInCanvasActive = // TODO: Check if an input field of the canvas is active.
wrapper.style.pointerEvents = inputFieldInCanvasActive ? 'auto' : 'none';
});
it doesn't work that way. the work around is to manually check the coordinates of the mouse click against the area occupied by each element.
area occupied by an element can found found by 1. getting the location of the element with respect to the top left of the page, and 2. the width and the height. a library like jQuery makes this pretty simple, although it can be done in plain js. adding an event handler for mousemove on the document object will provide continuous updates of the mouse position from the top and left of the page. deciding if the mouse is over any given object consists of checking if the mouse position is between the left, right, top and bottom edges of an element.
Nope, you can't click ‘through’ an element. You can get the co-ordinates of the click and try to work out what element was underneath the clicked element, but this is really tedious for browsers that don't have document.elementFromPoint. Then you still have to emulate the default action of clicking, which isn't necessarily trivial depending on what elements you have under there.
Since you've got a fully-transparent window area, you'll probably be better off implementing it as separate border elements around the outside, leaving the centre area free of obstruction so you can really just click straight through.

Resources