Lukas Baliƫnas Lukas Baliƫnas - 3 months ago 17
HTML Question

Overlapping svg path events depending on variable

I made a basketball svg court. In this svg there two significant paths that are useful to me:

#inside_area_a
with
#threepoint_area_b
and
#inside_area_b
with
#threepoint_area_b
.

#inside_area_a
overlaps with
#threepoint_area_b
and
#inside_area_b
overlaps with
#threepoint_area_a
. With jQuery i want to make only one pair(a or b) to be clickable, depending on a variable. For example,

if(poss=="home"){
//#inside_area_a and #threepoint_area_a click functions
}
else //#inside_area_b and #threepoint_area_b click functions


How could this be done with jQuery?



<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 435.7 234.4" style="enable-background:new 0 0 435.7 234.4;" xml:space="preserve">
<style type="text/css">
svg {
height: 100%;
}
.st0 {
fill: none;
stroke: #010101;
stroke-width: 3;
}
#inside_area_a {
fill: transparent;
}
#inside_area_b {
fill: transparent;
}
#inside_area_a:hover {
fill: #1abc9c;
}
#inside_area_b:hover {
fill: #1abc9c;
}
</style>







<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 435.7 234.4" style="enable-background:new 0 0 435.7 234.4;" xml:space="preserve">
<style type="text/css">
svg {
height: 100%;
}
.st0 {
fill: none;
stroke: #010101;
stroke-width: 3;
}
</style>
<rect id="XMLID_28_" x="5.2" y="24.3" class="st0" width="0" height="186.7" />
<path id="inside_area_a" class="st0" d="M29.1,211c52.4,0,94.9-41.8,94.9-93.4S81.5,24.3,29.1,24.3H5.2V211H29.1z" />
<path id="threepoint_area_a" class="st0" d="M5.3,24L5.3,24l0-0.7L5.3,24h23.9c52.4,0,94.9,41.8,94.9,93.4s-42.5,93.4-94.9,93.4H5.3
v0.6l0-0.6v18.7h425.4V5.3H5.3V24z" />
<path id="inside_area_b" class="st0" d="M430.5,23.6v188.1V211h-23.9c-52.4,0-94.9-41.8-94.9-93.4s42.5-93.4,94.9-93.4h23.9" />
<path id="threepoint_area_b" class="st0" d="M430.4,210.4L430.4,210.4l0,0.7L430.4,210.4h-23.9c-52.4,0-94.9-41.8-94.9-93.4
s42.5-93.4,94.9-93.4h23.9V23l0,0.6V5H5v224.1h425.4V210.4L430.4,210.4z" />
<line id="center_line" class="st0" x1="217.8" y1="231.9" x2="217.8" y2="3.4" />
<ellipse id="center_circle" class="st0" cx="217.8" cy="117.6" rx="27.3" ry="26.9" />
<line id="freethrow_line_a" class="st0" x1="93.3" y1="144.5" x2="93.3" y2="90.8" />
<line id="freethrow_line_b" class="st0" x1="342.4" y1="144.5" x2="342.4" y2="90.8" />
<path id="freethrow_circle_a" class="st0" d="M93.3,90.8c15.1,0,27.3,12,27.3,26.9s-12.2,26.9-27.3,26.9" />
<path id="freethrow_circle_b" class="st0" d="M342.4,144.5c-15.1,0-27.3-12-27.3-26.9s12.2-26.9,27.3-26.9" />
<line id="freethrow_lane_line_a_left" class="st0" x1="93.3" y1="144.5" x2="4.6" y2="144.9" />
<line id="freethrow_lane_line_a_right_dashes" class="st0" x1="4.4" y1="90.8" x2="93.8" y2="90.8" />
<line id="freethrow_lane_line_b_left_dashes" class="st0" x1="431.1" y1="144.5" x2="342" y2="144.5" />
<line id="freethrow_lane_line_b_right_dashes" class="st0" x1="430.6" y1="90.8" x2="342.2" y2="90.8" />
<line id="basket_board_a" class="st0" x1="23.4" y1="131.1" x2="23.4" y2="104.2" />
<line id="basket_board_b" class="st0" x1="412.3" y1="131.1" x2="412.3" y2="104.2" />
<line id="basket_holder_a" class="st0" x1="23.4" y1="117.6" x2="27.9" y2="117.6" />
<line id="basket_holder_b" class="st0" x1="412.3" y1="117.6" x2="407.7" y2="117.6" />
<ellipse id="XMLID_27_" class="st0" cx="31.7" cy="117.6" rx="3.8" ry="3.7" />
<ellipse id="basket_b" class="st0" cx="403.9" cy="117.6" rx="3.8" ry="3.7" />
</svg>




Answer

I duplicated your "inside" and "three point" areas. For one set I left the id's as they were. For the other set I prepended "select_" onto the id. Having these two sets allows me to separate hover targets from color targets. (You should probably do this duplication dynamically, especially for more complicated graphics, but this manual duplication is good enough to demonstrate the technique.)

I put the originals at the "bottom" of the svg stack of elements (i.e. near the start of the svg code) so that coloring them wouldn't hide any black lines. (Note that I had to slightly rearrange these so that, when colored, the three point areas wouldn't cover the inside area.) However, I put the duplicate set at the "top" of the svg stack (i.e. near the end of the svg code) so that the hover targets would be topmost.

Then I hid all of the duplicate elements, i.e. the ones that emit hover events, such that no hovers can initially be detected. When one team's button is clicked, only the one hoverable "inside" area and the one hoverable "three point" area for that team are made "visible". These still remain unseen by the viewer (fill is always transparent) but "visible" with respect to now being hover targets (visibility changes from hidden to visible). Thus, the hover targets are essentially swapped depending on which team is chosen. Note that the hoverability of all the targets always remains intact. It's just that only 2 of the 4 are ever visible, and thus truly hoverable, at any point in time.

The code that includes the doubly-nested forEach loops is just a concise way of setting up all the jQuery hover events.

UPDATE: You asked about which area to click on. I updated the code to show that the appropriate targets are those with id's starting with "select_". I had fun demo'ing that by implementing a simple game score updated by clicking on a 2- or 3-point area for either the home or away teams.

var $btn = $('button');
var ins    = 'inside_area_';
var thr    = 'threepoint_area_';
var selIns = 'select_' + ins;
var selThr = 'select_' + thr;
var score  = {home: 0, away: 0};

[[ins, selIns], [thr, selThr]].forEach(function(areas) {
  ['a', 'b'].forEach(function(side) {
    $('#' + areas[1] + side).hover(
      function() {$('#' + areas[0] + side).css('fill', '#1abc9c'    );},
      function() {$('#' + areas[0] + side).css('fill', 'transparent');}
    );
    $('#' + areas[1] + side).click(basketballShotHandler);
  });
});

function basketballShotHandler(evt) {
  areaClicked = evt.target.id;
  var team, pts;
  switch (areaClicked) {
    case 'select_inside_area_a':     team = 'home'; pts = 2; break;
    case 'select_threepoint_area_a': team = 'home'; pts = 3; break;
    case 'select_inside_area_b':     team = 'away'; pts = 2; break;
    case 'select_threepoint_area_b': team = 'away'; pts = 3; break;
  }
  score[team] += pts;
  $('#homeScore').text(score.home);
  $('#awayScore').text(score.away);
}

$btn.click(function(e) {
  var currentSide, opposingSide;
  switch (e.target.innerText) {
    case 'Home':
      currentSide = 'a';
      opposingSide = 'b';
      break;
    case 'Away':
      currentSide = 'b';
      opposingSide = 'a';
      break;
    }
  $('#' + selIns + currentSide).css('visibility', 'visible');
  $('#' + selThr + currentSide).css('visibility', 'visible');
  $('#' + selIns + opposingSide).css('visibility', 'hidden');
  $('#' + selThr + opposingSide).css('visibility', 'hidden');
});
svg {
  height: 100%;
}
.st0 {
  fill: none;
  stroke: #010101;
  stroke-width: 3;
}
.st1 {
  fill: transparent;
  visibility: hidden;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="home">Home</button>
<button id="away">Away</button>
<span>Home: <span id="homeScore">0</span> Away: <span id="awayScore">0</span></span>
<div>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 435.7 234.4" style="enable-background:new 0 0 435.7 234.4;" xml:space="preserve">
  <rect id="XMLID_28_" x="5.2" y="24.3" class="st0" width="0" height="186.7" />
  <path id="threepoint_area_a" class="st0" d="M5.3,24L5.3,24l0-0.7L5.3,24h23.9c52.4,0,94.9,41.8,94.9,93.4s-42.5,93.4-94.9,93.4H5.3 v0.6l0-0.6v18.7h425.4V5.3H5.3V24z" />
  <path id="threepoint_area_b" class="st0" d="M430.4,210.4L430.4,210.4l0,0.7L430.4,210.4h-23.9c-52.4,0-94.9-41.8-94.9-93.4 s42.5-93.4,94.9-93.4h23.9V23l0,0.6V5H5v224.1h425.4V210.4L430.4,210.4z" />
  <path id="inside_area_a" class="st0" d="M29.1,211c52.4,0,94.9-41.8,94.9-93.4S81.5,24.3,29.1,24.3H5.2V211H29.1z" />
  <path id="inside_area_b" class="st0" d="M430.5,23.6v188.1V211h-23.9c-52.4,0-94.9-41.8-94.9-93.4s42.5-93.4,94.9-93.4h23.9" />
  <line id="center_line" class="st0" x1="217.8" y1="231.9" x2="217.8" y2="3.4" />
  <ellipse id="center_circle" class="st0" cx="217.8" cy="117.6" rx="27.3" ry="26.9" />
  <line id="freethrow_line_a" class="st0" x1="93.3" y1="144.5" x2="93.3" y2="90.8" />
  <line id="freethrow_line_b" class="st0" x1="342.4" y1="144.5" x2="342.4" y2="90.8" />
  <path id="freethrow_circle_a" class="st0" d="M93.3,90.8c15.1,0,27.3,12,27.3,26.9s-12.2,26.9-27.3,26.9" />
  <path id="freethrow_circle_b" class="st0" d="M342.4,144.5c-15.1,0-27.3-12-27.3-26.9s12.2-26.9,27.3-26.9" />
  <line id="freethrow_lane_line_a_left" class="st0" x1="93.3" y1="144.5" x2="4.6" y2="144.9" />
  <line id="freethrow_lane_line_a_right_dashes" class="st0" x1="4.4" y1="90.8" x2="93.8" y2="90.8" />
  <line id="freethrow_lane_line_b_left_dashes" class="st0" x1="431.1" y1="144.5" x2="342" y2="144.5" />
  <line id="freethrow_lane_line_b_right_dashes" class="st0" x1="430.6" y1="90.8" x2="342.2" y2="90.8" />
  <line id="basket_board_a" class="st0" x1="23.4" y1="131.1" x2="23.4" y2="104.2" />
  <line id="basket_board_b" class="st0" x1="412.3" y1="131.1" x2="412.3" y2="104.2" />
  <line id="basket_holder_a" class="st0" x1="23.4" y1="117.6" x2="27.9" y2="117.6" />
  <line id="basket_holder_b" class="st0" x1="412.3" y1="117.6" x2="407.7" y2="117.6" />
  <ellipse id="XMLID_27_" class="st0" cx="31.7" cy="117.6" rx="3.8" ry="3.7" />
  <ellipse id="basket_b" class="st0" cx="403.9" cy="117.6" rx="3.8" ry="3.7" />
  <path id="select_inside_area_a" class="st1" d="M29.1,211c52.4,0,94.9-41.8,94.9-93.4S81.5,24.3,29.1,24.3H5.2V211H29.1z" />
  <path id="select_threepoint_area_a" class="st1" d="M5.3,24L5.3,24l0-0.7L5.3,24h23.9c52.4,0,94.9,41.8,94.9,93.4s-42.5,93.4-94.9,93.4H5.3
									v0.6l0-0.6v18.7h425.4V5.3H5.3V24z" />
  <path id="select_inside_area_b" class="st1" d="M430.5,23.6v188.1V211h-23.9c-52.4,0-94.9-41.8-94.9-93.4s42.5-93.4,94.9-93.4h23.9" />
  <path id="select_threepoint_area_b" class="st1" d="M430.4,210.4L430.4,210.4l0,0.7L430.4,210.4h-23.9c-52.4,0-94.9-41.8-94.9-93.4
									s42.5-93.4,94.9-93.4h23.9V23l0,0.6V5H5v224.1h425.4V210.4L430.4,210.4z" />
</svg>
  </div>

Comments