在圆和具有svg和d3的线之间的过渡 [英] Transition between a circle and a line with svg and d3

查看:136
本文介绍了在圆和具有svg和d3的线之间的过渡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

JS小提琴



我是试图弄清楚如何通过在顶部剪切来展开/解开一个圆圈,然后它会动画到一条线。



通过使用16点(和第17关闭它,因为如果我使用一个闭合插值,过渡会看起来很奇怪)



动画?只是调整x和y点?,另一个插值?)你可以在圆和线之间一次转换一个点?



圆点: / p>

  //我们行的数据
var circleData = [{x:150,y:20 },
{x:165.30,y:23.04},
{x:178.28,y:31.71},
{x:186.95, y:44.69},
{x:190,y:60},
{x:186.95,y:75.30} :178.28,y:88.28},
{x:165.30,y:96.95},
{x:150,y:100},
{x:134.69,y:96.95},
{x:121.71,y:88.28},
{x:113.04,y:75.30}
{x:110,y:60.00},
{x:113.04,y:44.69},
{x:121.71, :31.71},
{x:134.69,y:23.04},
{x:150,y:20}

行点:

  var lineData = [{x:10,y:200},
{x:20,y:200},
{x :30,y:200},
{x:40,y:200},
{x:50,y:200},
{x:60,y:200},
{x:70,y:200},
{x:80,y:200}
{x:90,y:200},
{x:100,y:200},
{x:110,y :200},
{x:120,y:200},
{x:130,y:200},
{x:140 ,y:200},
{x:150,y:200},
{x:160, x:170,y:200}];


解决方案

当我尝试Duopixel的演示时,我注意到的第一件事是圆似乎收缩到适合的行。因此,我决定使线的长度与圆相同。此外,为了具有均匀分布,我写了两个函数来创建线和圆数据数组:

  var numberOfPoints = 30; 
var radius = 60
var margin = {top:20,left:20}
var lineLength = 2 * radius * Math.PI

var circleData = $ .map(array(numberOfPoints),function(d,i){
var imag = margin.left + lineLength / 2 + radius * Math.sin(2 * i * Math.PI /(numberOfPoints - 1))
var real = margin.top + radius - radius * Math.cos(2 * i * Math.PI /(numberOfPoints - 1))
return {x:imag,y:real}
})

var lineData = $ .map(array(numberOfPoints),function(d,i){
var y = margin.top + 2 * radius;
var x = margin.left + i * lineLength /(numberOfPoints - 1)
return {x:x,y:y}
})reverse()

那么,现在,我们可以应用什么效果?我将用最简单的一个:一个过渡映射圆的每个点到它的点上的线。

  var circle = svgContainer.append(g)
.append(path)
.data([circleData])
.attr(d,lineFunction)
.attr(class,circle)
.on(click,transitionToLine)

function transitionToLine(){
circle.data([lineData])
.transition()
.duration(1000)
。 )
.attr('d',lineFunction)
circle.on(click,transitionToCircle)
}
function transitionToCircle(){
circle.data [circleData])
.transition()
.duration(1000)
.ease(linear)
.attr('d',lineFunction)
circle .on(click,transitionToLine)
}

这里是jsFiddle ,你只需要点击节点就可以看到动画。


$ b $一个重要的事情要注意的是,过渡需要相同的时间为每个点,而在现实中,你想要的点到达中间附近的点之后到达。你可以使用的技巧是使动画的持续时间与从源点到目标点的距离成正比,但我不知道如何使用它与线,因为你传递整个数组,所以你不能改变持续时间为特定点。


JS Fiddle

I am trying to figure out how to "unfurl"/"unravel" a circle by "snipping" it at the top, and then it would animate to a line.

I have made a circle by using 16 points (and a 17th to close it since if I used a closed interpolation, the transition would look weird)

How (would it be via an animation?, just adjusting the x and y points?, another interpolation?) can you transition between the circle and the line one point at a time?

Circle points:

//The data for our line
var circleData = [ { "x": 150 , "y": 20   },
                 { "x": 165.30, "y": 23.04},
                 { "x": 178.28, "y": 31.71},
                 { "x": 186.95, "y": 44.69},
                 { "x": 190   , "y": 60   },
                 { "x": 186.95, "y": 75.30},
                 { "x": 178.28, "y": 88.28},
                 { "x": 165.30, "y": 96.95},
                 { "x": 150   , "y": 100   },
                 { "x": 134.69, "y": 96.95},
                 { "x": 121.71, "y": 88.28},
                 { "x": 113.04, "y": 75.30},
                 { "x": 110   , "y": 60.00},
                 { "x": 113.04, "y": 44.69},
                 { "x": 121.71, "y": 31.71},
                 { "x": 134.69, "y": 23.04},
                 { "x": 150   , "y": 20   }   ];

Line Points:

var lineData = [ { "x": 10    , "y": 200   },
                 { "x": 20    , "y": 200   },
                 { "x": 30    , "y": 200   },
                 { "x": 40    , "y": 200   },
                 { "x": 50    , "y": 200   },
                 { "x": 60    , "y": 200   },
                 { "x": 70    , "y": 200   },
                 { "x": 80    , "y": 200   },
                 { "x": 90    , "y": 200   },
                 { "x": 100   , "y": 200   },
                 { "x": 110   , "y": 200   },
                 { "x": 120   , "y": 200   },
                 { "x": 130   , "y": 200   },
                 { "x": 140   , "y": 200   },
                 { "x": 150   , "y": 200   },
                 { "x": 160   , "y": 200   },
                 { "x": 170   , "y": 200   }   ];

解决方案

The first thing that I noticed when trying Duopixel's demo was that the circle seemed to shrink to fit on the line. Thus I decided to make the line the same length as the circle. Moreover to have a uniform distribution I wrote two functions to create the line and circle data arrays:

var numberOfPoints = 30;
var radius = 60
var margin = {top: 20,left: 20}
var lineLength = 2 * radius * Math.PI

var circleData = $.map(Array(numberOfPoints), function (d, i) {
    var imag = margin.left + lineLength / 2 + radius * Math.sin(2 * i * Math.PI / (numberOfPoints - 1))
    var real = margin.top + radius - radius * Math.cos(2 * i * Math.PI / (numberOfPoints - 1))
    return {x: imag, y: real}
})

var lineData = $.map(Array(numberOfPoints), function (d, i) {
    var y = margin.top + 2 * radius;
    var x = margin.left + i * lineLength / (numberOfPoints - 1)
    return { x: x, y: y}
}).reverse()

So, now, what effect can we apply? I will go with the easiest one: a transition mapping each point of the circle to its point on the line.

var circle = svgContainer.append("g")
    .append("path")
    .data([circleData])
    .attr("d", lineFunction)
    .attr("class", "circle")
    .on("click", transitionToLine)

function transitionToLine() {
    circle.data([lineData])
        .transition()
        .duration(1000)
        .ease("linear")
        .attr('d', lineFunction)
    circle.on("click", transitionToCircle)
}
function transitionToCircle() {
    circle.data([circleData])
        .transition()
        .duration(1000)
        .ease("linear")
        .attr('d', lineFunction)
    circle.on("click", transitionToLine)
}

Here is the jsFiddle, you just have to click on the node to see the animation.

One important thing to notice is that the transition takes the same time for each point whereas in reality you would like the points in the end to arrive after the points near the middle. The trick you can use is to make the duration of the animation be proportional to the distance from the source point to the destination one but I don't see how to use it with lines as you pass the whole array so you cannot change the duration for a specific point.

这篇关于在圆和具有svg和d3的线之间的过渡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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