11

I have a triangle with a javascript function that moves that image.

The issue is that the element has a square shape so click and hover state are triggered ouside the triangle (see the red part in following image) :

CSS triangle with wrong hover and click zone

How can I prevent hover and click outside the triangle shape and allow click/hover state only inside the triangle shape?

web-tiki
  • 99,765
  • 32
  • 217
  • 249
gn66
  • 803
  • 2
  • 12
  • 33
  • 3
    Is this a valid solution? http://www.fileformat.info/info/unicode/char/25b2/index.htm – 000 Jun 06 '14 at 22:29
  • @Joe Frambach unfortunately no, but thanks for the idea – gn66 Jun 07 '14 at 14:45
  • Is this image a PNG with some transparent parts? Are you looking to detect whether the pixel the user has clicked on is transparent or opaque? Can the image be anything, or is it always a triangle of exactly this shape? – Bemmu Jun 09 '14 at 00:45
  • I know a solution for you, but could you add some code to be able to fully understand your problem? – micnic Jun 09 '14 at 07:38
  • ok, thanks for the reply, here's the fiddle: http://jsfiddle.net/EdB27/1/ – gn66 Jun 09 '14 at 15:56

4 Answers4

17

To prevent hover and click outside the CSS triangle you can use transforms to make the the triangle.

This technique is described here : CSS Triangles with transform rotate

The point is to use a wrapper with hidden overflow and rotate the clickable/hoverable element so that it actualy has a triangular shape and prevent the click event or hover state outside the triangle.

Demo: Click and hover on a CSS triangle

hover and click CSS triangle The hover state and click event are triggered only inside the triangle

.tr {
  width: 40%;
  padding-bottom: 28.2842712474619%; /* = width / sqrt(2) */
  position: relative;
  overflow: hidden;
}
.tr a {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
  background-color: rgba(0, 122, 199, 0.7);
  transform-origin: 0 100%;
  transform: rotate(45deg);
  transition: background-color .3s;
}
/** hover effect **/
.tr a:hover {
  background: rgba(255, 165, 0, 0.7);
}
<div class="tr"><a href="#"></a></div>

Another approach would be to use an SVG with a clickable triangle :

#tr{
  fill:transparent;
  transition:fill .3s;
}
#tr:hover{
  fill: orange;
}

/** for the demo **/
html,body{height:100%;margin:0; padding:0;}
body{background:url('https://farm8.staticflickr.com/7435/13629508935_62a5ddf8ec_c.jpg') center no-repeat;background-size:contain;}
svg{display:block;width:30%;margin:0 auto;}
<svg viewbox="-2 -2 104 64">
  <a xlink:href="#">
    <polygon id="tr" points="50 0 100 60 0 60" fill="transparent" stroke="darkorange" stroke-width="2"/>
  </a>
</svg>
Community
  • 1
  • 1
web-tiki
  • 99,765
  • 32
  • 217
  • 249
  • Ok, really thanks about the answer, I upgraded here: http://jsfiddle.net/EdB27/2/ for you too see everything just working fine, just one thing I need if you dont mind, can you integrate this image in the code? http://static.tumblr.com/g1c47pc/7iMn39g0v/tr1.png , I'm really not succeeding integrate an image to the code you've done so far :S – gn66 Jun 09 '14 at 16:04
  • @gn66 glad you found a solution! – web-tiki Jun 10 '14 at 08:07
  • 1
    works in chrome but it doesn't work in iceweasel (standard-browser in last linux-ccrunchbang version) 24.5.0... – Jere Jun 10 '14 at 11:55
  • @Jere you made me notice I made a typo for non webkit or ms browsers, I fixed that typo and hope it will also fix it in iceweasel – web-tiki Jun 10 '14 at 15:14
5

You should be able to just use an image map. Just create one poly that covers the triangle by setting the coords to (w/2, 0), (w, h), (0, h) where w and h are width and height. (Assuming an equilateral triangle like in your example. Otherwise just find the points with an image editor.)

<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/7/7f/Green_equilateral_triangle_point_up.svg/600px-Green_equilateral_triangle_point_up.svg.png"
     width="60" height="52"
     usemap="#imgmap" />

<map name="imgmap">
    <area href="javascript:alert('Triggered')"
          shape="poly"
          coords="30,0,60,52,0,52"
          style="outline:none;"
          target="_self" />
</map>

Demo: http://jsfiddle.net/QXv2c/

freshtop
  • 706
  • 8
  • 17
  • 1
    I've fixed your JSFiddle here: http://jsfiddle.net/QXv2c/2/. You hadn't included the MoverBehaviour and there was no element with the id "me". Other than that it was fine. – freshtop Jun 09 '14 at 16:45
3

This should work:   (based on Brian Nickel's answer to another question)

$('#triangle').mousedown(function(e) {
    e.preventDefault();

    //create matching canvas representation for the image
    if(!this.canvas) {
        this.canvas = $('<canvas/>')[0];
        this.canvas.width = this.width;
        this.canvas.height = this.height;
        this.canvas.getContext('2d').drawImage(this, 0, 0, this.width, this.height);
    }
    var pixelData = this.canvas.getContext('2d').getImageData(e.offsetX, e.offsetY, 1, 1).data;

    //check that the pixel is not transparent
    if (pixelData[3] > 0) {
        //your code
    }
});

Working example: http://jsfiddle.net/FCf9d/

This solution assumes there are no transparent pixels inside the triangle.
This example uses the jsfiddle logo instead of a triangle, because you can't use remote images. The jsfiddle-logo works because it's on the jsFiddle-domain but any other random image doesn't work.
But that shouldn't be a problem once you implement the code on your own website.


I took the liberty of adding the move-function to the fiddle for you so you could see everything in action. If you like my script and would like to add boundaries to the move area, check out another fiddle of mine which has those build in: http://jsfiddle.net/SN8Ys/

Community
  • 1
  • 1
myfunkyside
  • 3,890
  • 1
  • 17
  • 32
1

Taken from CSS-tricks. This is a neat solution however I'm not sure about the clicking part. Maybe you can use it to mask over what you have.

HTML:

<div class="arrow-up"></div>
<div class="arrow-down"></div>
<div class="arrow-left"></div>
<div class="arrow-right"></div>

CSS:

.arrow-up {
    width: 0; 
    height: 0; 
    border-left: 5px solid transparent;
    border-right: 5px solid transparent;

    border-bottom: 5px solid black;
}

.arrow-down {
    width: 0; 
    height: 0; 
    border-left: 20px solid transparent;
    border-right: 20px solid transparent;

    border-top: 20px solid #f00;
}

.arrow-right {
    width: 0; 
    height: 0; 
    border-top: 60px solid transparent;
    border-bottom: 60px solid transparent;

    border-left: 60px solid green;
}

.arrow-left {
    width: 0; 
    height: 0; 
    border-top: 10px solid transparent;
    border-bottom: 10px solid transparent; 

    border-right:10px solid blue; 
}

Source: http://css-tricks.com/snippets/css/css-triangle/

TheBokiya
  • 620
  • 6
  • 21
  • 1
    Despite the title, it seems that the OP has already created the triangle. The question is about clicking: "Is there a way to prevent my mouse to select the red part?" – showdev Jun 06 '14 at 22:37
  • @user0000000 The question's title originally specified a CSS triangle. It has since been edited. – showdev Jun 10 '14 at 21:52