Есть ли способ настроить контейнер svg на его содержимое? - PullRequest
2 голосов
/ 11 октября 2019

Я разрабатываю интерактивную карту, где можно увидеть стрелки. Эти стрелки сделаны с кодом SVG. При щелчке контейнера SVG появляется всплывающее окно, как показано на рисунке ниже:

Stations

Основная проблема заключается в том, что поле для монетодержателя (помеченос сплошной белой рамкой 1px) действует как зона щелчка для отображения всплывающего окна, затрудняя щелчок по одной из них, когда рядом находятся стрелки, как в следующем примере:

near arrows

Итак, я пытаюсь сделать контейнер svg похожим на маленькую стрелку большего размера:

wanted solution

Сделать его легко кликаемым по желаемомуarrow.

Я не очень опытный разработчик HTML / javascript, поэтому я не знаю, можно ли «придать форму» контейнеру SVG для его содержимого, сделав его с той же формой «стрелки»,и, если возможно, как мне поступить?

РЕДАКТИРОВАТЬ 1: jsfiddle с примером:

Я использую следующий код JavaScript:

function windArrow(speed, angle)
{    
  //var angulo = 0;
  var direction = 90-angle;
  // var speed = 20;
  var x = speed*Math.cos(deg2rad(direction)).toFixed(4);
  var y = speed*Math.sin(deg2rad(direction)).toFixed(4);
  var svgHeader = '<svg version="1.1" id="arrow_svg" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="100px" height="100px" ><defs><marker id="arrowHead" markerWidth="10" markerHeight="10" refX="0" refY="1" orient="auto" markerUnits="strokeWidth"><path d="M0,0 L0,2 L2,1 z" stroke="none" fill="red"/><path stroke-width=".3" stroke="white" fill="none" d="M0,0 L0,2 L2,1 z" /></marker></defs>';
  var outerArrow = '<g class="outerArrow"> <path marker-end="url(#arrowHead)" d="M50,50 l'+x.toString()+','+y.toString()+'" /></g>';
  var innerArrow = '<g  class="innerArrow"><path marker-end="url(#arrowHead)" d="M50,50 l'+x.toString()+','+y.toString()+'" /></g>';
  var svgFoot = '</svg>';
  return svgHeader+outerArrow + '\n' + innerArrow + svgFoot;
}
document.getElementById('arrow').innerHTML = windArrow(20,45);

DEMO: https://jsfiddle.net/manespgav/at8y24dL/3/

Ответы [ 3 ]

5 голосов
/ 11 октября 2019

Я не совсем уверен, что вы хотите, но вы можете привязать onclick к компоненту svg

svg { pointer-events: none; border: 1px solid black;}
svg * { pointer-events: auto;}
#g2 { position:absolute; left:50px;}
<svg height="100" width="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="gray" onclick="console.log('clicked Gray')"/>
</svg>
<svg id=g2 height="100" width="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="green" onclick="console.log('clicked Green')"/>
</svg>
1 голос
/ 11 октября 2019

Существует несколько способов исправить ваше решение. Как говорится в другом ответе, вы можете привязать события щелчка к соответствующему элементу вашей SVG-графики - например, к явно заданному хитбоксу для стрелки, всей стрелки, ее кончика или чего-либо еще.

Другое решениеи я лично думаю, что это тот, который вы должны предпочесть - потому что ваши SVG-измерения кажутся произвольными и не имеют особого смысла, учитывая, что они просто жестко закодированы, а ваша стрелка занимает лишь часть этого. Вам нужно исправить окно просмотра документа SVG с помощью атрибута viewBox в элементах SVG.

Спецификация SVG очень хорошо это охватывает, но вкратце ваша проблема заключается в том, чточто ваш SVG имеет размеры 100 x 100 пикселей, в то время как графические изображения со стрелками намного меньшеУдалите атрибуты width и height из корневого элемента SVG, вместо этого добавьте атрибут viewBox с соответствующими значениями для области просмотра (определяя его размер в ограничительной рамке вашей стрелки) и используйте CSS для управления визуализацией . размеры ваших svg элементов на карте.

0 голосов
/ 11 октября 2019

События указателя могут помочь вам достичь более точных зон нажатия:

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/pointer-events

...