3 回答

TA贡献1851条经验 获得超5个赞
我的建议:不用担心事件的movementX/Y属性。只需担心鼠标在哪里开始以及现在在哪里。
(这还有一个额外的好处,即使您错过了一些事件,您也可以获得相同的结果:可能是因为鼠标移出了窗口,或者可能是因为您想对事件进行分组,所以每个动画帧只运行一次代码。)
对于鼠标的起始位置,您可以在mousedown事件上对其进行测量。使用.getScreenCTM().inverse()和所使用的方法,将其转换为SVG坐标中的位置.matrixTransform()。进行此转换后,您无需担心此点在屏幕上的什么位置。您只关心它在图片中的位置。这就是图片中您始终要移动到鼠标下方的要点。
在mousemove事件上,您使用相同的转换方法来找出鼠标当前在当前SVG坐标系内的位置。然后,您可以算出距离鼠标下方想要的点(同样,在SVG坐标中)有多远。那就是您用来变换图形的数量。我遵循了您的示例,并通过移动x和的y一部分来进行转换viewBox:
function move(e) {
var targetPoint = svgCoords(event, svg);
shiftViewBox(anchorPoint.x - targetPoint.x,
anchorPoint.y - targetPoint.y);
}
您也可以在SVG中transform的组(<g>元素)上使用来移动图形。只要确保将相同的组元素用于getScreenCTM()从clientX/Y事件坐标转换的调用即可。
拖动演示的完整演示。我已经跳过了所有绘图代码和缩放效果。但是缩放应该仍然有效,因为您要保存在全局值中的唯一位置已经转换为SVG坐标。
var svg = document.querySelector("svg");
var anchorPoint;
function shiftViewBox(deltaX, deltaY) {
svg.viewBox.baseVal.x += deltaX;
svg.viewBox.baseVal.y += deltaY;
}
function svgCoords(event,elem) {
var ctm = elem.getScreenCTM();
var pt = svg.createSVGPoint();
// Note: rest of method could work with another element,
// if you don't want to listen to drags on the entire svg.
// But createSVGPoint only exists on <svg> elements.
pt.x = event.clientX;
pt.y = event.clientY;
return pt.matrixTransform(ctm.inverse());
}
svg.addEventListener("mousedown", function(e) {
anchorPoint = svgCoords(event, svg);
window.addEventListener("mousemove", move);
window.addEventListener("mouseup", cancelMove);
});
function cancelMove(e) {
window.removeEventListener("mousemove", move);
window.removeEventListener("mouseup", cancelMove);
anchorPoint = undefined;
}
function move(e) {
var targetPoint = svgCoords(event, svg);
shiftViewBox(anchorPoint.x - targetPoint.x,
anchorPoint.y - targetPoint.y);
}
body {
display: grid;
margin: 0;
min-height: 100vh;
}
svg {
margin: auto;
width: 70vmin;
height: 70vmin;
border: thin solid gray;
cursor: move;
}
<svg viewBox="-40 -40 80 80">
<polygon fill="skyBlue"
points="0 -40, 40 0, 0 40 -40 0" />
</svg>
添加回答
举报