Итак, как следует из названия, я безуспешно пытаюсь переместить части SVG в центр экрана при щелчке по ним.
Я понятия не имею, почему это происходит, поскольку я попробовал это на другом SVG, и он работает отлично.
const svg = document.querySelector("svg");
const paths = document.querySelectorAll("svg path");
const popUp = document.querySelector(".pop");
let selectedPath = null;
function calcCenterMove(element){
/*
X and Y are the current position of the element to be moved (top left corner).
Width and Height are the width and height of the element to be moved.
CX and CY are the X and Y coordinates of the centre of the screen.
*/
var x = element.getBoundingClientRect().x * 2;
var y = element.getBoundingClientRect().y * 2;
var width = element.getBoundingClientRect().width * 2;
var height = element.getBoundingClientRect().height * 2;
var cx = window.innerWidth / 2;
var cy = window.innerHeight / 2;
var xVector = cx-(width/2)-x;
var yVector = cy-(height/2)-y;
return [xVector, yVector];
}
for (const path of paths) {
path.addEventListener("click", (event) => {
if (selectedPath === path) return; // Don't change if clicking the same path again
selectedPath = path;
paths.forEach(otherPath => {
if (otherPath !== selectedPath) {
otherPath.style.opacity = "0.4"
otherPath.style.fill = "lightgray"; // Reduce opacity for unselected paths
otherPath.style.pointerEvents = "none";
}
});
var xAxisMove = calcCenterMove(svg)[0];
var yAxisMove = calcCenterMove(svg)[1];
path.style = "transform: translate("+xAxisMove+"px,"+yAxisMove+"px);";
path.classList.add("selected");
path.style.pointerEvents = "auto";
if (selectedPath != null) {
document.documentElement.addEventListener("click", captureClick, true);
}
});
function captureClick(event) {
if (!event.target.classList.contains("selected")) {
var xAxisMove = calcCenterMove(svg)[0];
var yAxisMove = calcCenterMove(svg)[1];
selectedPath.style = "transform: translate("+-xAxisMove+"px,"+-yAxisMove+"px);";
for (const path of paths) {
path.classList.remove("selected");
path.style.opacity = 1;
path.style.pointerEvents = "auto";
path.style.fill = "gray";
}
selectedPath = null;
document.documentElement.removeEventListener("click", captureClick, true);
}
}
path.addEventListener("mouseenter", (event) => {
const pathId = event.target.id;
popUp.querySelector("p").textContent = `Content for path: ${pathId}`;
const pathRect = event.target.getBoundingClientRect();
popUp.style.top = `${pathRect.top + pathRect.height / 2}px`;
popUp.style.left = `${pathRect.left + pathRect.width / 2}px`;
popUp.style.opacity = 0.8;
});
path.addEventListener("mouseenter", (event) => {
const districtName = event.target.id;
event.target.style.fill = "red";
});
path.addEventListener("mouseleave", () => {
event.target.style.fill = "";
popUp.style.opacity = 0;
});
}.hoverme {
display: none;
}
body{
background: white;
font-family: 'Open Sans Hebrew', Arial, sans-serif;
text-align: center;
}
.div-svg{
float: right;
}
svg{
position: relative;
height: auto;
}
svg path {
fill: gray;
cursor: pointer;
transition: all 0.3s ease;
}
svg path.selected {
fill: #007bff;
transition: all 0.3s ease;
transform: scale(2);
}
svg path:hover {
fill: rgba(black, 0.3);
.pop {
opacity: 1;
width: 200px;
height: 200px;
}
}
.pop {
pointer-events: none;
position: absolute;
transition: all 0.3s ease;
background-color: lightblue;
}<div class = "div-svg">
<svg width = "700" height = "700" viewBox = "0 0 12969 26674">
<path id = "Braga" data-z = "32" class = "Braga" d = "M5329 1730c-66-17-64 0-92 15l-110 113c-121 4-292 156-324 162-42-3-181 2-190-1l-63-42-153 42c-101 28-190 153-246 162-51-1-120-63-171 40-4 70-22 172-11 235-20 5-54 13-72 31l-21 36c-2 67 22 43 26 107l-40 111-33 28-36-11-62-98c-65-6-65 3-114 40-67-40-52-40-108-46l-17-34-39 18 1 73c-47-2-31 4-66-28-40 2-230 40-268 53l-15 35c-82 42-170 47-257 69l65 294v261l66 131v131c58-22 39-9 81-55l27 42c109 12 53-8 132 66l116-33 37 19c30 44 51 107 91 124 77 31 65 60 140 30 45 26 29 11 64 87l-136 68 54 184c22 1 354-18 355-19 43-53 52-56 91-127l199-29 49 55c169 16 391-82 456-69-5 45-7 28 10 72 85-32 174-64 260-95 18-12 31-70 32-70 71-42 91-27 138-55l9-72c200 51 198-5 310 190-62 100 186 171 254 209 28-43 13-30 58-54 34 44 76 73 118 125 13-1 198-149 211-169l33-101c7-14 156-340 157-344 9-53-16-96 14-224l57-58c77 5 27 32 103-17 20-33-6-61 15-92l68 6c18-31 175-267 176-267 47-34 93-52 67-124l-67-130-77-25c-39 47-31 42-60 106-28 5-189 31-190 31-53-16-324-80-356-101-10-157 16-226 65-356-19-23-196-122-214-117-103 32-202 79-336 73 47-93 81-60 123-143 21-42 16-47 19-78 7-67 32-123 89-158-19-156 4-155 96-264l-98-33-163 131-327-66z"/>
<path id= "Porto" cx = "50" cy = "50" r = "40" data-z = "33" class = "Porto" d = "M2979 3657c58-22 39-9 81-55l27 42c109 12 53-8 132 66l116-33 37 19c30 44 51 107 91 124 77 31 65 60 140 30 45 26 29 11 64 87l-136 68 54 184c22 1 354-18 355-19 43-53 52-56 91-127l199-29 49 55c169 16 391-82 456-69-5 45-7 28 10 72 85-32 174-64 260-95 18-12 31-70 32-70 71-42 91-27 138-55l9-72c200 51 198-5 310 190-62 100 186 171 254 209 28-43 13-30 58-54 34 44 76 73 118 125 13-1 198-149 211-169l33-101c16 22 26 37 54 52 45 24 25-8 53 50l-63 72 17 36c22 24 296 61 184 170 8 70 98 202 161 240l-67 180c60 164-59 157-5 260-80 148-101 93-78 206-81-1-47 33-132-15l-63 52c-4 1-330 118-382 134-200 36 0-77-312 49-60 24-159-10-215-29-99-33-95 35-136 75-61-6-43-9-81 9l-80 56c-66-44-124-64-152-46-34 46-183 240-248 197-88-57-84-35-184-62 29 91-23 107 68 163-6 89 13 55-17 111-120-48-33-85-155-107l19-71c-109-48-10-16-110-91-61 62-65 8-143 50 110 52 39 12 47 139-49 42-41 32-112 63l-90-133-33-19c-73 42-75 33-102 107l-76 28c-96-16-95-48-202-36l-32-26-33-130-32-98v-196l-66-196-153-308c-15-180-51-371-108-541v-131l-32-98-66-98-65-195 33-196z"/>
</svg>
</div>
<div class = "pop"> <p>This is the pop-up content.</p>
</div>Я следовал некоторым инструкциям здесь текст, мне удалось сдвинуть его НЕМНОГО к центру, но не до конца. Спасибо за помощь.
Добавьте рамку к элементу svg, чтобы понять, почему вы не можете переместить его в центр окна. Также вы устанавливаете ширину и высоту для вашего svg-элемента, которые не соответствуют соотношению сторон viewBox. В зависимости от того, чего вы хотите достичь, возможным решением может быть использование узкого viewBox.
@TimRoberts да, это всего лишь прототип, но карта должна быть в правой части экрана.
@enxaneta моя цель - иметь возможность щелкнуть элемент svg, и после этого он переместится в центр экрана, а затем масштабирует его. Я посмотрю на ширину и высоту SVG и проверю его границы.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не очень уверен, чего вы хотите достичь. Пожалуйста, попробуйте следующее:
Поместите фигуру в символ с плотным viewBox. В этом случае:
<symbol id = "braga_porto" viewBox = "2848 1665 3985 4275">
Используйте символ так, чтобы он оказался в исходном положении:
<use href = "#braga_porto" x = "2848" y = "1665" width = "3985" height = "4275"...
Сравните значения атрибутов ширины и высоты x, y с viewBox символа.
<use> на 0,0 (верхний левый угол холста SVG). Использование будет занимать всю ширину (т. е. 12969). Вам нужно будет рассчитать высоту так, чтобы она соответствовала соотношению сторон (т. е. 4275 * 12969/3985).Сравните новую ширину использования со значением viewBox элемента svg.
use.addEventListener("click",()=>{
use.setAttribute("x","0");
use.setAttribute("y","0");
use.setAttribute("width",12969);
use.setAttribute("height",4275 * 12969 / 3985);
});svg{border:solid}<svg viewBox = "0 0 12969 26674">
<symbol id = "braga_porto" viewBox = "2848 1665 3985 4275">
<path id = "Braga" data-z = "32" class = "Braga" d = "M5329 1730c-66-17-64 0-92 15l-110 113c-121 4-292 156-324 162-42-3-181 2-190-1l-63-42-153 42c-101 28-190 153-246 162-51-1-120-63-171 40-4 70-22 172-11 235-20 5-54 13-72 31l-21 36c-2 67 22 43 26 107l-40 111-33 28-36-11-62-98c-65-6-65 3-114 40-67-40-52-40-108-46l-17-34-39 18 1 73c-47-2-31 4-66-28-40 2-230 40-268 53l-15 35c-82 42-170 47-257 69l65 294v261l66 131v131c58-22 39-9 81-55l27 42c109 12 53-8 132 66l116-33 37 19c30 44 51 107 91 124 77 31 65 60 140 30 45 26 29 11 64 87l-136 68 54 184c22 1 354-18 355-19 43-53 52-56 91-127l199-29 49 55c169 16 391-82 456-69-5 45-7 28 10 72 85-32 174-64 260-95 18-12 31-70 32-70 71-42 91-27 138-55l9-72c200 51 198-5 310 190-62 100 186 171 254 209 28-43 13-30 58-54 34 44 76 73 118 125 13-1 198-149 211-169l33-101c7-14 156-340 157-344 9-53-16-96 14-224l57-58c77 5 27 32 103-17 20-33-6-61 15-92l68 6c18-31 175-267 176-267 47-34 93-52 67-124l-67-130-77-25c-39 47-31 42-60 106-28 5-189 31-190 31-53-16-324-80-356-101-10-157 16-226 65-356-19-23-196-122-214-117-103 32-202 79-336 73 47-93 81-60 123-143 21-42 16-47 19-78 7-67 32-123 89-158-19-156 4-155 96-264l-98-33-163 131-327-66z"/>
<path id= "Porto" cx = "50" cy = "50" r = "40" data-z = "33" class = "Porto" d = "M2979 3657c58-22 39-9 81-55l27 42c109 12 53-8 132 66l116-33 37 19c30 44 51 107 91 124 77 31 65 60 140 30 45 26 29 11 64 87l-136 68 54 184c22 1 354-18 355-19 43-53 52-56 91-127l199-29 49 55c169 16 391-82 456-69-5 45-7 28 10 72 85-32 174-64 260-95 18-12 31-70 32-70 71-42 91-27 138-55l9-72c200 51 198-5 310 190-62 100 186 171 254 209 28-43 13-30 58-54 34 44 76 73 118 125 13-1 198-149 211-169l33-101c16 22 26 37 54 52 45 24 25-8 53 50l-63 72 17 36c22 24 296 61 184 170 8 70 98 202 161 240l-67 180c60 164-59 157-5 260-80 148-101 93-78 206-81-1-47 33-132-15l-63 52c-4 1-330 118-382 134-200 36 0-77-312 49-60 24-159-10-215-29-99-33-95 35-136 75-61-6-43-9-81 9l-80 56c-66-44-124-64-152-46-34 46-183 240-248 197-88-57-84-35-184-62 29 91-23 107 68 163-6 89 13 55-17 111-120-48-33-85-155-107l19-71c-109-48-10-16-110-91-61 62-65 8-143 50 110 52 39 12 47 139-49 42-41 32-112 63l-90-133-33-19c-73 42-75 33-102 107l-76 28c-96-16-95-48-202-36l-32-26-33-130-32-98v-196l-66-196-153-308c-15-180-51-371-108-541v-131l-32-98-66-98-65-195 33-196z"/>
</symbol>
<use href = "#braga_porto" x = "2848" y = "1665" width = "3985" height = "4275" id = "use" />
</svg>Чтобы получить значения для узкого окна просмотра символа, я использовал метод getBBox().
Во-первых, спасибо за ответ. Чтобы не флудить и не спамить просьбой о помощи, я уменьшил SVG, но все это карта, карта Португалии с ее районами. Моя цель — иметь возможность щелкнуть по любому из районов, и когда я это сделаю, выбранный район переместится в центр экрана, а затем увеличится.
Проблема в том, что каждая из ваших фигур начинается с очень большой буквы M (перемещение), что делает ограничивающий прямоугольник очень большим, поскольку начальная точка рисования находится примерно на полэкрана от заполненного пути - вы должны это компенсировать. в расчете ограничивающего прямоугольника (и не забудьте выполнить расчеты, используя соотношение viewBox и ширины/высоты.)
Это имеет смысл
После некоторого тестирования я изменил SVG и сумел как-то заставить его работать.
У вас
.div-svgплавает вправо. Вы это намеревались?