作者热门文章
- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试根据鼠标的位置在 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);
如果您需要从屏幕空间转换到元素的本地转换,请使用 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/
我是一名优秀的程序员,十分优秀!