SVG зависает на нескольких слоях, а не только на верхнем - PullRequest
0 голосов
/ 28 сентября 2018

Я хочу отобразить дерево решений в виде SVG с некоторой интерактивностью.Различные пути все там, и при наведении увеличена их непрозрачность.Но состояние наведения, похоже, применяется только к верхнему элементу.

#flow polyline {
  stroke: #0071bc;
  stroke-opacity: 0;
  stroke-width: 8px;

  mix-blend-mode: color;
}
#flow polyline:hover {
  stroke-opacity: 1;
}

https://jsfiddle.net/yv82f3ud/

Как я могу применить событие наведения на все наведенные полилинии svg, а не только на верхний слой?


Дополнительный вопрос: есть ли способ, чтобы к более широкому пути применялся режим наведения, чтобы мне не нужно было точно над линией?

1 Ответ

0 голосов
/ 29 сентября 2018

Как применить событие наведения на все наведенные полилинии svg, а не только на верхний слой?

Нет тривиального пути.Вам нужно будет определить, над каким разделом вы находитесь, определить, какие из них должны быть выделены, а затем вручную выделить их самостоятельно.

Есть ли способ получить более широкий путь, к которому применяется состояние наведениятак что мне не нужно быть точно над линией?

Да, используйте отдельную прозрачную более толстую линию

.line {
  stroke: grey;
  stroke-width: 2;
}

.line-wider {
  stroke: transparent;
  stroke-width: 40;
}

g:hover .line {
  stroke: blue;
}
<svg>
  <g>
    <path d="M0,50 L 300,50" class="line"/>
  </g>
  <g>
    <path d="M0,100 L 300,100" class="line"/>
    <path d="M0,100 L 300,100" class="line-wider"/>
  </g>
</svg>

Вы можете использовать события наведения курсора на разделах с толстой прозрачной линией, чтобы определить, над каким разделом вы находитесь, и сделать подсветку на его основе.

Примерно так:

// Add event listener to each "line-wider" path, that highlights the sections
var sections = document.querySelectorAll(".line-wider");
sections.forEach(function(elem) {
  elem.addEventListener("mouseover", doHover);
  elem.addEventListener("mouseout", clearHover);
});


var highlightedSections = {
  's1':   '.s1, .s11, .s12, .s111, .s112, .s121, .s122',
  's11':  '.s1, .s11, .s111, .s112',
  's12':  '.s1, .s12, .s121, .s122',
  's111': '.s1, .s11, .s111',
  's112': '.s1, .s11, .s112',
  's121': '.s1, .s12, .s121',
  's122': '.s1, .s12, .s122'
};

function doHover(evt) {
  // Which section are we hovering over?
  var id = evt.target.id;
  // highlightedSections[id] is a CSS selector which selects all the sections which should be highlighted for this hover section
  document.querySelectorAll(highlightedSections[id]).forEach( function(elem) {
    // Add the "highlight" class to all the matching sections
    elem.classList.add("highlight");
  });
}


// Remove the "highlight" class from all elements which currently have it set
function clearHover(evt) {
  document.querySelectorAll(".highlight").forEach( function(elem) {
    elem.classList.remove("highlight");
  });
}
.line {
  fill: none;
  stroke: grey;
  stroke-width: 2;
}

.line-wider {
  fill: none;
  stroke: transparent;
  stroke-width: 40;
}

.highlight {
  stroke: blue;
}
<svg width="400" height="500">
  <!-- top section -->
  <path d="M 200,0 L 200,100" class="line s1"/>
  <path d="M 200,0 L 200,100" class="line-wider" id="s1"/>

    <!-- left branch -->
    <path d="M 200,100 L 100,200, 100,300" class="line s11"/>
    <path d="M 200,100 L 100,200, 100,300" class="line-wider" id="s11"/>

      <!-- left branch -->
      <path d="M 100,300 L 50,350, 50,450" class="line s111"/>
      <path d="M 100,300 L 50,350, 50,450" class="line-wider" id="s111"/>
      <!-- right branch -->
      <path d="M 100,300 L 150,350, 150,450" class="line s112"/>
      <path d="M 100,300 L 150,350, 150,450" class="line-wider" id="s112"/>

    <!-- right branch -->
    <path d="M 200,100 L 300,200, 300,300" class="line s12"/>
    <path d="M 200,100 L 300,200, 300,300" class="line-wider" id="s12"/>

      <!-- left branch -->
      <path d="M 300,300 L 250,350, 250,450" class="line s121"/>
      <path d="M 300,300 L 250,350, 250,450" class="line-wider" id="s121"/>
      <!-- right branch -->
      <path d="M 300,300 L 350,350, 350,450" class="line s122"/>
      <path d="M 300,300 L 350,350, 350,450" class="line-wider" id="s122"/>

</svg>
...