D3.js 使用进度条控制动画

D3.js 使用进度条控制动画,d3.js,D3.js,我正在使用这些库 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script> <script src="https://d3js.org/d3-selection-multi.v1.min.js"></script> 对于每个元素,我在指定起点(.begin)和终点(.destiny),以及延迟(.del

我正在使用这些库

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script>
对于每个元素,我在指定起点(
.begin
)和终点(
.destiny
),以及延迟(
.delay
)的
json
中定义其动画属性,然后根据每个元素的这些属性定义生成转换。此json的一个示例如下:

circleValues={
"delay":4000,
"duration":3000,
"begin": {
  "cx": 250,
  "r":20,
  "fill": "blue"
},
"destiny": {
  "cx": 0,
  "fill": "orane"
 }
}
因此,对于
,我将生成一个动画,该动画将从以下属性开始:

//circleValues.begin
"begin": {
  "cx": 250,
  "r":20,
  "fill": "blue"
}
//circleValues.destiny
"destiny": {
  "cx": 0,
  "fill": "orange"
}
将生成一个转换,最终将以以下属性结束:

//circleValues.begin
"begin": {
  "cx": 250,
  "r":20,
  "fill": "blue"
}
//circleValues.destiny
"destiny": {
  "cx": 0,
  "fill": "orange"
}
整个动画将在15秒内完成,对于圆,根据我定义的属性,这意味着它将在4秒内开始,因为它将有4000(circleValues.delay)的
延迟,并将持续(
circleValues.duration
)秒

然后我有一个名为
initAnimation()
的函数,其中我为样式中的每个元素执行此转换:

function initAnimation(percentage){
  //circle properties  
  circle.styles(circleValues.begin)
    .transition()
    .delay(circleValues.delay)
    .duration(circleValues.duration)
    .ease(d3.easeLinear())
    .styles(circleValues.destiny)
}
我希望使用进度条控制动画。在本例中,我使用以下方式定义进度条:

//15 seconds,  min value is 0 seconds, max value is 15 seconds, step=1
<input id="progressbar" type="range" min="0" max="15" step="1" value="0" oninput="setPercentValue(+event.target.value)">
我通过调用这两行代码来执行我的所有代码

initAnimation(0);
moveProgressBar();
问题是,我不知道如何使它根据我的进度条选择的时间,它对应于动画中每个元素的当前时刻。我希望根据移动进度条时选择的值,它与我为每个元素定义的行为相对应,即使我
暂停
恢复
动画。这超出了我在
d3.js
的知识范围

我怎么做

d3.选择(#可视化”).append('svg');
var vis=d3。选择(“svg”).attr(“宽度”,800)。attr(“高度”,150)。样式(“边框”,“1px实心红色”);
var持续时间=15000//持续15秒的动画
var second=0;//进度现值
变量间隔;//setInterval实例
函数暂停(){
间隔时间;
}
函数播放(){
moveProgressBar();
}
函数moveProgressBar(){
间隔=设置间隔(()=>{
第二++;
document.getElementById(“progressbar”).value=second;
如果(秒=15){
间隔时间;
}
},1000)
}
函数setPercentValue(百分比){
秒=百分比;
矩形中断();
圈。中断();
初始动画(百分比);
}
变量值={
“延迟”:2000年,
“持续时间”:5000,
“开始”:{
“x”:0,
“y”:0,
“高度”:70,
“宽度”:100,
“不透明度”:1,
“填充”:“红色”
},
“命运”:{
“x”:250,
“y”:1,
“高度”:100,
“宽度”:120,
“不透明度”:0.8,
“填充”:“绿色”
}
}
var rectangle=vis.append(“rect”)
变量循环=相对附加(“循环”);
var循环值={
“延迟”:4000,
“持续时间”:3000,
“开始”:{
“cx”:250,
“r”:20,
“填充”:“蓝色”
},
“命运”:{
“cx”:0,
“填充”:“橙色”
}
}
函数初始化动画(百分比){
//矩形属性
矩形.样式(rectValues.begin)
.transition()
.delay(rectValues.delay)
.duration(rectValues.duration)
.ease(t=>d3.easeLinear(百分比+t*(1-百分比)))
.style(rectValues.destiny)
//圆属性
circle.style(circleValues.begin)
.transition()
.延迟(循环值延迟)
.持续时间(circleValues.持续时间)
.ease(t=>d3.easeLinear(百分比+t*(1-百分比)))
.styles(circleValues.destiny)
}
初始化动画(0);
moveProgressBar()

暂停
玩

正如您在文章中指定的,动画由延迟和过渡组成。
如果希望在某个固定时间T(由progressbar值确定)显示此类动画的结果,则需要评估以下条件:

  • 如果T小于延迟,那么您仍在等待转换开始。正在设置动画的形状仍将所有属性设置为
    begin
    值,只需缩短延迟
  • 如果T大于延迟,但小于延迟+过渡持续时间,则形状已处于过渡阶段。在这种情况下,您需要确定在时间T的转换距离,并插入属性值(因此这些值将介于
    开始
    命运
    )之间),同时转换持续时间也需要缩短
  • 如果T大于延迟,则转换已经完成。在这种情况下,属性值将设置为
    destiny
  • 此逻辑封装在下面的函数
    interpolateValuesAtTime
    中。此函数除了计算新的
    延迟
    持续时间
    开始
    命运
    值外,还创建了一个新的缓和函数,该函数计算从时间T开始缓和应如何继续(关于修改后的缓和函数如何工作的详细信息将在本章中详细介绍)


    您可以在下面的代码段中测试它。

    以下是有关其功能的几个注意事项:
    • 单击进度条后,动画将在给定时间显示(动画将暂停,按play开始播放)
    • 此外,按“播放”后,动画从与进度条对应的时间开始(由于进度条只计算整秒,这意味着如果暂停并播放动画,它可能会向后跳一点)
    const progressbar=document.getElementById('progressbar');
    d3.选择(“#可视化”).append('svg');
    常量vis=d3。选择(“svg”).attr(“宽度”,800)。attr(“高度”,150)。样式(“边框”,“1px实心红色”);
    const rectangle=vis.append(“rect”)
    常数