我正在开发一个PyQt应用程序,它有一个基于QWebKit的SVG查看器。最初,SVG文件由外部应用程序(LilyPond)生成,但我们希望使用JavaScript在查看器中编辑SVG。
基本上它工作得很好,但我们遇到一个奇怪的舍入/转换/光栅问题,我们不知道:拖动对象时,onmousemove
仅输出栅格化值clientX/clientY
或pageX/pageY
。也就是说,我们可以看到事件多次触发,并且(比方说)clientX
会产生一系列值,如100 100 100 100 101 101 101 101 102 102 102 102
等,重复次数取决于视图的缩放系数
我认为这些值不是屏幕像素,而是以SVG文档为单位的数字,这是我们问题的根源。
文件的svg
元素如下所示:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.2" width="210.00mm" height="297.00mm" viewBox="0 0 119.5016 169.0094">
(请记住,这是从外部程序生成的)。
我假设viewBox
属性用于确保SVG坐标与原始应用程序的坐标系一致(LilyPond在&#34;员工空间&#34;中思考,显然是{的翻译在SVG文件中{1}}与在LilyPond中翻译1个人员空间完全相同。如果我在LilyPond中更改&#34;全局人员大小&#34; 1
属性将得到不同的值。)
所以我基本上需要的是viewBox
(等等)给我浮点结果而不是舍入整数。
有没有办法让JavaScript做到这一点?
或者我是否必须进行一些计算 - 以某种方式将clientX
(等)坐标转换为屏幕像素,然后再转回(将缩放和/或硬件考虑在内)?
在尝试了解不同阶段的不同缩放选项时,我感到很茫然......
修改 这里还有一些代码...... 正如@ uli_1973所提到的,鼠标位置由clientX / -Y属性维持:
clientX
要将鼠标位置转换为SVG的坐标,我们使用以下代码行:
svgPoint.x = event.clientX;
svgPoint.y = event.clientY;
我想主要的问题是,我们能以某种方式获得更高的分辨率吗?目前,鼠标移动的最小可能差异转换为SVG坐标(mm)中的0.15。
EDIT2 整个文件可以在左看到 https://github.com/PeterBjuhr/frescobaldi/blob/svg-edit/frescobaldi_app/svgview/editsvg.js
可以在文件底部的三个事件处理程序中找到拖动的实现。
最初(svgPoint = svgPoint.matrixTransform(svg.getScreenCTM().inverse());
)调用构造函数onmousedown
(当前从第219行开始)。 DraggableObject(elem, event)
事件对象在第319行传递给onmousemove
方法
两者都使用文件顶部的函数updatePositions(e)
。这个功能是我们查明问题的地方。
当我们拨打mousePos()
或event.clientX
或screenX
时,我们会收到错误解决方案的输出。
有关我们所有观察和想法的更详细讨论可以在https://github.com/PeterBjuhr/frescobaldi/issues/21