首页 > 解决方案 > 图形编辑器 Javascript - 观察者设计模式

问题描述

我正在使用 two.js(SVG 画布)开发一个图形编辑器。在这个应用程序中,我需要拖动节点(圆圈)。该节点有一个形状(圆形)和一个标签。节点通过线连接到其他节点,每条线都有自己的标签。

移动节点时的图形编辑器

这个想法是当我拖动节点(圆圈)时,我会随着它的标签移动,并相应地更新线条,并相应地更新标签角度和位置。我需要知道如何使用事件来使用最佳实践来编写我的代码,比如观察者设计模式。

我的意思是当我移动节点(圆圈)时,它会通知链接线它们应该更新。现在我只是将行的更新放在移动节点函数中。这是代码:

    function mousedown(e) { 
     document.getElementById('log1').textContent = 'offsetY:' + e.offsetY + ' - clientY:' + e.clientY;
     if (e.clientY < 25) return; // menu

     mouse.current.set(e.clientX, e.clientY);
     mouse.previous.copy(mouse.current);

     move.start.set(e.clientX, e.clientY);

     window.addEventListener('mousemove', mousemove, false);
     window.addEventListener('mouseup', mouseup, false);

     realMousePos = mouse.current.clone().subSelf(two.scene.translation).divideScalar(two.scene.scale);
}


    function mousemove(e) {
    mouse.current.set(e.clientX, e.clientY);
    if(!isDragging){
        isDragging = true;
    }

    var dx = mouse.current.x - mouse.previous.x;
    var dy = mouse.current.y - mouse.previous.y;

    // To Pan
    if (State !== 'MOVE'){
        zui.translateSurface(dx, dy);
    } else {
        // Move Selected Nodes
        Move_SelectedNodes(dx, dy); //========> (see below)
    }

    mouse.previous.copy(mouse.current);
}

更新 node_label 和链接线

function Move_SelectedNodes(dx, dy){
    var zoomScale = two.scene.scale;
    var rdx = dx/zoomScale;
    var rdy = dy/zoomScale; 

    var dep = {x: rdx, y:rdy};//dep: deplacement !!!

    for(let i = 0; i < selectedNodes.length; i++){
         var node = selectedNodes[i];
         var node_circle = node.circle;
         var node_label = node.label;

         node_circle.translation.addSelf(dep);
         node_label.translation.addSelf(dep);

         //Move line end
         for (iBr = 0; iBr < node.branches.length; iBr++){
         var ligne = node.branches[iBr].ligne;

              if (ligne.vertices[0].node_id == node_circle.node_id) {
                   ligne.vertices[0].addSelf(dep);
              } else if (ligne.vertices[1].node_id == node_circle.node_id){             
                   ligne.vertices[1].addSelf(dep);
              }

              //Move line label
              var edgeLabel = node.branches[iBr].label;
              var labelX = (ligne.vertices[0].x + ligne.vertices[1].x)/2;
              var labelY = (ligne.vertices[0].y + ligne.vertices[1].y)/2;       
              edgeLabel.translation.set(labelX, labelY);
              edgeLabel.rotation = angle(ligne.vertices[0], ligne.vertices[1]);         
          }
      }

      two.update();
 }

这是 JSFiddle https://jsfiddle.net/hichem147/fdzn1u0x/中的整个示例 使用它:

(1) create nodes by adding nodes by clicking first [(+) Nodes]
(2) click on the canvas where you want to add a node
(3) add branches (lines) by clicking [Branche]
(4) click on the nodes you want to link with a line
(5) To move nodes you click on [select] then
(6) select one node or many using [ctrl]
(7) click [Move]
(8) Move the selected nodes
(9) to end click [Pan/Zoom] or [Select] button

标签: javascripteventscanvasgraphtwo.js

解决方案


最后,我看到了这篇关于使用 raphaelJS 开发类似我开发的东西的教程,其中包含矩形和应该随矩形移动的文本。并且作者使用的方法与我最初使用的方法相同。看来,没有必要把事情复杂化。只是把事情做好。

http://thewayofcoding.com/2016/09/using-raphael-the-javascript-graphics-library/


推荐阅读