对于在d3.js
中应用于文本对象的过渡,我希望像在 this example 中那样对文本进行补间。但是,我的问题是,如果文本是由字母而不是数字组成的,那么这将无法正常工作,直到现在,我仅发现仅使用数字的示例。
所以我的问题是:是否可以在带有字母的文本对象上创建这样的补间过渡?
这是我当前使用它的方式(使用interpolateString() function):
var mytext = svg.append("text")
.style("fill", 'black')
.attr("x", 0)
.attr("y", 0)
.style("font-size", "14")
.text("My old text")
mytext
.transition()
.delay(1500)
.duration(1000)
.tween("text", function(d) {
var self = d3.select(this)
var i = d3.interpolateString(self.text().replace(/,/g, ""), "My new text");
return function(t) {self.text(i(t))};
});
答案 0 :(得分:3)
您对interpolateString
的行为有误解。如果您查看API,将会看到它...
返回两个字符串a和b之间的插值器。字符串插值器查找数字嵌入在a和b中,其中每个数字都具有JavaScript(强调我的语言)可以理解的形式
因此,它不会插值仅由字母组成的字符串。
话虽如此,这使我们想到了一个问题:您想如何对字母进行插值?例如,您可以根据它们在罗马字母中的位置进行插值。如果是这样,这是一种方法:
使用字母创建数组...
const alphabet = " abcdefghijklmnopqrstuvwxyz".split("");
...,然后在tween
函数中,对字母表中每个字母的索引进行插值,从旧文本到新文本:
.tween("text", function() {
return function(t) {
d3.select(this).text(oldText.map(function(d,i){
return alphabet[~~(d3.interpolate(alphabet.indexOf(d), alphabet.indexOf(newText[i]))(t))]
}).join(""))
};
});
这是一个非常基本的方法,仅当两个字符串的长度完全相同时,该方法才有效。另外,请注意我在alphabet
数组中放置一个空格的事实,否则我们将在字符串中获得undefined
。
这是一个演示:
const svg = d3.select("svg")
const oldText = "this is my old text".split("");
const newText = "here is my new text".split("");
const alphabet = " abcdefghijklmnopqrstuvwxyz".split("");
const text = svg.append("text")
.attr("y", 50)
.attr("x", 20)
.attr("font-size", 30)
.text(oldText.join(""));
text.transition()
.delay(500)
.duration(2000)
.ease(d3.easeLinear)
.tween("text", function() {
return function(t) {
d3.select(this).text(oldText.map(function(d, i) {
return alphabet[~~(d3.interpolate(alphabet.indexOf(d), alphabet.indexOf(newText[i]))(t))]
}).join(""))
};
});
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg></svg>