|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
|
<meta charset="utf-8"> |
|
<head> |
|
<title>CDF test!</title> |
|
<style type="text/css"> |
|
text { |
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; |
|
font-size: 24px; |
|
} |
|
</style> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
|
|
</head> |
|
<body> |
|
|
|
</body> |
|
|
|
|
|
<script type="text/javascript"> |
|
// initialize the svg canvas |
|
var svg = d3.select("body").append("svg") |
|
.attr("width", 960) |
|
.attr("height", 500) |
|
.append("g") |
|
.attr("transform", "translate(80,150)"); |
|
|
|
// the message to animate |
|
var msg = "⇢ My great message"; |
|
// shrink to this many characters |
|
var min = 1; |
|
// once shrunk replace with "replacementText" |
|
var replacementText = '⇠'; |
|
|
|
// add the text to the canvas, calculate it's width, and then remove it |
|
var ty = svg.append("text") |
|
.text(msg); |
|
// could have also used getBBox for width and height |
|
var wid = ty.node().getComputedTextLength(); |
|
ty.remove(); |
|
|
|
ty = svg.append("text") |
|
.text(msg.substr(0, min)); |
|
var minWid = ty.node().getComputedTextLength(); |
|
ty.remove(); |
|
|
|
// add a path of equal length as the width calculated for the text |
|
svg.append("path") |
|
// if you are going to have more than 1 of these |
|
// on a give page, be sure to have a different id for each one |
|
.attr("id", "path") |
|
.attr("d", "M 0 25 L " + wid + " 25") |
|
|
|
// add the text back to the canvas, add a |
|
// text path for the text and link it to the path |
|
// note that the x and y attributes should not be set here - |
|
// instead the appropriate x and y positions should be in the 'd' |
|
// attribute of the path element! |
|
// also - apparently text-anchor does not work well here, although, |
|
// for my needs, it is not needed |
|
var tp = svg.append("text") |
|
.append("textPath") |
|
.attr("class", "textpath") |
|
.attr("xlink:href", "#path") |
|
// initialize startOffset to 0 so things will work nicely right off the bat |
|
.attr('startOffset', 0) |
|
.text(msg); |
|
|
|
// transition the text off of the viewport via the |
|
// startOffset attribute |
|
tp.on('click', function () { |
|
toggleTextSlide(this, msg, (wid - minWid), replacementText) |
|
}); |
|
|
|
function toggleTextSlide(elem, msg, transTo, transText) { |
|
if (d3.select(elem).attr('startOffset') != 0) { |
|
d3.select(elem).text(msg) |
|
.transition() |
|
.duration(750) |
|
.attr('startOffset', 0); |
|
} else { |
|
d3.select(elem).transition() |
|
.duration(750) |
|
.attr('startOffset', transTo) |
|
.each('end', function () { |
|
d3.select(this) |
|
.style('opacity', 0) |
|
.text(transText) |
|
.transition() |
|
.style('opacity', 1); |
|
}); |
|
} |
|
return true; |
|
} |
|
</script> |
|
</html> |