我有一个使用.transition()
进行动画处理的矩形,它需要5秒钟(.duration(5000)
)。我想知道是否有任何方法可以在这5秒内指定一个百分比,所以动画是从该百分比开始执行的。
例如,对于5秒的持续时间,如果我指定50%
的值,我希望动画从对应于2.5秒(5%的50%)的值开始。那可能吗?
这是我的代码:
d3.select("#visualization").append('svg');
var vis = d3.select("svg").attr("width", 800).attr("height", 614).style("border", "1px solid red");
var rectangle = vis.append("rect").attr("width", 100).attr("height", 70).attr("x", 0).attr("y", 50);
rectangle
.transition()
.duration(5000)
.attr("x", 250)
.attr("width", 100)
.attr("height", 100)
.attr("opacity", 0.5)
.attr("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="visualization"></div>
最佳答案
对于线性缓动,只需更改持续时间并传递自己的ease
函数即可,该函数很简单:
const percentage = 0.5;//here, a value between 0 and 1
selection.transition()
.duration(5000 * (1 - percentage))
.ease(t => percentage + t * (1 - percentage))
//etc...
如果您还有另一种放松,则将修改后的t
值传递给它。例如,使用d3.easeCubic
:.ease(t => d3.easeCubic(percentage + t * (1 - percentage)))
这里的逻辑很简单:正如API解释的那样,“对于过渡处于事件状态的每个帧,它使用介于0到1之间的缓和t值调用补间。因此,我们的函数仅使过渡从percentage
的缓和值开始,并且t
值(从0到1)用于指示必须添加的剩余量(1 - percentage
)的分数。当t = 1
时,整个表达式percentage + t * (1 - percentage)
等于1。这是演示。首先,您的常规过渡:
const vis = d3.select("body").append('svg').attr("width", 800).attr("height", 614).style("border", "1px solid red");
var rectangle = vis.append("rect").attr("width", 100).attr("height", 70).attr("x", 0).attr("y", 50);
rectangle
.transition()
.duration(5000)
.attr("x", 250)
.attr("width", 100)
.attr("height", 100)
.style("opacity", 0.5)
.attr("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
现在使用
percentage = 0.5
,所有内容(位置,不透明度等)都从原始转换的50%开始:const vis = d3.select("body").append('svg').attr("width", 800).attr("height", 614).style("border", "1px solid red");
var rectangle = vis.append("rect").attr("width", 100).attr("height", 70).attr("x", 0).attr("y", 50);
const percentage = 0.5;
rectangle
.transition()
.duration(5000 * (1 - percentage))
.ease(t => d3.easeCubic(percentage + t * (1 - percentage)))
.attr("x", 250)
.attr("width", 100)
.attr("height", 100)
.style("opacity", 0.5)
.attr("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
最后,使用
percentage = 0.8
。因为这是三次放松,所以不透明度/运动即将结束:const vis = d3.select("body").append('svg').attr("width", 800).attr("height", 614).style("border", "1px solid red");
var rectangle = vis.append("rect").attr("width", 100).attr("height", 70).attr("x", 0).attr("y", 50);
const percentage = 0.8;
rectangle
.transition()
.duration(5000 * (1 - percentage))
.ease(t => d3.easeCubic(percentage + t * (1 - percentage)))
.attr("x", 250)
.attr("width", 100)
.attr("height", 100)
.style("opacity", 0.5)
.attr("fill", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
PS:不相关,请使用
style
代替attr
设置样式。您会看到,在您的特定情况下,它会产生巨大的变化。