无法将 SVG 移动到屏幕中央

问题描述 投票:0回答:2

正如标题所示,我试图在单击 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>

我按照这里的一些说明进行操作text,我设法让它向中心移动一点,但不是一直移动。 谢谢您的帮助。

javascript html css svg
2个回答
2
投票

我不太确定你想要实现什么。请尝试以下操作:

  1. 将形状放入带有紧密 viewBox 的符号中。在这种情况下:

    <symbol id="braga_porto" viewBox="2848 1665 3985 4275">

  2. 使用符号,使其落在原始位置:

    <use href="#braga_porto" x="2848" y="1665" width="3985" height="4275"...

请将 x、y 宽度和高度属性的值与符号的 viewBox 进行比较。

  1. 如果需要将形状放大到 svg 的宽度,则需要将
    <use>
    的位置 (x,y) 更改为 0,0(svg 画布的左上角)。使用将占用整个宽度(即 12969)。您需要计算高度,使其符合纵横比(即 4275 * 12969 / 3985)。

请将使用的新宽度与svg元素的viewBox的值进行比较。

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>

为了获取符号的紧密 viewBox 的值,我使用了 getBBox() 方法。


0
投票

问题是你的每个形状都以一个非常大的M(移动)开始 - 这使得边界矩形非常大,因为绘制的起点距离填充路径大约半个屏幕 - 你必须补偿这在你的边界矩形计算中(并且不要忘记使用 viewBox 与宽度/高度的比率进行计算。)

© www.soinside.com 2019 - 2024. All rights reserved.