Reputation: 2346
I know how to do a normal fade in transition using the opacity attribute, but how would I go about making the transition start from one end of the element and gradually complete itself horizontally?
Something like this:
I am trying to do this for some text:
text = svg.selectAll(".myText")
.data(myData)
.enter()
.append("text")
.attr("class", "myText")
.attr("text-anchor", "start")
.attr("fill-opacity", 0)
.text(function (d)
{
return d.message
});
text.transition()
.delay(500)
.duration(1000)
.attr("fill-opacity", 1)
Upvotes: 3
Views: 1394
Reputation: 108567
Cool question. How about this craziness:
<!DOCTYPE html>
<html>
<head>
<script data-require="[email protected]" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<script>
var str = "This is a long string.",
i = 0;
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 300);
var text = svg.append("text")
.style("fill", "black")
.style("font-size", "30pt")
.style("font-family", "arial")
.attr("transform", "translate(10,50)");
fadeLeftToRight();
function fadeLeftToRight(){
i++;
if (i >= str.length) return;
var char = str.substring(i-1,i);
text
.append("tspan")
.style("opacity", 0)
.text(char)
.transition()
.delay(100)
.duration(char === " " ? 0 : 500)
.style("opacity", 1)
.each("start", function(d){
fadeLeftToRight();
})
}
</script>
</body>
</html>
Upvotes: 1
Reputation: 3562
You can see how to do this with pure CSS here: CSS fade left to right
Below is the same approach given in the linked answer just applying it with D3...
The gist is to place a box over the text and use transitions to modify the box width (from completely covering the text to completely revealing it).
To prevent the box edges from being visible and too harsh a gradient is applied.
To make sure the box nicely covers the text, the covering rect uses parameters from the text's bounding box using the function getBBox()
var height = 25,
width = 100;
d3.select('div').append('svg')
.attr('width', '100%')
.attr('viewBox', "0 0 " + width + " " + height)
.attr('style', 'border: solid 1px green')
.append('g')
.attr('transform','translate('+ width/2 +','+ height/2 +')')
.attr('id', 'main');
var text = d3.select('#main').append('text')
.attr('class', 'myText')
.attr('text-anchor', 'middle')
.attr('alignment-baseline','middle')
.text('My Message');
bbox = text[0][0].getBBox();
var gradient = d3.select('svg').append("defs")
.append("linearGradient")
.attr("id", "gradient")
.attr("x1", "0%")
.attr("x2", "0%")
.attr("spreadMethod", "pad");
gradient.append("stop")
.attr("offset", "0%")
.attr("stop-color", "#fff")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr("offset", "100%")
.attr("stop-color", "#fff")
.attr("stop-opacity", 0);
fadeBox = d3.select('#main').append('rect')
.attr('x', bbox.x)
.attr('y', bbox.y)
.attr('width', bbox.width)
.attr('height', bbox.height)
.style("fill", "url(#gradient)");
fadeBox.transition()
.delay(500)
.duration(2000)
.attr('width', 0)
.attr('x', bbox.width)
gradient.transition()
.delay('500')
.duration('2000')
.attr('x1','100%')
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div>
</div>
Upvotes: 5