在此jsfiddle
中,标签通过减少旧文本的字体从一个文本转换到另一个文本,从而增加新文本的字体。
但是,我希望以“打字机”的方式将新文本用于上传,就像在jsfiddle
中一样。如何编写自定义D3文本插补器,以这种“打字机”方式启用文本转换?
答案 0 :(得分:8)
有趣的想法,都可以完成工作,但有一种特定于d3的方法:自定义tween function。
在这里小提琴:http://jsfiddle.net/QbysN/3/
代码:
function transition() {
d3.select('text').transition()
.duration(5000)
.ease("linear")
.tween("text", function () {
var newText = data[i];
var textLength = newText.length;
return function (t) {
this.textContent = newText.substr(0,
Math.round( t * textLength) );
};
});
i = (i + 1) % data.length;
}
传递给.tween()
的外部函数称为 tween factory ,因为它为每个元素创建了补间函数。在转换开始时,每个元素执行一次(通常使用元素的数据和索引作为参数)。它运行任何设置计算,然后返回将在转换期间使用的补间函数。
返回的补间函数也称为插值器,因为它计算中间值。在这种情况下,它是:
function (t) {
this.textContent = newText.substr(0, Math.round( t * textLength) );
};
此函数将在转换的每个“tick”处被调用,并传递0到1之间的值,表示结果应该在转换的距离。 (0更改为1的速率将根据缓动参数而变化,我使用线性缓动来获得稳定的类型。)
当您为属性或样式指定自定义补间函数时,补间函数将返回在转换中该点处用于该属性或样式的值。对于泛型transition.tween()
,不使用返回值,您的函数必须实际进行更改 - 我通过直接设置元素的textContent
属性来执行此操作。我将它设置为目标文本的子字符串,其中子字符串中的字符数由t
参数(始终在0和1之间)和文本的长度确定,以便整个文本在转换的长度内输入。
P.S。您也可以享受缓动功能。 “弹跳”的轻松使得打字员看起来不确定他们写的是什么:
答案 1 :(得分:2)
我试了一下。我必须说我之前没有任何D3经验。我试图得到你展示的两个小提琴的组合。我认为仍然需要做一些清理以及何时停止打字,但这些应该是微不足道的。
查看jsFiddle
<强> HTML:强>
<div id="writer">
<span id='sentence'></span>
<span id='char'></span>
</div>
<强> CSS:强>
#writer{
border: 1px solid black;
width:300px;
min-height: 200px;
margin: auto;
}
span
{
float:left;
}
<强> JavaScript的:强>
var text = "Hello World! I'm some typed text!";
var counter = 0;
var speed = 50;
function type()
{
var sentence = document.getElementById("sentence");
var lastText = sentence.innerHTML;
var nextChar = text.charAt(counter);
counter++;
transition(nextChar,
function()
{
lastText+=nextChar;
sentence.innerHTML = lastText;
setTimeout(type, speed);
});
}
function transition(char, onComplete) {
d3.select('#char').transition()
.text("")
.duration(300)
.style("font-size","1px")
.transition()
.duration(300)
.text(char)
.style("font-size","16px")
.each("end", onComplete);
}
type();
答案 2 :(得分:2)
我认为文本会更容易自动输入。因此,我遍历每个字符并调用过渡方法。我向它添加了2个参数row
和column
,以便我可以给出适当的延迟。
data.forEach(function(d,row) {
d.split("").forEach(function(d,column) {
transition(row,column);
});
});
function transition(row,column) {
d3.select('text').datum(data[row].split("").slice(0,column+1))
.transition()
.delay(function(d) { return (row*5000) + (column*50); } )
.text(function(d){return d.join("");});
}
试试这个小提琴:http://jsfiddle.net/QbysN/2/