#javascript #css #reactjs #svg #hover
Вопрос:
Я пытаюсь создать глобальный трекер COVID-19 для каждой страны, используя React. Чтобы выделить отдельные страны и представить их, я использовал элемент SVG, как показано на рисунке:
<svg
xmlns="http://www.w3.org/2000/svg"
width="inherit"
height="inherit"
fill="#ececec"
stroke="#000"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="0.2"
version="1.2"
viewBox="0 0 2000 857"
className="world-map">
<!-- More Svg -->
<path
d="M669.1 851.7l-3-.2h-5l-6-13.6 3.1 2.8 4.3 4.6 7.8 3.7 7.3 1.5-.8 3-4.4.3-3.3-2.1zM638.6 644.7l11.3 10.4 4.6 1 7.3 4.8 5.9 2.5 1.1 2.8-4.2 9.8 5.8 1.7 6.3 1 4.2-1 4.3-5 .3-5.6 2.6-1.3 3.2 3.8.4 5.1-4.2 3.5-3.3 2.6-5.3 6.3-6 8.7-.5 5.2-.4 6.6 1.2 6.4-.9 1.4.4 4.1.3 3.4 7.8 5.5.2 4.4 3.9 2.8.3 3.1-3.3 8.2-7 3.5-10.2 1.3-6-.7 2.1 3.9.1 4.7 1.8 3.2-2.5 2.3-5.1.9-5.6-2.4-1.5 1.7 2.5 6.3 4 1.9 2.3-2 2.5 3.3-4.2 2-2.9 4 1.2 6.3-.1 3.4h-4.8l-3 3.2.1 4.8 6.5 4.6 5.2 1.2.2 5.7-4.6 3.5-.6 7.3-3.5 2.4-.9 2.9 4.2 6.5 4.6 3.5-2.1-.3-4.9-1-12.1-.8-3.5-3.6-1.9-4.6-3.1.4-2.6-2.3-3.1-6.5 2.7-2.8.1-3.9-1.8-3.2.7-5.4-1.1-8.3-1.8-3.7 1.8-1.2-1.4-2.4-2.8-1.2.8-2.7-3.1-2.4-3.7-7.3 1.7-1.3-3.3-7.8-.8-6.5-.2-5.7 2.5-2.3-3.3-6.3-1.6-5.8 3-4.2-1.4-5.4 1.6-6.2-1.4-5.9-1.6-1.2-4.9-11.1 2.1-6.6-1.7-6.2.9-5.9 2.6-6 3.3-4-2-2.5.8-2.1-1.6-10.7 5.6-3.1 1.2-6.7-.9-1.6 4-5.8 7.5 1.6 3.7 4.6 1.6-5.2 6.4.3 1 1.4z"
className="Argentina"
fill={colorMap[covidMap["Argentina"]]}></path>
<path
d="M645.5 212.5l-2.2-3.6 2.9-8.5-1.6-1.8-3.7 1-1.1-1.6-5.5 4.7-3.2 4.9-2.8 2.9-2.5 1-1.7.3-1.1 1.5h-9.3l-7.8.1-2.7 1.1-6.8 4.4v-.1l-.9-.4-2 .9-1.9 1.3-1.8-1.1-4.7.8-3.9.9-1.9.8-2.3 2.1 1.8.7 1.7-.4h.3l-.3 1.9-4.8.7-2.8.8-1.7 1-2.6-.6-1.6.3-2.9 1.8-4.6 2-2.7-.4 2-2.2 3.7-3.5 4.1-2.1 1.1-1.8.9-3 3.8-3.5.9-4 1.1 3.9 3.8.9 2.4-2.1-1.4-4.8-.9-2-4-1.2-3.8-.7h-3.9l-3.4-.8-.4-1.4-1.4.9-1.2-.2 1.9-2.1-1.8-.8 1.9-2.4-1.2-1.8 1.7-1.8-5.2-.9-.1-3.6-.8-.8-3.3-.2-4.1-1.2-1.5.8-1.8 1.5-3.3 1-3.1 2.5-5.4-1.7-4.4.8-3.9-1.9-4.6-1-3.3-.4-1-1 .9-3.4h-1.7l-1.3 2.4H377l-5.4-6.1-1.6-2.7-7-2.6 1.3-5.5 3.6-3.7-4.1-2.7 3.1-4.9-2.1-4.4 2.5-3.2 5.1-2.9 3.2-3.8-4.6-3.8 1.4-6.9 1.1-4.2-1.6-2.7-.8-2.4.6-3.1-6.5 1.9-7.6 3.3-.3-3.8-.5-2.6-2.8-1.6-4.2-.2L385.4 87 410 66.6l6 1.3 3.3 2.6 3.7.5 6.3-2.2 7-1.7 5.3.6 8.9-2.3 8.2-1.3.2 2.2 4.5-1.3 3.9-2.5 2.1.6 1.4 4.8 9.5-3.7-3.9 4.1 6-.9 3.2-1.5 4.6.3 3.9 2.2 7.5 2 4.7.9 4.4-.3 2.9 2.8-8.5 2.7 6.4 1.1 11.9-.6 4.4-1 1.4 3.3 7.1-2.7-2.1-2.4 4.5-1.8 5.2-.3 3.9-.5 2.1 1.3 1.5 2.9 5-.4 5.3 2.5 7.2-.9 6 .1 2.4-3.4 4.5-.9 4.9 1.8-4.3 5.2 6.2-4.4 3.2.2 6.4-5.5-1.6-3.3-2.9-2.2 5.5-5.9 8.2-3.8 4.5.9 2 2.3.4 6-5.8 2.6 6.7 1.1-4.4 5.5 8.9-4.2 2.2 3.5-4.3 4 1.3 3.7 7.3-3.9 6.5-4.8 4.7-5.9 5.5.4 5.4.8 3.6 2.7-1.7 2.7-5.1 2.9.9 2.9-2.4 2.7-10.9 3.9-6.5.9-3.2-1.7-3.3 2.8-7.4 4.7-3 2.5-7.7 3.8-6.5.4-5.1 2.4-2.9 3.8-5.7.7-8.7 4.7-9.4 6.5-5 4.6-4.9 6.9 6 1-1.5 5.5-.8 4.6 7.3-1.2 7 2.6 3.3 2.3 1.7 2.8 4.9 1.7 3.6 2.5 7.6.4 4.8.6-3.6 5.2-1.7 6.1.1 6.9 4.4 5.9 4.7-2 5.6-6.4 2.3-9.6-1.7-3.2 9-2.9 7.5-4.2 4.8-4.2 1.7-4-.4-5.1-3.2-4.5 8.9-6.2 1-5.3 3.9-9 3.8-1.4 6.7 1.6 4.2.6 4.5-1.6 3.1 2 3.6 3.4.2 2.2 7.7.5-2.6 4.9-2.3 7.4 3.8 1 1.6 3.5 8.2-3.3 7.5-6.6 4.2-2.7 1.1 5.3 2.6 7.5 2 7.2-3.4 3.8 4.8 3.4 2.9 3.4 6.9 1.6 2.4 1.9v5.2l3.4.8 1.1 2.3-2 6.9-4.3 2.3-4.2 2.2-8.8 2.2-7.9 5-8.6 1.1-10.1-1.4h-7.3l-5.3.4-5.7 4.5-7.4 2.8-10.1 8.2-7.9 5.8 4.7-1 10.9-8.3 12.3-5.2 7.6-.6 3.3 3.1-6.1 4.2-.6 6.7.1 4.8 5.6 3.1 8.6-.9 7.2-7.1-1 4.6 2.5 2.3-7.4 4.1-12.4 3.8-5.8 2.5-7.2 4.6-3.7-.5 1.5-5.3 10.4-5.3-8.1.2-5.9.8z"
className="Canada"
fill={/*colorMap[covidMap["Canada"]]*/"orange"}
id="canada"></path>
<text style={{fontSize:"30px"}} textAnchor="middle"><textPath href="#canada">Text</textPath></text>
<!-- More Svg -->
</svg>
Теперь я хочу добиться 2 вещей:
- Как я могу добавить наложение текста, которое находится непосредственно в центре элементов пути, т. Е. В приведенном выше примере я безуспешно пытался использовать элементы SVG text amp; textPath для обозначения пути, заполненного оранжевым цветом с текстом: «Канада»?
- Как я могу добавить эффект наведения, я пробовал добавлять путь:наведение, svg-путь:наведение и даже .Канада:наведите курсор на мой CSS-файл с атрибутами; Цвет фона: «синий» заливка: «синий». Ни одна из этих попыток не сработала. Есть идеи, что я мог бы сделать для достижения вышеуказанного?
Я просмотрел несколько ссылок на переполнение стека, и ни одна из них не решила мою проблему. В идеале я хочу избежать выполнения каких-либо ручных функций javascript, связанных с координатами путей.
Комментарии:
1. Использовал этот ресурс: css-tricks.com/change-color-of-svg-on-hover , по-прежнему безрезультатно.
2. Добавьте дочерний элемент заголовка к каждому пути, т. е. используйте встроенную подсказку SVG.
Ответ №1:
<svg>
...
<text transform="matrix(1 0 0 1 418.5 143.5996)" fontSize="36">Canada</text>
</svg>
Вы можете изменить положение и стили.
2. Чтобы применить эффект наведения
Там нет заливки, поэтому интерьер по умолчанию не улавливает события мыши, и поэтому наведение курсора не реагирует на это. Изменение указателя-события на все исправит это в этом случае:
path{
fill:none;
stroke:black;
pointer-events:all;
}
Вы также можете перейти по этой ссылке.
https://jsfiddle.net/zuul/k7a3q5xm/
Ответ №2:
<textPath>
не сработает, потому что путь-это контур страны- вам нужно
path.getBBox()
рассчитать центр страны - центр-это расположение X,Y для
<text>
названия страны - Я добавил
<g>
групповой тег вокруг каждой страны<path>
для удобства - таким
<text>
образом, элемент вводится сразу после элемента Country<path>
- чтобы заставить работать смежный селектор CSS:
path:hover text { font-size: 50px; fill: white }
- намеренно никакого кода реакции (вы можете сделать это сами), 100% чистый SVG-ответ
- в соответствии с его комментарием Роберт добавил
<title>
тег
<style>svg{height:180px}</style>
<svg id=WORLD xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 240">
<style>
* { pointer-events: none }
path { pointer-events: all; stroke: grey }
text { text-anchor: middle }
path:hover { stroke: black; fill: blue }
path:hover text { font-size: 50px; fill: white }
</style>
<rect width="100%" height="100%" fill="lightblue"></rect>
<g>
<path id="Chile" fill="green" d="m480 222-3 0h-5l-6-14 3 3 4 5 8 4 7 2-1 3-4 0-3-2zm-30-207 11 10 5 1 7 5 6 3 1 3-4 10 6 2 6 1 4-1 4-5 0-6 3-1 3 4 0 5-4 4-3 3-5 6-6 9-1 5 0 7 1 6-1 1 0 4 0 3 8 6 0 4 4 3 0 3-3 8-7 4-10 1-6-1 2 4 0 5 2 3-3 2-5 1-6-2-2 2 3 6 4 2 2-2 3 3-4 2-3 4 1 6 0 3h-5l-3 3 0 5 7 5 5 1 0 6-5 4-1 7-4 2-1 3 4 7 5 4-2 0-5-1-12-1-4-4-2-5-3 0-3-2-3-7 3-3 0-4-2-3 1-5-1-8-2-4 2-1-1-2-3-1 1-3-3-2-4-7 2-1-3-8-1-7 0-6 3-2-3-6-2-6 3-4-1-5 2-6-1-6-2-1-5-11 2-7-2-6 1-6 3-6 3-4-2-3 1-2-2-11 6-3 1-7-1-2 4-6 8 2 4 5 2-5 6 0 1 1z"></path>
</g>
<g>
<path id="Canada" fill="orange" pathLength="100" d="m310 180-2-4 3-9-2-2-4 1-1-2-6 5-3 5-3 3-3 1-2 0-1 2h-9l-8 0-3 1-7 4v0l-1 0-2 1-2 1-2-1-5 1-4 1-2 1-2 2 2 1 2 0h0l0 2-5 1-3 1-2 1-3-1-2 0-3 2-5 2-3 0 2-2 4-4 4-2 1-2 1-3 4-4 1-4 1 4 4 1 2-2-1-5-1-2-4-1-4-1h-4l-3-1 0-1-1 1-1 0 2-2-2-1 2-2-1-2 2-2-5-1 0-4-1-1-3 0-4-1-2 1-2 2-3 1-3 3-5-2-4 1-4-2-5-1-3 0-1-1 1-3h-2l-1 2h-137l-5-6-2-3-7-3 1-6 4-4-4-3 3-5-2-4 3-3 5-3 3-4-5-4 1-7 1-4-2-3-1-2 1-3-7 2-8 3 0-4-1-3-3-2-4 0 37-32 25-20 6 1 3 3 4 1 6-2 7-2 5 1 9-2 8-1 0 2 5-1 4-3 2 1 1 5 10-4-4 4 6-1 3-2 5 0 4 2 8 2 5 1 4 0 3 3-9 3 6 1 12-1 4-1 1 3 7-3-2-2 5-2 5 0 4-1 2 1 2 3 5 0 5 3 7-1 6 0 2-3 5-1 5 2-4 5 6-4 3 0 6-6-2-3-3-2 6-6 8-4 5 1 2 2 0 6-6 3 7 1-4 6 9-4 2 4-4 4 1 4 7-4 7-5 5-6 6 0 5 1 4 3-2 3-5 3 1 3-2 3-11 4-7 1-3-2-3 3-7 5-3 3-8 4-7 0-5 2-3 4-6 1-9 5-9 7-5 5-5 7 6 1-2 6-1 5 7-1 7 3 3 2 2 3 5 2 4 3 8 0 5 1-4 5-2 6 0 7 4 6 5-2 6-6 2-10-2-3 9-3 8-4 5-4 2-4 0-5-3-5 9-6 1-5 4-9 4-1 7 2 4 1 5-2 3 2 4 3 0 2 8 1-3 5-2 7 4 1 2 4 8-3 8-7 4-3 1 5 3 8 2 7-3 4 5 3 3 3 7 2 2 2v5l3 1 1 2-2 7-4 2-4 2-9 2-8 5-9 1-10-1h-7l-5 0-6 5-7 3-10 8-8 6 5-1 11-8 12-5 8-1 3 3-6 4-1 7 0 5 6 3 9-1 7-7-1 5 3 2-7 4-12 4-6 3-7 5-4-1 2-5 10-5-8 0-6 1z"></path>
</g>
<text font-size="60px"><textPath startoffset="36" href="#Canada">Canada</textPath></text>
</svg>
<script>
WORLD.querySelectorAll("path").forEach(country => {
let { x, y, width, height } = country.getBBox();
let cx = x width / 2;
let cy = y height / 2;
let center = document.createElementNS("http://www.w3.org/2000/svg", "circle");
center.setAttribute("cx", cx);
center.setAttribute("cy", cy);
center.setAttribute("r", 5);
center.setAttribute("fill", "red");
let name = document.createElementNS("http://www.w3.org/2000/svg", "text");
name.setAttribute("x", cx);
name.setAttribute("y", cy - 5);
name.innerHTML = country.id;
let title = document.createElementNS("http://www.w3.org/2000/svg", "title");
title.innerHTML = country.id;
country.parentNode.append(name, center, title);
})
</script>