动画化SVG分组的DOM运动 [英] Animate DOM movement of SVG groupings

查看:106
本文介绍了动画化SVG分组的DOM运动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个d3布局,其中包含10个节点,结构如下:

I have a d3 layout with 10 nodes structured as follows...

<body>
    <svg id="mainSvg" style="position: relative" width="1200" height = "1200">
        <g>
            <svg width = "800" height="800>
                <g class="nodeGroupSVG" transform=translate(someXValue,someYValue) scale(someScaleValue)
                    <g class="node" transform=translate(someXValue,someYValue)>
                        <circle>
                        <text>
                    </g>
                    //9 more of these individual node groupings
                </g>
            </svg>
        </g>
        <g class="gToMoveTo">
            //starts off empty
        </g>
    <svg>
</body> 

我想将节点移动到新容器,这可以在jquery中使用...轻松实现.

I want to move the nodes to a new container, which can easily be achieved in jquery using...

$('.gToMoveTo').append($('.node'));

但是,当涉及到过渡到新的DOM位置的动画时,我很难从以下SO答案中实现该想法:

But when it comes to animating that transition to a new DOM position, I'm having troubles implementing the idea from the SO answer here: JQuery - animate moving DOM element to new parent?

使用该函数对我来说与简单的jquery行具有完全相同的效果(加上我认为是由于调用了动画函数而导致的更新中的较小延迟-即使没有逐步过渡到新位置)

Using that function has exactly the same effect for me as the simple jquery line (plus a minor delay in updating which I'm assuming is due to the animation function being called - even though there's no gradual transition to the new position).

要问是否有人知道我列出的功能不适合动画SVG组元素过渡的充分原因,这是一个很长的路要走?如果是这样,是否有任何方法可以将其修改为与SVG结合使用.

All that's a long way of asking whether anyone knows of a good reason why the function I've listed would not be suited to animating the transition of SVG group elements? And if so, whether there's any ideas of a way to adapt it for use with SVG.

推荐答案

这是一种常用的算法:

代码如下:

<html>
<head>
<script src="d3.v3.min.js"></script>
<script src="jquery-2.1.0.min.js"></script>

<style>
.svg_contariner {
    background-color:#CCCCCC;
}
#origin {
    width:200px;
    height:200px;
    margin:5px; 
}
#target {
    width:200px;
    height:200px;
    margin:5px; 
}
circle {
    fill:#e72;
}
text {
    font-family:Tahoma, Geneva, sans-serif;
    font-size:10px;
}
.clone {
    margin:0;
    padding:0;
    width:20px;
    height:20px;
    position:absolute;
}
</style>
</head>
<body>
<div id="data"></div>

<script>
var data_text = "", data = [], r = 10;
/* --- add some random data --- */
for (i = 0; i < 10; i++) {
    data.push( {
        "x": Math.round(Math.random() * 180)+10,
        "y": Math.round(Math.random() * 180)+10,
        "text": i
    });  
    data_text += "x:" + data[i].x + " y:" + data[i].y + " text:" + data[i].text + "<br>";
}
/* --- create 2 containers --- */
var svgContainerTar = d3.select("body").append("svg")
        .attr("id","target")
        .attr("class","svg_contariner");

var svgContainerOrg = d3.select("body").append("svg")
        .attr("id","origin")
        .attr("class","svg_contariner");

/* --- add g node to origin --- */
var ele = svgContainerOrg.selectAll("g")
        .data(data)
        .enter()
        .append("g")
        .attr("class", "node")
        .on("click", function (d) {     /* --- bind onClick to every g --- */
            d3.select(this).remove();   /* --- remove origin element --- */
            moveCircle(d);              /* --- create, animate ghost --- */
        });

/* --- add circle to g --- */       
var circles = ele.append("circle")
             .attr("cx", function (d) { return d.x; })
             .attr("cy", function (d) { return d.y; })
             .attr("r", r+"px");
/* --- add text to g --- */
var labels = ele.append("text")
                .attr("dx", function(d) {return d.x - 2})
                .attr("dy", function(d) {return d.y + 3})
                .text(function (d) {return d.text});

function moveCircle(d) {
    ori_x = d.x;
    ori_y = d.y;
    ori_tex = d.text;
    ori_pos = $("#origin").position();
    tar_pos = $("#target").position();
    /* --- create ghost using jQuery --- */
    $("body").append("<div id='ghost' class='clone' style='left:"+(ori_x - r/2+ori_pos.left)+";top:"+(ori_y - r/2+ori_pos.top)+"';>"+
                        "<svg width='20px' height='20px'>"+
                            "<circle cx='"+r+"' cy='"+r+"' r='"+r+"px'></circle>"+
                            "<text x='"+(r - 2)+"' y='"+(r+3)+"'>"+ori_tex+"</text>"+
                        "</svg></div>");
    /* --- animate ghost --- */
    $("#ghost").animate({
        "left" : tar_pos.left + ori_x,
        "top" : tar_pos.top + ori_y
        },100,"swing",
            function () {
                time = setTimeout(function () {             /* --- when animation ends create target element --- */
                    var new_node = d3.select("#target")
                                    .append ("g")
                                        .attr("class", "node");
                        new_node.append("circle")
                                .attr("cx", ori_x+r/2+"px")
                                .attr("cy", ori_y+r/2+"px")
                                .attr("r", r+"px")
                        new_node.append("text")
                                .attr("dx", ori_x+r/2-2)
                                .attr("dy", ori_y+r/2+3)
                                .text(ori_tex);
                    $("#ghost").remove();                   /* --- remove ghost --- */
                },100)
            });
}

</script>

</body></html>

希望获得帮助

这篇关于动画化SVG分组的DOM运动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆