What is the best way of turning a Canvas element into a link - by this I mean the whole canvas element, not just a part of the image.
I have tried the obvious thing - wrapping the element in an A element - but finding issues in IE9.
Take this markup for example:
<a href="#link">
<canvas width="100" height="100">
//fallback
</canvas>
</a>
Using CSS I have styled the link background colour to change on hover, and am finding in most modern canvas supporting browsers it works as expected - you hover, the background changes colour, you click the link, the link is followed.
However, in IE9 when hovering over the element it doesn't recognise that it's a link - no hover effect, no cursor changing to a pointer, clicking does nowt.
Interestingly, if I add a 1 pixel border to the A element, and hover the mouse precariously over the 1 pixel border, IE9 does recognise the link, and after that you can move the mouse over the canvas and it maintains it's hover state and works as a link.
It's almost as if the canvas is overriding the link, so the browser isn't able to recognise the link, only the canvas element - if that makes sense?
So, really I just want to ascertain:
Is is acceptable to simply wrap a Canvas element in an A element - is this just IE9 being weird or am I doing it wrong?
If I'm doing it wrong, what is the accepted technique for doing this seemingly simple task?
Thanks
UPDATE
OK, so the answer's I've had below are all correct, but unfortunately weren't working in my implementation either. My markup is quite a lot more complicated than the simplified example above, so I'm guessing that actually there is something else at play that is causing the problem - with native hover events and events attached with JavaScript - nothing was working.
However, I've come up with a hack that solved the problem. I gave my link an RGBA background colour with zero opacity. Once that was there, things work fine. Weird I know, but fixed :)
I'm not 100% on the problems with the canvas element in IE but you can update the onclick handler of the canvas element, changing the window location to where you want.
document.getElementById("mycanvas").onclick = function(e){
window.location.href = 'http://www.google.com';
};
Example: http://jsfiddle.net/jonathon/HtmVS/
You could handle other events (like the mousein/mouseout) to set the cursor, if you wanted.
You can use javascript's onclick to handle this, and combine it with CSS to put a cursor: pointer; on it. You could then implement canvas:hover in CSS for the hover effects. You can combine this with an <a> to allow the user to "tab" through the links/canvases.
Not sure if you wanted to use jQuery, but if so, try this.
$("#myCanvasId").click(function(){
window.open("https://www.google.com");
});
Cross-browser way to do this is simply by putting a div on top of the canvas that has the exact same pixel position and width and height as the canvas. Then install on click handler on that div and the use window.location.href as suggested in the earlier answer.
...
<canvas id=".. >
<div id="overlay"/>
...
Related
Perhaps the title isn't great, but I had a little trouble with the wording...
Basically, is it possible to have jQuery's hover only fire over the actual content of a png with an alpha channel.
So in the image below;
http://i.imgur.com/3kO7v.png
Only fire on the rectangle and not the alpha channel which make up the rest of the document bounds...
I've tried the obvious $('obj').hover(function(){stuff}) but this fires on the alpha channel too...
The final implementation of this will be for more complex shapes than just a rotated square, so css3 tricks are out for the primary basis, but could be used with a back-up/shim, plus I need to support IE7 and ipad,iphone,ipod....
If there is a CSS2 solution then that would be suitable too. Also any real guidance on this issue is more than welcome.
My backup for this will be to have an empty div, display block and position it over the shape and then use that. This will obviously not be ideal for the less square objects.
Any hits or tips are more than welcome.
Thank you
Yes it is possible depending on the stacking context of your elements. Keep in mind that when you do a focus over any particular element on a page, that you are actually focusing all other elements within the same stacking context.
So what you could do is either stop the event from bubbling up the stack (if the element you want to "hover" is lower in the stack that the elements you want to prevent hover effects on), or specifically put in prevent default for onhover events for all elements in the stacking context except for the one you want to actually get a hover effect.
For a 'shooting gallery'-like game, there are images with an onMouseOver event that will show a crosshair (which follows the mouse) and an onMouseOut event that will hide it.
However, the instant the crosshair becomes visible, it covers the below image, activating its onMouseOut event which hides the crosshair.
This creates a 'flicker' effect which is very, very ugly.
Is there a way to prevent the crosshair image from obscuring the target below?
One easy solution is to create an onMouseOver for the crosshair that shows it (I know this is redundant, but it works for menus and the like).
Another solution would be to set a timeout in the onMouseOut to hide the crosshair. It will reduce the flickering and the crosshair will be visible out of the target for a short time.
Edit:
And another would be to perform a collision detection between the mouse and the elements, changing the mouseOver to a mouseMove in the target's parent element:
http://jsfiddle.net/sHecT/1/
The code is quite long, but its logic is what I've said above.
Just a note: The getElementsByClassName doesn't work in older browsers, but you can use an array of targets, as you create them, add them to an aray (probably you already has one) and use it in place of this call;
This one illustrates an easing function to position the crosshair smothly and the cursor is hidden when over the target
http://jsfiddle.net/sHecT/2/
Instead of using an image for your background, and an image for your cross-hairs, what if you used a div with a background image for your background instead, and then made the cross-hairs image a child of that div?
I haven't tested this, but since the cross-hair image would now be part of the content of the background div, I would imagine that it would no longer trigger a mouseout.
I believe The pointer-events property is exactly what you're looking for. It basically prevents an element from being the target of any sort of mouse-event so the elements underneath it can handle them instead. Parent elements can still react to the event.
HOWEVER it is only supported in the later versions of Firefox, Safari, and Chrome, and it probably won't be in the CSS specification until CSS4. It an awesome solution for supported browsers, but if you want to fix the issue in any version of IE or Opera you'll also need an alternate solution. I felt like it deserved a mention here though. :D
If you take a quick look at the two links below, you'll see most people want to get rid of the outline around the area of a map on an image. I see this occurs on the MAC OS X platform, exclusively.
Removing outline on image map area
How do I get rid of this border outline for my image map areas when clicked (OS X Chrome Only)
However, what I want to do is show the outline in multiple browsers and change it's color and width. I tried but to avail. I created a style for an id. Didn't work. I tried using a class and that didn't work. I set an inline style and that didn't work, either. And I attempted it on both the map and area tags, by the way.
As of now, I use a gif to "border" the area when clicked. But it would make things so much easier if I could take advantage of the built-in shape attribute to highlight the area clicked.
Thank you very much for any help.
This answer looks interesting:
Changing the colour/transparency of a div on rollover or using an imagemap
Links to here: http://davidlynch.org/js/maphilight/docs/demo_simple.html
Older versions of Internet Explorer do not respect CSS for the area outlines. You can solve this by blocking the default handing of the mousedown event. If using jquery, something like
$('area').bind('mousedown',function(e) {
e.preventDefault();
});
would take care of it for all image maps on the page.
Also take a look at my plugin: http://www.outsharked.com/imagemapster which will let you easily handle outline (and other) effects on mouseover and click events.
is it possible to have a visible html element but one which lacks presence on the page?
Let me give you an example of what I mean. Lets say I have a picture gallery and a light box. Usually lightboxes grey out the background so you can focus on the image. All i want is the greyed out overlay but i dont want it to be interactive. So if you were to click on it, you would click on the element behind it. So lets say I have a paragraph and in that paragraph i have a link and covering the paragraph is a overlay at 50% opacity, if i were to hover over the link, the link would react asif the overlay was not there.
I hope I have explained this well enough
AFAIK there is no easy way to do this and the only alternative would be to get the mouse coordinates and relay them somehow :/ is ther anyway what I want is possible?
Thanks
This can be done with pointer-events: none in certain browsers, but unfortunately not any version of IE.
It is not possible to have an overlay be transparent in the sense you want it to be. What you could try to do is the opposite; put the 'overlay' layer behind the rest of your page and then change the opacity of your entire page to 50%. Visually this will not make any difference, but it will remove the bubbly effect of JS clicking.
You can take an element out of the document flow with CSS but when that happens the element still receives click events as long as it is visible.
You could probably attach a click event to the overlay and then use the mouse coordinates with document.elementFromPoint or by manually looping through all the elements you want to be interactive and checking their coordinates on the page. The problem with this approach is that NoScript or a number of other products might detect this as ClickJacking, which it essentially is even though you are using it for a benign purpose.
I don't see why this isn't possible. opacity is about 5 css properties for cross-browser. I am not sure what exactly you mean by an overlay (same thing as a layer or z-index?) or are you talking about the possibility of using a css
for all p tags, then it's p:hover in css, but for a specific p tag, then you use an #id with :hover pseudo-class like this:
#myptag:hover {
background-color: #f3c9d5;
background-image:url(/images/mybgimg.jpg);
color:blue;
cursor:pointer;
}
for opacity, use a number in windows.index from 0 to 100:
//this function modifies the opacity of an element at a
//specific id like el1 or el2 using imageNumber as the index.
//you also specify an opacityInteger, which is an non-negative
//integer number in the range 0..100
//works on chrome, safari, ie, and firefox, all the major browsers.
function processimage(imageNumber, opacityInteger) {
var opacityFloat=opacityInteger/100.0;
//set image style, if we can - I hear it's readonly...
//filter:alpha(opacity=100);-moz-opacity:1.0;opacity:1.0
document.getElementById("el"+imageNumber).style.filter="alpha(opacity="+opacityInteger+")";
document.getElementById("el"+imageNumber).style.mozOpacity=opacityFloat.toString();
document.getElementById("el"+imageNumber).style.opacity=opacityFloat.toString();
}
well, I just realized this is only marginally helpful. while it may get your toward your goal, you may still have to set a css z-index:1; on a layerto get an actual overlay. what I just gave you was an UNDERLAY or simply setting a given p tag's color or background image to another thing. I don't know if that's desirable to you or not. I have found overlays to be extremely difficult to manage, because the page layout engine treats all the layers as if they were the same layer tags-flow-wise and you have to use absolute positioning to force them to stick in a position you want them in. plus it messes up your main page using layers.
There are many of us looking for a Javascript/CSS3 solution that can provide a windows7-like UI within a webpage, without using flash.
We need an Opacity mask, rounded borders, and a Blur...
We've got the Opacity and the rounded borders, now we need to be able to apply some Blur effects to a semi-transparent Div.
I tried the BlurFast effect from the Pixastic Library, but it only blurs the actual image, not the background we are seeing trough the image...
Basically, we want a Div to act as a Blur Mask over other contents...
If someone actually succeeded with this, i'll be glad to know its possible :) Thank you
http://t.co/fFLPKnzC
very good article on blur showing the state of the art
sadly "masking" parts of your page, that blur everything behind, is not that easy.
maybe the suggestions in ths blog help you out, as they are very straight forward and from a totally different direction..
therefor to embedd html within svg and use svg-filters on html elements later on
Thought this could be relevant: Aero
Personally, I think the fact that the author states this to be "In other words, one of the most messy and most ineffecient implementations ever"... AND that he can onlt get the effect to work in a single browser... to be extremely telling.
There is no way to do this efficiently or cross-browser at the moment.
The only way you might be able to do it is by using Pixastic to create the blurred image within Canvas, export as dataURI, then use that image as the background for your div. If the div moves, then the positioning of the background-image should move accordingly.