Display arrow head for an animated line
I am animating a line from Point 1 to Point 2 with https://jsfiddle.net/arungeorgez/r9x6vhcb/4/. How do I add an arrowhead to the same line?
<style>
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
</style>
css html5 webkit
add a comment |
I am animating a line from Point 1 to Point 2 with https://jsfiddle.net/arungeorgez/r9x6vhcb/4/. How do I add an arrowhead to the same line?
<style>
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
</style>
css html5 webkit
What is your technical difficulty? Is it difficult to calculate the correct coordinates of the path or the timing? All you need to do is draw the arrowhead. Have you tried anything regarding drawing the arrowhead itself?
– Andrei Gheorghiu
Nov 15 '18 at 23:39
The arrow head can be drawn but how can it be animated along with the line?
– Arun George
Nov 15 '18 at 23:50
You have a limited set of options and you should pick the one you like. You can either start two lines from the end of the arrow itself after you finish the arrow, you can treat the entire composition as a drawing and imagine it's uncovered by a piece of paper (so you'd start drawing the two small lines as you get close to the arrow's head) or you could draw the arrow head separately, after finishing the arrow, as you would with a pen (starting from one of the sides, going to the arrow head and then finishing it in the other side).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
Updated the code to include the arrow head.
– Arun George
Nov 16 '18 at 0:03
Solution B can be applied also to the case where, instead of having two small lines as arrow head you want an area there (with one or two triangles, depending on the type of arrow head you want).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
add a comment |
I am animating a line from Point 1 to Point 2 with https://jsfiddle.net/arungeorgez/r9x6vhcb/4/. How do I add an arrowhead to the same line?
<style>
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
</style>
css html5 webkit
I am animating a line from Point 1 to Point 2 with https://jsfiddle.net/arungeorgez/r9x6vhcb/4/. How do I add an arrowhead to the same line?
<style>
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
</style>
css html5 webkit
css html5 webkit
edited Nov 16 '18 at 0:03
Arun George
asked Nov 15 '18 at 23:33
Arun GeorgeArun George
4172722
4172722
What is your technical difficulty? Is it difficult to calculate the correct coordinates of the path or the timing? All you need to do is draw the arrowhead. Have you tried anything regarding drawing the arrowhead itself?
– Andrei Gheorghiu
Nov 15 '18 at 23:39
The arrow head can be drawn but how can it be animated along with the line?
– Arun George
Nov 15 '18 at 23:50
You have a limited set of options and you should pick the one you like. You can either start two lines from the end of the arrow itself after you finish the arrow, you can treat the entire composition as a drawing and imagine it's uncovered by a piece of paper (so you'd start drawing the two small lines as you get close to the arrow's head) or you could draw the arrow head separately, after finishing the arrow, as you would with a pen (starting from one of the sides, going to the arrow head and then finishing it in the other side).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
Updated the code to include the arrow head.
– Arun George
Nov 16 '18 at 0:03
Solution B can be applied also to the case where, instead of having two small lines as arrow head you want an area there (with one or two triangles, depending on the type of arrow head you want).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
add a comment |
What is your technical difficulty? Is it difficult to calculate the correct coordinates of the path or the timing? All you need to do is draw the arrowhead. Have you tried anything regarding drawing the arrowhead itself?
– Andrei Gheorghiu
Nov 15 '18 at 23:39
The arrow head can be drawn but how can it be animated along with the line?
– Arun George
Nov 15 '18 at 23:50
You have a limited set of options and you should pick the one you like. You can either start two lines from the end of the arrow itself after you finish the arrow, you can treat the entire composition as a drawing and imagine it's uncovered by a piece of paper (so you'd start drawing the two small lines as you get close to the arrow's head) or you could draw the arrow head separately, after finishing the arrow, as you would with a pen (starting from one of the sides, going to the arrow head and then finishing it in the other side).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
Updated the code to include the arrow head.
– Arun George
Nov 16 '18 at 0:03
Solution B can be applied also to the case where, instead of having two small lines as arrow head you want an area there (with one or two triangles, depending on the type of arrow head you want).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
What is your technical difficulty? Is it difficult to calculate the correct coordinates of the path or the timing? All you need to do is draw the arrowhead. Have you tried anything regarding drawing the arrowhead itself?
– Andrei Gheorghiu
Nov 15 '18 at 23:39
What is your technical difficulty? Is it difficult to calculate the correct coordinates of the path or the timing? All you need to do is draw the arrowhead. Have you tried anything regarding drawing the arrowhead itself?
– Andrei Gheorghiu
Nov 15 '18 at 23:39
The arrow head can be drawn but how can it be animated along with the line?
– Arun George
Nov 15 '18 at 23:50
The arrow head can be drawn but how can it be animated along with the line?
– Arun George
Nov 15 '18 at 23:50
You have a limited set of options and you should pick the one you like. You can either start two lines from the end of the arrow itself after you finish the arrow, you can treat the entire composition as a drawing and imagine it's uncovered by a piece of paper (so you'd start drawing the two small lines as you get close to the arrow's head) or you could draw the arrow head separately, after finishing the arrow, as you would with a pen (starting from one of the sides, going to the arrow head and then finishing it in the other side).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
You have a limited set of options and you should pick the one you like. You can either start two lines from the end of the arrow itself after you finish the arrow, you can treat the entire composition as a drawing and imagine it's uncovered by a piece of paper (so you'd start drawing the two small lines as you get close to the arrow's head) or you could draw the arrow head separately, after finishing the arrow, as you would with a pen (starting from one of the sides, going to the arrow head and then finishing it in the other side).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
Updated the code to include the arrow head.
– Arun George
Nov 16 '18 at 0:03
Updated the code to include the arrow head.
– Arun George
Nov 16 '18 at 0:03
Solution B can be applied also to the case where, instead of having two small lines as arrow head you want an area there (with one or two triangles, depending on the type of arrow head you want).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
Solution B can be applied also to the case where, instead of having two small lines as arrow head you want an area there (with one or two triangles, depending on the type of arrow head you want).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
add a comment |
1 Answer
1
active
oldest
votes
<animate attributeType="XML"
attributeName="opacity"
from="0" to="1"
dur=".08s" begin=".23s"
repeatCount="0" fill="freeze"
/>
seems to produce a decent effect for your case, since the arrowhead is small. However, for a more fine-tuned solution one could use <animateTransform>
or <animateMotion>
, instead of <animate>
, depending on case.
Here's the spec for SMIL Animations.
While the effect is easily achievable with CSS animations (in the end, I'm only animating opacity
above), I tend to recommend SMIL Animations for <svg>
s, as they provide a lot more options for controlling the different aspects of animations, far superior to CSS options, IMHO.
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
$(document).ready(function() {
var line = makeSVG('line', {
id: "-",
class: "key-anim1",
x1: 20,
y1: 20,
x2: 120,
y2: 120,
stroke: 'black',
'stroke-width': 2,
'marker-end': "url(#arrow)"
});
document.getElementById("svg").appendChild(line);
});
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth" opacity="0">
<path d="M0,0 L0,6 L9,3 z" fill="#000" />
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".08s" begin=".23s" repeatCount="0" fill="freeze" />
</marker>
</defs>
</svg>
Note: the easy way to fine-tune any animation is to decrease the speed 10 times. This way you'll be able to make it perfect, and to increase it back after you're happy with how it performs 10 times slower. Sometimes, when speeding it back up you need to make minor adjustments from how it would be "technically correct" to counterbalance optical illusions (but this is often times far into the land of "invisible details").
If you want the maker to be visible and move along with the line, you need to drop the dasharray (because now your line has the same length from start to end of animation, but it's drawn with a dashed line and you're simply moving the gaps in that dashed line so it looks like it's growing). Instead you need to make it short initially and animate it towards being longer.
Here's an example:
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#000" opacity="0">
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".1s" repeatCount="0" fill="freeze" />
</path>
</marker>
</defs>
<line id="-" x1="20" y1="20" x2="21" y2="21" stroke="black" stroke-width="2" marker-end="url(#arrow)">
<animate attributeType="XML" attributeName="x2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
<animate attributeType="XML" attributeName="y2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
</line>
</svg>
Can markers be animated from (x1,y1) to (x2,y2)?
– Arun George
Nov 16 '18 at 20:05
Yes, any attribute can be animated in SVG as long as it has same type of values and they are animatable (don't expect a string to be animated into another string, though)... I added an example.
– Andrei Gheorghiu
Nov 16 '18 at 22:59
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53329341%2fdisplay-arrow-head-for-an-animated-line%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
<animate attributeType="XML"
attributeName="opacity"
from="0" to="1"
dur=".08s" begin=".23s"
repeatCount="0" fill="freeze"
/>
seems to produce a decent effect for your case, since the arrowhead is small. However, for a more fine-tuned solution one could use <animateTransform>
or <animateMotion>
, instead of <animate>
, depending on case.
Here's the spec for SMIL Animations.
While the effect is easily achievable with CSS animations (in the end, I'm only animating opacity
above), I tend to recommend SMIL Animations for <svg>
s, as they provide a lot more options for controlling the different aspects of animations, far superior to CSS options, IMHO.
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
$(document).ready(function() {
var line = makeSVG('line', {
id: "-",
class: "key-anim1",
x1: 20,
y1: 20,
x2: 120,
y2: 120,
stroke: 'black',
'stroke-width': 2,
'marker-end': "url(#arrow)"
});
document.getElementById("svg").appendChild(line);
});
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth" opacity="0">
<path d="M0,0 L0,6 L9,3 z" fill="#000" />
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".08s" begin=".23s" repeatCount="0" fill="freeze" />
</marker>
</defs>
</svg>
Note: the easy way to fine-tune any animation is to decrease the speed 10 times. This way you'll be able to make it perfect, and to increase it back after you're happy with how it performs 10 times slower. Sometimes, when speeding it back up you need to make minor adjustments from how it would be "technically correct" to counterbalance optical illusions (but this is often times far into the land of "invisible details").
If you want the maker to be visible and move along with the line, you need to drop the dasharray (because now your line has the same length from start to end of animation, but it's drawn with a dashed line and you're simply moving the gaps in that dashed line so it looks like it's growing). Instead you need to make it short initially and animate it towards being longer.
Here's an example:
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#000" opacity="0">
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".1s" repeatCount="0" fill="freeze" />
</path>
</marker>
</defs>
<line id="-" x1="20" y1="20" x2="21" y2="21" stroke="black" stroke-width="2" marker-end="url(#arrow)">
<animate attributeType="XML" attributeName="x2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
<animate attributeType="XML" attributeName="y2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
</line>
</svg>
Can markers be animated from (x1,y1) to (x2,y2)?
– Arun George
Nov 16 '18 at 20:05
Yes, any attribute can be animated in SVG as long as it has same type of values and they are animatable (don't expect a string to be animated into another string, though)... I added an example.
– Andrei Gheorghiu
Nov 16 '18 at 22:59
add a comment |
<animate attributeType="XML"
attributeName="opacity"
from="0" to="1"
dur=".08s" begin=".23s"
repeatCount="0" fill="freeze"
/>
seems to produce a decent effect for your case, since the arrowhead is small. However, for a more fine-tuned solution one could use <animateTransform>
or <animateMotion>
, instead of <animate>
, depending on case.
Here's the spec for SMIL Animations.
While the effect is easily achievable with CSS animations (in the end, I'm only animating opacity
above), I tend to recommend SMIL Animations for <svg>
s, as they provide a lot more options for controlling the different aspects of animations, far superior to CSS options, IMHO.
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
$(document).ready(function() {
var line = makeSVG('line', {
id: "-",
class: "key-anim1",
x1: 20,
y1: 20,
x2: 120,
y2: 120,
stroke: 'black',
'stroke-width': 2,
'marker-end': "url(#arrow)"
});
document.getElementById("svg").appendChild(line);
});
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth" opacity="0">
<path d="M0,0 L0,6 L9,3 z" fill="#000" />
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".08s" begin=".23s" repeatCount="0" fill="freeze" />
</marker>
</defs>
</svg>
Note: the easy way to fine-tune any animation is to decrease the speed 10 times. This way you'll be able to make it perfect, and to increase it back after you're happy with how it performs 10 times slower. Sometimes, when speeding it back up you need to make minor adjustments from how it would be "technically correct" to counterbalance optical illusions (but this is often times far into the land of "invisible details").
If you want the maker to be visible and move along with the line, you need to drop the dasharray (because now your line has the same length from start to end of animation, but it's drawn with a dashed line and you're simply moving the gaps in that dashed line so it looks like it's growing). Instead you need to make it short initially and animate it towards being longer.
Here's an example:
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#000" opacity="0">
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".1s" repeatCount="0" fill="freeze" />
</path>
</marker>
</defs>
<line id="-" x1="20" y1="20" x2="21" y2="21" stroke="black" stroke-width="2" marker-end="url(#arrow)">
<animate attributeType="XML" attributeName="x2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
<animate attributeType="XML" attributeName="y2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
</line>
</svg>
Can markers be animated from (x1,y1) to (x2,y2)?
– Arun George
Nov 16 '18 at 20:05
Yes, any attribute can be animated in SVG as long as it has same type of values and they are animatable (don't expect a string to be animated into another string, though)... I added an example.
– Andrei Gheorghiu
Nov 16 '18 at 22:59
add a comment |
<animate attributeType="XML"
attributeName="opacity"
from="0" to="1"
dur=".08s" begin=".23s"
repeatCount="0" fill="freeze"
/>
seems to produce a decent effect for your case, since the arrowhead is small. However, for a more fine-tuned solution one could use <animateTransform>
or <animateMotion>
, instead of <animate>
, depending on case.
Here's the spec for SMIL Animations.
While the effect is easily achievable with CSS animations (in the end, I'm only animating opacity
above), I tend to recommend SMIL Animations for <svg>
s, as they provide a lot more options for controlling the different aspects of animations, far superior to CSS options, IMHO.
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
$(document).ready(function() {
var line = makeSVG('line', {
id: "-",
class: "key-anim1",
x1: 20,
y1: 20,
x2: 120,
y2: 120,
stroke: 'black',
'stroke-width': 2,
'marker-end': "url(#arrow)"
});
document.getElementById("svg").appendChild(line);
});
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth" opacity="0">
<path d="M0,0 L0,6 L9,3 z" fill="#000" />
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".08s" begin=".23s" repeatCount="0" fill="freeze" />
</marker>
</defs>
</svg>
Note: the easy way to fine-tune any animation is to decrease the speed 10 times. This way you'll be able to make it perfect, and to increase it back after you're happy with how it performs 10 times slower. Sometimes, when speeding it back up you need to make minor adjustments from how it would be "technically correct" to counterbalance optical illusions (but this is often times far into the land of "invisible details").
If you want the maker to be visible and move along with the line, you need to drop the dasharray (because now your line has the same length from start to end of animation, but it's drawn with a dashed line and you're simply moving the gaps in that dashed line so it looks like it's growing). Instead you need to make it short initially and animate it towards being longer.
Here's an example:
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#000" opacity="0">
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".1s" repeatCount="0" fill="freeze" />
</path>
</marker>
</defs>
<line id="-" x1="20" y1="20" x2="21" y2="21" stroke="black" stroke-width="2" marker-end="url(#arrow)">
<animate attributeType="XML" attributeName="x2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
<animate attributeType="XML" attributeName="y2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
</line>
</svg>
<animate attributeType="XML"
attributeName="opacity"
from="0" to="1"
dur=".08s" begin=".23s"
repeatCount="0" fill="freeze"
/>
seems to produce a decent effect for your case, since the arrowhead is small. However, for a more fine-tuned solution one could use <animateTransform>
or <animateMotion>
, instead of <animate>
, depending on case.
Here's the spec for SMIL Animations.
While the effect is easily achievable with CSS animations (in the end, I'm only animating opacity
above), I tend to recommend SMIL Animations for <svg>
s, as they provide a lot more options for controlling the different aspects of animations, far superior to CSS options, IMHO.
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
$(document).ready(function() {
var line = makeSVG('line', {
id: "-",
class: "key-anim1",
x1: 20,
y1: 20,
x2: 120,
y2: 120,
stroke: 'black',
'stroke-width': 2,
'marker-end': "url(#arrow)"
});
document.getElementById("svg").appendChild(line);
});
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth" opacity="0">
<path d="M0,0 L0,6 L9,3 z" fill="#000" />
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".08s" begin=".23s" repeatCount="0" fill="freeze" />
</marker>
</defs>
</svg>
Note: the easy way to fine-tune any animation is to decrease the speed 10 times. This way you'll be able to make it perfect, and to increase it back after you're happy with how it performs 10 times slower. Sometimes, when speeding it back up you need to make minor adjustments from how it would be "technically correct" to counterbalance optical illusions (but this is often times far into the land of "invisible details").
If you want the maker to be visible and move along with the line, you need to drop the dasharray (because now your line has the same length from start to end of animation, but it's drawn with a dashed line and you're simply moving the gaps in that dashed line so it looks like it's growing). Instead you need to make it short initially and animate it towards being longer.
Here's an example:
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#000" opacity="0">
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".1s" repeatCount="0" fill="freeze" />
</path>
</marker>
</defs>
<line id="-" x1="20" y1="20" x2="21" y2="21" stroke="black" stroke-width="2" marker-end="url(#arrow)">
<animate attributeType="XML" attributeName="x2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
<animate attributeType="XML" attributeName="y2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
</line>
</svg>
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
$(document).ready(function() {
var line = makeSVG('line', {
id: "-",
class: "key-anim1",
x1: 20,
y1: 20,
x2: 120,
y2: 120,
stroke: 'black',
'stroke-width': 2,
'marker-end': "url(#arrow)"
});
document.getElementById("svg").appendChild(line);
});
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth" opacity="0">
<path d="M0,0 L0,6 L9,3 z" fill="#000" />
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".08s" begin=".23s" repeatCount="0" fill="freeze" />
</marker>
</defs>
</svg>
function makeSVG(tag, attrs) {
var el = document.createElementNS('http://www.w3.org/2000/svg', tag);
for (var k in attrs)
el.setAttribute(k, attrs[k]);
return el;
}
$(document).ready(function() {
var line = makeSVG('line', {
id: "-",
class: "key-anim1",
x1: 20,
y1: 20,
x2: 120,
y2: 120,
stroke: 'black',
'stroke-width': 2,
'marker-end': "url(#arrow)"
});
document.getElementById("svg").appendChild(line);
});
.key-anim1 {
-webkit-animation: Drawpath 1s linear forwards;
animation: Drawpath 1s linear forwards;
stroke-dasharray: 0, 600;
}
@-webkit-keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
@keyframes Drawpath {
from {
stroke-dasharray: 0, 600;
}
to {
stroke-dasharray: 600, 600;
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth" opacity="0">
<path d="M0,0 L0,6 L9,3 z" fill="#000" />
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".08s" begin=".23s" repeatCount="0" fill="freeze" />
</marker>
</defs>
</svg>
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#000" opacity="0">
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".1s" repeatCount="0" fill="freeze" />
</path>
</marker>
</defs>
<line id="-" x1="20" y1="20" x2="21" y2="21" stroke="black" stroke-width="2" marker-end="url(#arrow)">
<animate attributeType="XML" attributeName="x2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
<animate attributeType="XML" attributeName="y2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
</line>
</svg>
<svg height="600" width="600" id="svg">
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="0" refY="3" orient="auto" markerUnits="strokeWidth">
<path d="M0,0 L0,6 L9,3 z" fill="#000" opacity="0">
<animate attributeType="XML" attributeName="opacity" from="0" to="1" dur=".1s" repeatCount="0" fill="freeze" />
</path>
</marker>
</defs>
<line id="-" x1="20" y1="20" x2="21" y2="21" stroke="black" stroke-width="2" marker-end="url(#arrow)">
<animate attributeType="XML" attributeName="x2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
<animate attributeType="XML" attributeName="y2" from="21" to="120" dur="1s" repeatCount="0" fill="freeze" />
</line>
</svg>
edited Nov 16 '18 at 23:01
answered Nov 16 '18 at 0:26
Andrei GheorghiuAndrei Gheorghiu
36.2k75076
36.2k75076
Can markers be animated from (x1,y1) to (x2,y2)?
– Arun George
Nov 16 '18 at 20:05
Yes, any attribute can be animated in SVG as long as it has same type of values and they are animatable (don't expect a string to be animated into another string, though)... I added an example.
– Andrei Gheorghiu
Nov 16 '18 at 22:59
add a comment |
Can markers be animated from (x1,y1) to (x2,y2)?
– Arun George
Nov 16 '18 at 20:05
Yes, any attribute can be animated in SVG as long as it has same type of values and they are animatable (don't expect a string to be animated into another string, though)... I added an example.
– Andrei Gheorghiu
Nov 16 '18 at 22:59
Can markers be animated from (x1,y1) to (x2,y2)?
– Arun George
Nov 16 '18 at 20:05
Can markers be animated from (x1,y1) to (x2,y2)?
– Arun George
Nov 16 '18 at 20:05
Yes, any attribute can be animated in SVG as long as it has same type of values and they are animatable (don't expect a string to be animated into another string, though)... I added an example.
– Andrei Gheorghiu
Nov 16 '18 at 22:59
Yes, any attribute can be animated in SVG as long as it has same type of values and they are animatable (don't expect a string to be animated into another string, though)... I added an example.
– Andrei Gheorghiu
Nov 16 '18 at 22:59
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53329341%2fdisplay-arrow-head-for-an-animated-line%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
What is your technical difficulty? Is it difficult to calculate the correct coordinates of the path or the timing? All you need to do is draw the arrowhead. Have you tried anything regarding drawing the arrowhead itself?
– Andrei Gheorghiu
Nov 15 '18 at 23:39
The arrow head can be drawn but how can it be animated along with the line?
– Arun George
Nov 15 '18 at 23:50
You have a limited set of options and you should pick the one you like. You can either start two lines from the end of the arrow itself after you finish the arrow, you can treat the entire composition as a drawing and imagine it's uncovered by a piece of paper (so you'd start drawing the two small lines as you get close to the arrow's head) or you could draw the arrow head separately, after finishing the arrow, as you would with a pen (starting from one of the sides, going to the arrow head and then finishing it in the other side).
– Andrei Gheorghiu
Nov 16 '18 at 0:03
Updated the code to include the arrow head.
– Arun George
Nov 16 '18 at 0:03
Solution B can be applied also to the case where, instead of having two small lines as arrow head you want an area there (with one or two triangles, depending on the type of arrow head you want).
– Andrei Gheorghiu
Nov 16 '18 at 0:03