I'd like to animate(move) the text element from point A to B while its content is changing
SVG :
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="300 160 350 150" height="80px" width="100%" xml:space="preserve">
<text id="text_animated" x="422" y="280" fill="white" font-size="17">
<animate attributeName="y" from="150" to="250" begin="3s" dur="5.5s" repeatCount="1" fill="freeze"/>
</text>
<circle cx="422" cy="280" fill="red" r="5">
<animate id="animation_depth_circle" attributeName="cy" from="150" to="250" begin="indefinite" dur="1.5s" repeatCount="1" fill="freeze" onend="endAnimate()" />
</circle>
</svg>
JS:
var counter=0;
var test_t = setInterval(function(){
document.getElementById('text_animated').textContent = ""+counter;
if(counter===120){
clearInterval(test_t);
}
counter=counter+1;
},10);
My goal is to move the text (inside a circle) as the text is changing. The problem is that the text doesn't move. Only the circle does move.
btw. I can't use
document.getElementById('text_animated').setAttribuite('y',something);
because it is not synchronized with the SVG animation (if network bottleneck issues occur). I'm using Chrome.
EDIT :
I managed to move my text using dy as so :
<text x="422" y="280" fill="white" >
<animate attributeName="dy" from="0" to="250" dur="1.5s" repeatCount="indefinite"/>
</text>
The problem is that It doesn't move if I change the text with my javascript. So It's either change or move.
When you do textContent = "" + counter;
you remove the animation from inside the text element. However you can declare the animation outside the animated element (the text in this case) and give an explicit target element for the animation by using the xlink:href
attribute to reference the target's id: xlink:href="#text_animated"
.
Also you are animating the cy attribute. I prefer to use animateTransform
and animate a translation instead
var counter = 0;
var test_t = setInterval(function() {
document.getElementById("text_animated").textContent = "" + counter;
if (counter === 120) {
clearInterval(test_t);
}
counter = counter + 1;
}, 10);
svg{background:black}
<svg viewBox="350 120 150 250" width="200">
<text id="text_animated" x="422" y="150" fill="white" font-size="17" transform="translate(0,0)">
</text>
<animateTransform
attributeType="XML"
attributeName="transform"
type="translate"
values="0,0; 0,100"
begin="3s"
dur="5.5s"
repeatCount="1" fill="freeze"
xlink:href="#text_animated" />
<circle cx="422" cy="280" fill="red" r="5">
<animateTransform id="animation_depth_circle"
attributeType="XML"
attributeName="transform"
type="translate"
values="0,0; 0,100"
begin="3s"
dur="1.5s"
repeatCount="1" fill="freeze"/>
</circle>
</svg>
Yet another solution would have been puting the text inside a tspan element <tspan id="text_animated"></tspan>
var counter = 0;
var test_t = setInterval(function() {
document.getElementById("text_animated").textContent = "" + counter;
if (counter === 120) {
clearInterval(test_t);
}
counter = counter + 1;
}, 10);
svg{background:black}
<svg viewBox="350 120 150 250" width="200">
<text x="422" y="150" fill="white" font-size="17" transform="translate(0,0)">
<animateTransform
attributeType="XML"
attributeName="transform"
type="translate"
values="0,0; 0,100"
begin="3s"
dur="5.5s"
repeatCount="1" fill="freeze"
/>
<tspan id="text_animated"></tspan>
</text>
<circle cx="422" cy="280" fill="red" r="5">
<animateTransform id="animation_depth_circle"
attributeType="XML"
attributeName="transform"
type="translate"
values="0,0; 0,100"
begin="3s"
dur="1.5s"
repeatCount="1" fill="freeze"/>
</circle>
</svg>
I've chanved the viewBox value because I wanted to see what I am doing. You can use what you want.