gpt4 book ai didi

javascript - 如何将鼠标移动距离转换为 SVG 坐标空间?

转载 作者:行者123 更新时间:2023-12-04 22:54:45 30 4
gpt4 key购买 nike

我在这里有一个 CSS4 颜色关键字在 HSL 空间中分布的 SVG 可视化:https://meyerweb.com/eric/css/colors/hsl-dist.html

我最近通过鼠标滚轮添加了缩放,并通过鼠标咔嗒声和拖动进行平移。我可以使用 matrixTransform 将一个点从屏幕空间转换为 SVG 坐标空间, .getScreenCTM() , 和 .inverse()感谢我在网上找到的示例代码,但是如何在拖动过程中转换鼠标移动?现在我只是转移 viewBox event 中的 X 和 Y 值坐标,这意味着放大时图像拖动比鼠标移动快。

例如,假设我放大了图像并拖动以平移,我将鼠标向左并略微向下猛拉。 event.movementX返回 -37event.movementY返回 6 .如何确定 SVG 坐标中的距离,以便 viewBox坐标是否正确移动?

( 注意: 我知道有这类库,但我有意编写 Vanilla JS 代码以了解有关 SVG 和 JS 的更多信息。所以请不要发布“大声笑,只需使用库 X”就可以了。谢谢!)

编辑添加:我被要求发布代码。发布整个 JS 似乎过长,但这是在 mousemove 上触发的函数事件:

function dragger(event) {
var target = document.getElementById('color-wheel');
var coords = parseViewBox(target);
coords.x -= event.movementX;
coords.y -= event.movementY;
changeViewBox(target,coords);
}

如果需要更多,请在链接页面上查看源代码;所有的 JS 都在页面的顶部。除了只包含可视化的所有 HSL 值和颜色名称的文件之外,没有什么是外部的。

最佳答案

我的建议:
不用担心 movementX/Y事件的属性。
只需担心鼠标从哪里开始以及现在在哪里。

(这有一个额外的好处,即使你错过了一些事件,你也能得到相同的结果:可能是因为鼠标移出了窗口,或者可能是因为你想对事件进行分组,所以你只在每个动画帧运行一次代码。)

对于鼠标开始的位置,您可以在 mousedown 事件上进行测量。
使用您使用的方法将其转换为 SVG 坐标中的位置,
.getScreenCTM().inverse().matrixTransform() .
在此转换之后,您不必关心屏幕上的这个点在哪里。您只关心它在图片中的位置。这就是图片中的一点,您总是要移动到鼠标下方。

在 mousemove 事件上,您使用相同的转换方法来找出鼠标当前在当前 SVG 坐标系中的位置。然后,您可以计算出距离您想要在鼠标下方的点(同样,在 SVG 坐标中)有多远。这就是您用于转换图形的数量。我已经按照您的示例进行了转换,并通过移动 xy viewBox 的一部分:

function move(e) {
var targetPoint = svgCoords(event, svg);
shiftViewBox(anchorPoint.x - targetPoint.x,
anchorPoint.y - targetPoint.y);
}

您也可以使用 transform 移动图形。在 SVG 中的组( <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>

关于javascript - 如何将鼠标移动距离转换为 SVG 坐标空间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55564432/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com