gpt4 book ai didi

javascript - 尽管有伪造的 getBoundingClientRect(),您如何将事件坐标转换为 SVG 坐标?

转载 作者:搜寻专家 更新时间:2023-11-01 04:54:26 27 4
gpt4 key购买 nike

我正在尝试根据鼠标的位置在 SVG 元素上动态绘制内容。不幸的是,我很难将鼠标坐标从 mousemove 事件转换到 SVG 元素的坐标空间。

这是我一直在测试的一个错误函数:

CylinderDemo.prototype.handleMouseMove = function(evt)
{
debugEvent = evt;

var bcr = evt.target.getBoundingClientRect();
var x2 = evt.clientX - bcr.left;
var y2 = evt.clientY - bcr.top;

console.log(evt.target);
//console.log(evt.clientY+" - "+evt.target.getBBox());

var d = this.pathForCylinder(this.x0, this.y0, x2, y2, 30);
this.cap.setAttributeNS(null, "d", d);
}

canvas.onmousemove = function(evt) {
self.handleMouseMove(evt);
}

问题是(至少在 Firefox 中)getBoundingClientRect() 没有给我 SVG 对象的边界。它为我提供了 SVG 对象内可绘制对象的边界。当您将鼠标悬停在 firebug 中的日志行上时,它会变得非常明显,并且会突出显示可绘制元素的微不足道的子矩形。这意味着我的坐标转换给出了有缺陷的结果。

我应该使用什么技术将事件坐标系转换为 SVG 容器的坐标系?

我只是拼凑起来的http://jsfiddle.net/7kvkq/来说明问题。

最佳答案

不要使用 getBoundingClientRect()。相反,使用 getScreenCTM() 将点从屏幕空间转换为全局 SVG 空间:

var pt = demo.createSVGPoint(); // demo is an SVGElement
demo.addEventListener('mousemove',function(evt) {
pt.x = evt.clientX;
pt.y = evt.clientY;
var svgGlobal = pt.matrixTransform(demo.getScreenCTM().inverse());
// svgGlobal.x and svgGlobal.y are now in SVG coordinates
},false);

固定演示:http://jsfiddle.net/7kvkq/3/

如果您需要从屏幕空间转换到元素的本地转换,请使用 getTransformToElement() 进一步转换点:

var elTransform = demo.getTransformToElement(someElement);
var elLocal = svgGlobal.matrixTransform(elTransform );

getTransformToElement() 演示:http://jsfiddle.net/7kvkq/4/

为了获得更好的性能,不要将点转换两次并创建一个中间点,而是将矩阵组合成一个并使用它来转换坐标:

var demo = document.querySelector('svg'),
pt = demo.createSVGPoint(),
g = demo.querySelector('#myGroup');

// Assumes that the group does not move with respect to the SVG;
// if so, re-calculate this as appropriate.
var groupXForm = demo.getTransformToElement(g);
demo.addEventListener('mousemove',function(evt) {
pt.x = evt.clientX;
pt.y = evt.clientY;
var xform = groupXForm.multiply(demo.getScreenCTM().inverse());
var localPoint = pt.matrixTransform(xform);
// localPoint.x/localPoint.y are the equivalent of your mouse position
},false);

您可以在我的网站上看到使用这些技术的演示:
http://phrogz.net/svg/drag_under_transformation.xhtml

关于javascript - 尽管有伪造的 getBoundingClientRect(),您如何将事件坐标转换为 SVG 坐标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20957627/

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