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”)
常数