【问题标题】:Javascript SVG draggingJavascript SVG拖动
【发布时间】:2011-08-17 15:26:06
【问题描述】:

原问题在http://stackoverflow.com/questions/7055607/trying-to-rotate-and-transform-svg-path-do-i-need-trigonometry-calculations

...我试图弄清楚如何拖动另一个电阻点: http://www.3lectronics.com/electronics-layout/resistor.svg

SVG 事件、父母、孩子和其他家庭需要时间让我了解。

如果有人想帮忙...

【问题讨论】:

  • 或者这个问题可以作为对原始问题的评论添加。

标签: javascript svg dom-events coordinate-transformation


【解决方案1】:

我想我有类似您所要求的内容:http://dl.dropbox.com/u/169269/resistor2.svg 无论如何,它应该能让你开始。

现在要复杂得多,但应该可以更轻松地添加更多元素。我怀疑一定有更简单的方法,但这是一个有趣的挑战。它现在使用矩阵变换,我认为这是必要的(所以如果你还不知道它们,你需要学习它们),因为你需要跟踪以前的变换。我建议看http://www.w3.org/TR/SVG/coords.html#NestedTransformations

新的拖动功能如下所示:

function drag(evt)
{
    if(selected_element != 0)
    {
        dx = rotate_x - evt.pageX;
        dy = rotate_y - evt.pageY;

        new_size  = Math.sqrt(dx*dx + dy*dy) / element_size;
        new_angle = Math.PI/2 + Math.atan2(dy, dx);
        delta_size  = new_size / current_size;
        delta_angle = new_angle - current_angle;
        current_size  = new_size;
        current_angle = new_angle;

        new_matrix = new Array(6);

        // Scale
        for (i=0; i<6; i++){
            current_matrix[i] = current_matrix[i] * delta_size;
        }
        current_matrix[4] = current_matrix[4] + (-delta_size) * rotate_x;
        current_matrix[5] = current_matrix[5] + (-delta_size) * rotate_y;


        for (i=0; i<6; i++){new_matrix[i] = current_matrix[i]; }

        // Rotate around (0,0)
        cos_theta = Math.cos(delta_angle);
        sin_theta = Math.sin(delta_angle);
        new_matrix[0] = cos_theta*current_matrix[0] - sin_theta*current_matrix[1];
        new_matrix[1] = sin_theta*current_matrix[0] + cos_theta*current_matrix[1];
        new_matrix[2] = cos_theta*current_matrix[2] - sin_theta*current_matrix[3];
        new_matrix[3] = sin_theta*current_matrix[2] + cos_theta*current_matrix[3];
        new_matrix[4] = cos_theta*current_matrix[4] - sin_theta*current_matrix[5];
        new_matrix[5] = sin_theta*current_matrix[4] + cos_theta*current_matrix[5];

        // Transform back to original point
        new_matrix[4] += rotate_x;
        new_matrix[5] += rotate_y;

        transform = "matrix(" + new_matrix.join(' ') + ")" ;
        selected_element.setAttributeNS(null, "transform", transform);
        current_matrix = new_matrix;
    }
}

它与以前类似,只是现在它测量自上次拖动事件以来角度和距离的差异。

电阻组如下所示:

  <g class="resistor" transform="matrix(1 0 0 1 0 0)" onmouseup="deselectElement()" size="200">
    <line x1="200" y1="200" x2="200" y2="400" stroke="blue" stroke-width="5" pointer-events="none"/>
    <rect x="180" y="250" width="40" height="100" stroke="blue" fill="white" stroke-width="5" pointer-events="none"/>
    <circle cx="200" cy="200" r="10" fill="blue" onmousedown="selectElement(evt, 200, 400)"/> 
    <circle cx="200" cy="400" r="10" fill="blue" onmousedown="selectElement(evt, 200, 200)"/> 
  </g>

需要注意的重要一点是,主组有一个 size 属性,它告诉函数电阻应该多长。这些圆圈具有 selectElement 函数并传递另一个圆圈的坐标以指示旋转和缩放应该围绕该点进行。我确信有更好的方法来做到这一点。

【讨论】:

  • 我也确信一切都有更好的方法,但你的努力让我对应该如何处理这个问题和其他类似问题有了新的想法。请记住,我只是从 JS 和 SVG 开始,实际示例对于我学习如何解决某些问题是非常宝贵的课程。
  • 顺便说一句,此代码仅适用于 Chrome(在我的 Linux Mint 上),我启动了 Chrome 的 JS 控制台,它给了我:“资源解释为文档,但使用 MIME 类型图像/svg+xml 传输。”。它也使自己的缩进。我将带有这些缩进的相同代码复制为电阻器3.svg,现在在 Opera 和 Midori 中运行(仍然不在 Firefox 中)?!一些愚蠢的浏览器规则! (3lectronics.com/electronics-layout/resistor3.svg)
  • 请不要为此烦恼,我有足够的人手练习,你帮了我一个大忙。我该如何报答你?如果你要去亚得里亚海沿岸,我很乐意让我的朋友在海滩附近(斯普利特克罗地亚附近)的一些公寓里给你住宿一段时间。如果您需要,也可以帮助您进行电子设计。不要犹豫。非常感谢!
  • 很高兴能为您提供帮助。它看起来像一个有趣的项目。混在一起很有趣。我想我可能有一段时间可以用更简单的方式来做这件事。我没有在 Chrome 之外测试它,不知道为什么它在 Firefox 上不起作用。我认为您不必担心“资源解释为文档,但使用 MIME 类型 image/svg+xml 传输。”。
  • 我访问了您的博客,我认为它非常有趣,设计乐观且美观。做得好。关于 Firefox 问题,我发现属性 tag: size= 对 SVG 无效。项目对我来说非常有趣,你可以在 (3lectronics.com/electronics-layout/Atarado-Draw1.html) 看到一些开始,我必须学习 SVG 以使其有意义。我也很想用原理图交互、自动布线、自动放置来升级它……但这需要一些时间。我很乐意尽我所能帮助你。保持健康。
猜你喜欢
  • 2011-12-08
  • 2014-03-22
  • 1970-01-01
  • 1970-01-01
  • 2014-06-25
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多