Как реализовать появление блока при наведениии на svg path?
Подскажите пожалуйста, как реализовать появление блока, при наведении на path внутри sgv. Есть sgv карта, внутри несколько path - области. При наведении на каждый район он закрашивается - всё ок. Но как сделать так, чтоб при наведении еще и отобразился блок у которого стиль display:none;
Со ссылкой - без проблем:
.hide {
display: none;
}
a:hover + .hide {
display: block;
}
<a href="">Ссылка</a>
<div class="hide">123456789</div>
А вот с path никак получается.
Мой код с работающей ссылкой и не работающим svg - https://codepen.io/innocentDimon/pen/VwpLbMr?editors=1100
Ответы (3 шт):
Держи) Поделюсь своей работой, может сможешь разобраться
body {
height: 100vh;
background: linear-gradient(180deg, rgb(0, 91, 187) 40%, rgb(255, 213, 0) 41%);
}
#Ukraine {
height: 100vh;
margin-left: 5%;
}
#KyivCity {
fill: #3184EA;
opacity: 0;
}
.mapBackground {
fill: #74B2FF;
stroke: #000;
stroke-width: 0.5;
}
#Ukraine path:hover {
fill: #97C2F8;
}
.pointerCircle {
r: 2px;
fill: #f00;
stroke-linecap:square;
stroke-linejoin:bevel;
stroke-miterlimit:4;
stroke-dasharray:none;
stroke-dashoffset:0;
stroke-opacity:1;
}
.cityName {
visibility: hidden;
opacity: 0;
transition: all 0.3s ease;
pointer-events: none;
font-family: 'Roboto', sans-serif;
font-weight: bold;
font-size: 0.7em;
fill: #000;
text-shadow: white 1px 1px 0, white -1px -1px 0,
white -1px 1px 0, white 1px -1px;
}
#Kiev:hover ~.cityKiev,
#KyivCity:hover ~.cityKiev,
#SevastopolCity:hover ~.citySevastopol,
#Crimea:hover ~.citySimferopol,
#Cherkasy:hover ~.cityCherkasy,
#Chernivtsi:hover ~.cityChernivtsi,
#Dnipropetrovsk:hover ~.cityDnipro,
#Donetsk:hover ~.cityDonetsk,
#Ivano-Frankivsk:hover ~.cityIvano-Frankivsk,
#Kharkiv:hover ~.cityKharkiv,
#Kherson:hover ~.cityKherson,
#Khmelnytskyi:hover ~.cityKhmelnytskyi,
#Kirovohrad:hover ~.cityKropyvnytskyi,
#Luhansk:hover ~.cityLuhansk,
#Lviv:hover ~.cityLviv,
#Mykolaiv:hover ~.cityMykolaiv,
#Odessa:hover ~.cityOdessa,
#Poltava:hover ~.cityPoltava,
#Rivne:hover ~.cityRivne,
#Sumu:hover ~.citySumu,
#Chernihiv:hover ~.cityChernihiv,
#Ternopil:hover ~.cityTernopil,
#Zakarpattia:hover ~.cityUzhhorod,
#Vinnytsia:hover ~.cityVinnytsia,
#Volyn:hover ~.cityLutsk,
#Zaporizhia:hover ~.cityZaporizhia,
#Zhytomyr:hover ~.cityZhytomyr{
visibility: visible;
opacity: 1;
}
Для этого примера я создал на бесплатном хосте сайтик без индэксного файла и залил на него json с таким же содержимм каки в моём комментрии ..
Потом методом fetch получил его и создал в html соответствующую разметку и в него вывел svg и сделал при наведении mouseover появление описание выбранной области
Плюсы такого подхода в том что при минимальном javascript коде мы получаем всю сразу карту с описанием - смотрим пример без заваливания html кучей тегов
function letsvg() {
fetch('https://facejsonserver.000webhostapp.com/ ')
.then((response) => {
return response.json();
})
.then((data) => {
let svg = "";
for (let value in data) {
let path = data[value];
let ids = path['data-id'];
let name = path['data-name'];
let paths = path['data-path'];
let description = path['data-description'];
svg += `<path d="${paths}"
data-name="${name}"
id="${ids}"
data-description="${description}"/>`;
}
map.innerHTML = svg;
});
}
letsvg();
map.addEventListener("mouseover", function(e) {
document.querySelector(".description").innerHTML =
e.target.getAttribute("data-description");
})
path:hover {
fill: blue;
}
.grid {
margin: 30px auto;
max-width: 768px;
display: grid;
grid-template-columns: 1fr 1fr;
}
.description {
font-size: 14px;
display: flex;
align-items: center;
margin-left: 30px;
}
<div class="grid">
<svg id="map" viewBox="0 0 1000 670"></svg>
<div class="description"></div>
</div>
Для того что бы сгенерировать такой json я поступил таким образом
- Вычистил не нужное теги g etc...
- Методом forEach перебрал все path и все поместил в один массив
Выглядит это так:
let paths = document.querySelectorAll("#map path");
let mass2 = [];
paths.forEach(function (path){
let ids = path.getAttribute("id");
let ds = path.getAttribute("d");
let name = path.getAttribute("name");
let description = "";
mass2.push({
"dataid":ids,
"datapath":ds,
"dataname":name ,
"datadescription": description
})
})
console.log(mass2)
И далее в кансоле выбираем Copy Object и потом создаём и переименовываем txt в json и вставляем ... ВСЁ и потом уже руками дополняем description
Для реализации показа одного элемента при наведении на другой в данном случае совсем не обязательно использование JS. Стоит заметить, что любой элемент содержимого SVG, в том числе и path - это обычный элемент, который ничем не отличается от любого другого элемента содержимого всего HTML-документа.
Простой вариант CSS с использованием SVG-элемента <foreignObject>. Для того, чтобы сократить CSS код до одной строчки:
path:hover ~ foreignObject {}
заключаем элементы path и foreignObject для группировки в элемент g.
Пример:
#map {
margin: 0 auto; width: 500px;
}
#map svg {
width: 100%; height: 250px;
stroke: yellow; fill: green;
background: aliceblue; border: 1px solid lightgray;
}
#one:hover {fill: red;}
#two:hover {fill: deepskyblue;}
.win__one {width: 120px; height: 40px; background: red;}
.win__two {width: 120px; height: 40px; background: deepskyblue;}
path {cursor: pointer; transition: all 0.5s;}
path:hover {transform: scale(1.05);}
foreignobject {
display: none; opacity: 0;
transition: all 0.5s;
}
path:hover ~ foreignObject {
display: block; opacity: 1;
transition: all 0.5s;
}
<div id="map">
<svg>
<g>
<g>
<path id="one" title="EnSO" d="M313.23,58.66L306.56,87.28L299.68,118.48L300.3,122.21L299.24,126.14L267.26,118.43L261.12,119.3L257.44,117.29L253.95,118.28L247.56,119.17L240.68,116.96L236.67,117.76L233.22,117.63L231.12,115.79L225.89,113.27L222.2,112.96L215.57,113.53L211.77,112.47L208.47,110.57L208.26,107.16L208.97,103.37L207.41,98.33L203.38,95.72L200.31,92.59L195.72,91.03L192.49,90.34L194.19,70.89L198.52,49.07L217.79,59.52L219.14,78.74L224.58,74.04L227.61,55.27L226.19,34.98L269.51,47.56z"/>
<foreignObject class="win__one">
<span>Окно EnSO</span>
</foreignObject>
</g>
<g>
<path id="two" title="RuSO" d="M299.24,126.14L301.91,131.28L304.11,133.69L304.17,137.26L301.92,139.8L298.48,145.04L294.56,151.7L290.12,155.29L286.7,159.8L285.82,163.34L288.45,165.54L289.06,168.74L286.18,174.71L276.58,214.43L276.56,214.49L227.74,202.25L159.29,181.87L158.03,168.07L170.35,146.42L179.28,122.31L192.49,90.34L195.72,91.03L200.31,92.59L203.38,95.72L207.41,98.33L208.97,103.37L208.26,107.16L208.47,110.57L211.77,112.47L215.57,113.53L222.2,112.96L225.89,113.27L231.12,115.79L233.22,117.63L236.67,117.76L240.68,116.96L247.56,119.17L253.95,118.28L257.44,117.29L261.12,119.3L267.26,118.43z"/>
<foreignObject class="win__two">
<span>Окно RuSO</span>
</foreignObject>
</g>
</g>
</svg>
</div>
