Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a clickable grid of triangles using html, svg?

Tags:

html

css

svg

I have already created a grid of triangles like so:

    svg {
      margin-left: 0px;
      margin-right: -60px;
      padding: 0;
    }
<div data-bind="foreach: Grid">
  <div data-bind="foreach: $data.rowData">
    <!-- ko if: $data.owner() === 0 && ($data.pos[0] + $data.pos[1])%2 === 0-->
    <svg height="103.92" width="120">
      <polygon class="" points="60,0 0,103.92 120,103.92" style="fill:grey;" data-bind="click: $root.test.bind($data, $data)" />
    </svg>
    <!-- /ko -->
    <!-- ko if: $data.owner() === 0 && ($data.pos[0] + $data.pos[1])%2 === 1-->
    <svg height="103.92" width="120">
      <polygon class="" points="0,0 120,0 60,103.92" style="fill:grey;" data-bind="click: $root.test.bind($data, $data)" />
    </svg>
    <!-- /ko -->
  </div>
</div>

My problem is that only the left half of the triangles is clickable. I think this is due to the (still rectangular) shape of the svg-element. But I have no idea how to fix this. Is there any way to make every triangle clickable in its whole area?

like image 539
Astra-Ritter Avatar asked Nov 30 '15 15:11

Astra-Ritter


2 Answers

At the moment, all your individual SVGs are overlapping one another and any click that misses a triangle will be swallowed by the parent <svg> element.

The cleanest solution would be to put all your polygons in one big SVG. However there is another way around your problem using the pointer-events property.

Set pointer-events="none" on your <svg> elements so that clicks will pass through them. But you'll also need to set an explicit pointer-events="fill" on your polygons, since otherwise they'll inherit the "none" from their parent SVGs.

var output = document.getElementById("output");
    
document.getElementById("red").addEventListener("click", function(e) {
  output.textContent = "red";
});

document.getElementById("green").addEventListener("click", function(e) {
  output.textContent = "green";
});
svg {
    position: absolute;
    top: 0;
    left: 0;
    pointer-events: none;
}

polygon {
    pointer-events: fill;
}

#output {
  margin-top: 120px;
}
<svg width="100px" height="100px">
    <polygon points="0,0,100,0,100,100" fill="red" id="red"/>
</svg>

<svg width="100px" height="100px">
    <polygon points="0,0,100,100,0,100" fill="green" id="green"/>
</svg>

<div id="output"></div>
like image 123
Paul LeBeau Avatar answered Nov 15 '22 03:11

Paul LeBeau


You should use one svg tag with both polygons inside it. This way the Square svg elements won't overlap each other:

polygon {
  fill: grey;
}
polygon:hover {
  fill: #000;
}
<svg height="103.92" width="185">
  <polygon points="60,0 0,103.92 120,103.92" />
  <polygon points="65,0 185,0 125,103.92" />
</svg>
like image 20
web-tiki Avatar answered Nov 15 '22 05:11

web-tiki