javascript - 如何使 svg 路径元素从元素未知中心点向上和向下缩放?
问题描述
我试图在鼠标悬停在 svg 上时弹出一些 svg 元素(通过缩放),反之亦然,当鼠标离开 svg 元素时。
我已经能够通过使用转换使 svg 元素的大小增加,但我希望它从每个元素的中心缩放。到目前为止,我已经习惯于.getBBox()
获取元素的边界并从名为godwardSqare_obj
. 我已经尝试在该函数selected_colour
中使其从中心按比例放大,但它不起作用;它按比例放大,但不是从元素的中心开始。
当我在浏览器上检查元素时,我可以看到翻译和转换正在应用于元素,但只有转换比例有效。
这是我的 svg(我使用这个网站svg-edit创建它):
function unselected_colour(evt) {
// get the element that triggered the browser event
let target = evt.target;
// modify the element
target.setAttribute('transform', 'scale(1)')
}
function selected_colour(evt) {
// get the element that triggered the browser event
let target = evt.target;
// modify the element
target.setAttribute('translate', '(cx/2, cy/2)');
target.setAttribute('translate','(0-cx,0-cy)');
target.setAttribute('transform', 'scale(1.25)')
}
// find the SVG rectangle in the DOM
let mileEndRoad_obj = document.getElementById('mile_end_road');
let bandcroftRoad_obj = document.getElementById('bandcroft_road');
let godwardSquare_obj = document.getElementById('godward_sqaure');
var godWard_Rect = godwardSquare_obj.getBBox();
godwardSquare_obj.setAttribute('x', godWard_Rect.x);
godwardSquare_obj.setAttribute('y', godWard_Rect.y);
godwardSquare_obj.setAttribute('width', godWard_Rect.width);
godwardSquare_obj.setAttribute('height', godWard_Rect.height);
godwardSquare_obj.setAttribute('cx', (godWard_Rect.x+0.5*godWard_Rect.width));
godwardSquare_obj.setAttribute('cy', (godWard_Rect.y+0.5*godWard_Rect.height));
let compSci_obj = document.getElementById('computer_science');
let itl_obj = document.getElementById('itl');
let engineering_obj = document.getElementById('engineering');
let peoplePalace_obj = document.getElementById('people_palace');
// pass the above functions as callbacks, to be triggered by mouse events
godwardSquare_obj.addEventListener('mouseover', selected_colour, false);
godwardSquare_obj.addEventListener('mouseout', unselected_colour, false);
compSci_obj.addEventListener('mouseover', selected_colour, false);
compSci_obj.addEventListener('mouseout', unselected_colour, false);
itl_obj.addEventListener('mouseover', selected_colour, false);
itl_obj.addEventListener('mouseout', unselected_colour, false);
engineering_obj.addEventListener('mouseover', selected_colour, false);
engineering_obj.addEventListener('mouseout', unselected_colour, false);
peoplePalace_obj.addEventListener('mouseover', selected_colour, false);
peoplePalace_obj.addEventListener('mouseout', unselected_colour, false);
<svg width="1640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit-->
<g class="layer">
<title>map</title>
<path d="m38,86.66667l0,94l64.66666,0l0.00001,-28l8.66666,0l0,27.33333l35.33334,0l-11.33334,-20l-12.66666,0l-0.00001,-8c8,0 12.66667,0 12.66667,0c0,0 -0.66667,-65.33333 0,-65.33333c0.66667,0 -89.33333,0 -97.33333,0z"
fill="rgb(94,43,126)" id="computer_science" stroke="#000000" stroke-width="5"/>
<rect fill="#10a3a3" height="447.44527" id="bandcroft_road" stroke="#10a3a3" stroke-width="5" width="35.76642" x="308.90512" y="-24.52553"/>
<rect fill="#10a3a3" height="54.74453" id="mile_end_road" stroke="#10a3a3" stroke-width="5" width="647.44528" x="-1.31387" y="425.10952"/>
<path d="m239.41174,257.50001l-133.52938,-0.14706l-0.00001,-69.85294l50.7353,-0.00001l-16.17647,-31.61765l58.82353,0l0,30.14706l39.70588,0l0.44115,71.4706z"
fill="#1bd1a6" id="godward_sqaure" stroke="#1bd1a6" stroke-width="5"/>
<rect fill="rgb(94,43,126)" height="100.5" id="itl" stroke="#000000" stroke-width="5" width="65" x="37" y="192"/>
<path d="m174.99947,274.5c-0.33149,41.16667 0.33149,82.83333 0,124l290.39161,0l0,-11.5l69.138332,0l0,-37l-68.641082,0l0,-142.5l-101.93541,0l0,167.5l-73.09515,0l0,-101l-115.8583,0.5z"
fill="rgb(94,43,126)" id="engineering" stroke="#000000" stroke-width="5"/>
<path d="m534.99996,206.029419l70.147082,-0.147072c0,0 0.441155,35.441191 -0.294139,34.705896c-0.735294,-0.735294 33.088235,0.000001 32.64708,-0.147072c-0.441155,-0.147073 0.441156,39.852955 0,39.705882c-0.441155,-0.147073 -18.676491,0.147074 -19.117647,0c-0.441156,-0.147073 0.441155,116.323546 0,116.176471c-0.441155,-0.147076 -82.647081,0.882369 -83.088235,0.735294c-0.441154,-0.147076 -0.294141,-191.764693 -0.294141,-191.029399z"
fill="rgb(94,43,126)" id="people_palace" stroke="#000000" stroke-width="5"/>
</g>
</svg>
解决方案
- 在您只使用字符串的那一刻,您实际上需要在 selected_colour 中计算 cx 和 cy
- 您需要将 cx 和 cy 字符串转换为这些变量的值
- 没有翻译这样的属性,即使有翻译也会覆盖。
- 您需要在一个步骤中设置所有转换
function unselected_colour(evt) {
// get the element that triggered the browser event
let target = evt.target;
// modify the element
target.setAttribute('transform', 'scale(1)')
}
function selected_colour(evt) {
// get the element that triggered the browser event
let target = evt.target;
// modify the element
let rect = target.getBBox();
let cx = rect.x + rect.width / 2;
let cy = rect.y + rect.height / 2;
target.setAttribute('transform', `translate(${cx}, ${cy}) scale(1.25) translate(${-cx},${-cy})`)
}
// find the SVG rectangle in the DOM
let mileEndRoad_obj = document.getElementById('mile_end_road');
let bandcroftRoad_obj = document.getElementById('bandcroft_road');
let godwardSquare_obj = document.getElementById('godward_sqaure');
var godWard_Rect = godwardSquare_obj.getBBox();
godwardSquare_obj.setAttribute('x', godWard_Rect.x);
godwardSquare_obj.setAttribute('y', godWard_Rect.y);
godwardSquare_obj.setAttribute('width', godWard_Rect.width);
godwardSquare_obj.setAttribute('height', godWard_Rect.height);
godwardSquare_obj.setAttribute('cx', (godWard_Rect.x+0.5*godWard_Rect.width));
godwardSquare_obj.setAttribute('cy', (godWard_Rect.y+0.5*godWard_Rect.height));
let compSci_obj = document.getElementById('computer_science');
let itl_obj = document.getElementById('itl');
let engineering_obj = document.getElementById('engineering');
let peoplePalace_obj = document.getElementById('people_palace');
// pass the above functions as callbacks, to be triggered by mouse events
godwardSquare_obj.addEventListener('mouseover', selected_colour, false);
godwardSquare_obj.addEventListener('mouseout', unselected_colour, false);
compSci_obj.addEventListener('mouseover', selected_colour, false);
compSci_obj.addEventListener('mouseout', unselected_colour, false);
itl_obj.addEventListener('mouseover', selected_colour, false);
itl_obj.addEventListener('mouseout', unselected_colour, false);
engineering_obj.addEventListener('mouseover', selected_colour, false);
engineering_obj.addEventListener('mouseout', unselected_colour, false);
peoplePalace_obj.addEventListener('mouseover', selected_colour, false);
peoplePalace_obj.addEventListener('mouseout', unselected_colour, false);
<svg width="1640" height="480" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - https://github.com/SVG-Edit/svgedit-->
<g class="layer">
<title>map</title>
<path d="m38,86.66667l0,94l64.66666,0l0.00001,-28l8.66666,0l0,27.33333l35.33334,0l-11.33334,-20l-12.66666,0l-0.00001,-8c8,0 12.66667,0 12.66667,0c0,0 -0.66667,-65.33333 0,-65.33333c0.66667,0 -89.33333,0 -97.33333,0z"
fill="rgb(94,43,126)" id="computer_science" stroke="#000000" stroke-width="5"/>
<rect fill="#10a3a3" height="447.44527" id="bandcroft_road" stroke="#10a3a3" stroke-width="5" width="35.76642" x="308.90512" y="-24.52553"/>
<rect fill="#10a3a3" height="54.74453" id="mile_end_road" stroke="#10a3a3" stroke-width="5" width="647.44528" x="-1.31387" y="425.10952"/>
<path d="m239.41174,257.50001l-133.52938,-0.14706l-0.00001,-69.85294l50.7353,-0.00001l-16.17647,-31.61765l58.82353,0l0,30.14706l39.70588,0l0.44115,71.4706z"
fill="#1bd1a6" id="godward_sqaure" stroke="#1bd1a6" stroke-width="5"/>
<rect fill="rgb(94,43,126)" height="100.5" id="itl" stroke="#000000" stroke-width="5" width="65" x="37" y="192"/>
<path d="m174.99947,274.5c-0.33149,41.16667 0.33149,82.83333 0,124l290.39161,0l0,-11.5l69.138332,0l0,-37l-68.641082,0l0,-142.5l-101.93541,0l0,167.5l-73.09515,0l0,-101l-115.8583,0.5z"
fill="rgb(94,43,126)" id="engineering" stroke="#000000" stroke-width="5"/>
<path d="m534.99996,206.029419l70.147082,-0.147072c0,0 0.441155,35.441191 -0.294139,34.705896c-0.735294,-0.735294 33.088235,0.000001 32.64708,-0.147072c-0.441155,-0.147073 0.441156,39.852955 0,39.705882c-0.441155,-0.147073 -18.676491,0.147074 -19.117647,0c-0.441156,-0.147073 0.441155,116.323546 0,116.176471c-0.441155,-0.147076 -82.647081,0.882369 -83.088235,0.735294c-0.441154,-0.147076 -0.294141,-191.764693 -0.294141,-191.029399z"
fill="rgb(94,43,126)" id="people_palace" stroke="#000000" stroke-width="5"/>
</g>
</svg>