【问题标题】:D3 JS - Group Containing a SVG Rectangle Won't Translate Smoothly on DragD3 JS - 包含 SVG 矩形的组在拖动时不会平滑平移
【发布时间】:2017-06-23 06:45:12
【问题描述】:

我使用 D3 拖动事件在 SVG 容器上创建了一个矩形。

我尝试通过在绘制矩形的父元素上应用 2D 变换(使用 translate(x,y))来实现移动矩形。

绘制矩形后,我得到包含矩形的容器的边界框值。然后我将 (x,y) 边界框坐标设置为 (0,0),从而将矩形移动到右上角的视口。然后我把它翻译回原来的位置。然后通过在拖动矩形时使用鼠标事件坐标更新它来再次应用翻译。

     d3.select('#rectangle').on('click', function(){ new Rectangle(); } );

function Rectangle(){

    var rectData = []; //holds the diagonal point 1 and 2 coordinates of the rectangle
    var rectContainer; // g element
    var shape = {}; //will hold the rectangle's d3 selections
    var start; //starting point
    var edge; //ending point
    var gData = {}; //holds translate values for g element

//    console.log(this);

    var rectangleDrag =  svgCanvas.call(d3.drag().on("start", initialPlod)
        .on('drag', secondaryPlod)
        .on('end', onStopDraw));

    //start rendering on drag start
    function initialPlod(){
        start = d3.mouse(this);
//      console.log(start);
        rectData = [{x:start[0], y:start[1]}, {x:start[0], y:start[1]}];
        rectContainer = svgCanvas.append("g");
        shape.rectEl = rectContainer.append('rect').attr('class', 'rectangle');
        renderRectangle();
    }

    //when continuing to drag from point 2
    function secondaryPlod(){
        edge = d3.mouse(this);
        rectData[1] = {x: edge[0], y: edge[1]};
        renderRectangle();
    }

    //on stop drawing bind a drag event
    function onStopDraw(){

        svgCanvas.call(d3.drag().on("start", null)
            .on('drag', null)
            .on('end', null));

        var bbox = shape.rectEl._groups[0][0].getBBox();
        console.log(this);
        console.log(bbox);

        //temporary variables that hold original position
        var rectCords = {
            x: bbox.x,
            y: bbox.y
        };

        //setting boundingbox to 0,0 coordinates
        bbox.x = 0;
        bbox.y = 0;

//      console.log(bbox);

        shape.rectEl.attr("x", bbox.x).attr("y", bbox.y);

        gData.x = rectCords.x;
        gData.y = rectCords.y;

        rectContainer.attr("transform", "translate(" + gData.x + "," + gData.y + ")");

        shape.rectEl.call(d3.drag().on("drag", dragRect));
    }

    //grab and drag rectangle
    function dragRect() {
        var move = d3.event;
        rectContainer.attr("transform", "translate(" + (gData.x += move.dx)  + "," + (gData.y += move.dy) + ")");
    }

    /**
     *
     * Method takes the x,y coordinates from rectData object array
     * which contains coordinates of point1 and point2
     * and calculates the the height and width
     *
     */
    function renderRectangle(){
        //rectangle attributes
        var xCoord = rectData[1].x - rectData[0].x > 0 ? rectData[0].x :  rectData[1].x;
        var yCoord = rectData[1].y - rectData[0].y > 0 ? rectData[0].y :  rectData[1].y;
        var width = Math.abs(rectData[1].x - rectData[0].x);
        var height = Math.abs(rectData[1].y - rectData[0].y);

        //render rectangle
        shape.rectEl.attr("x",xCoord)
            .attr("y", yCoord)
            .attr("width",width)
            .attr("height",height);
    }

}

矩形平移但不稳定。但是,如果我将相同的技术应用于 SVG 圆圈,它在鼠标拖动时就可以很好地转换。两种形状都可以在同一个视口上绘制。

这是fiddle

【问题讨论】:

    标签: javascript d3.js svg


    【解决方案1】:

    我设法找到了问题的原因。

    我已将拖动事件绑定到 g 元素内的矩形元素,这似乎在拖动矩形时导致了不稳定的平移。由于我在拖动矩形时正在翻译 g 元素,因此可能会导致问题。

    我将拖动事件绑定到矩形容器(g 元素)元素,它现在可以在拖动时平滑转换。

        //on stop drawing bind a drag event
        function onStopDraw(){
    
            svgCanvas.call(d3.drag().on("start", null)
                .on('drag', null)
                .on('end', null));
    
            var bbox = shape.rectEl._groups[0][0].getBBox();
            console.log(this);
            console.log(bbox);
    
            //temporary variables that hold original position
            var rectCords = {
                x: bbox.x,
                y: bbox.y
            };
    
            //setting boundingbox to 0,0 coordinates
            bbox.x = 0;
            bbox.y = 0;
    
    //      console.log(bbox);
    
            shape.rectEl.attr("x", bbox.x).attr("y", bbox.y);
    
            gData.x = rectCords.x;
            gData.y = rectCords.y;
    
            rectContainer.attr("transform", "translate(" + gData.x + "," + gData.y + ")");
    
    //bound the drag event to the entire g element of the rectangle
                rectContainer.call(d3.drag().on("drag", dragRect));
            }
    

    这是fiddle

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-26
      • 1970-01-01
      • 2019-06-15
      • 1970-01-01
      • 2012-09-22
      • 1970-01-01
      • 2015-01-23
      • 2022-01-16
      相关资源
      最近更新 更多