Я пытаюсь создать стрелку, наконечник которой движется от начальной точки до цели. Перемещение наконечника стрелы было успешно выполнено с помощью подсказки @Robert Longson. Я хочу, чтобы конец древка также следовал за наконечником стрелы и рос на всю его длину. Код приведен ниже, и обратите внимание, что вал не растет вместе со стрелкой, а также заканчивается частичной длиной. Есть ли способ исправить это. Любая помощь будет оценена.
<svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" xmlns:xlink = "http://www.w3.org/1999/xlink" viewBox = "5 0 100 45">
<style>
.wire {
fill: none;
stroke: red;
stroke-width: 1px;
/* Stroke-dasharray property to animate */
stroke-dasharray: 100%;
stroke-dashoffset: 100%;
animation: move linear 5s;
}
@keyframes move {
100% {
stroke-dashoffset: 0;
}
}
</style>
<path d = "M10,10 C15,50 95,50 100,10" stroke = "blue" stroke-width = "2" id = "wire" class = "wire">
<animate>
<mpath xlink:href = "#wire" />
</animate>
</path>
<!-- acceptable movement along the path but incorrect orientation -->
<polygon points = "-5,-5 5,0 -5,5 -3,0" fill = "red">
<animateMotion dur = "5s" repeatCount = "1" rotate = "auto" fill = "freeze">
<mpath xlink:href = "#wire" />
</animateMotion>
</polygon>
</svg>
Вот так я думаю. Обратите внимание, что вы могли бы сделать это и в SMIL.
Я установил анимацию вперед, чтобы она оставалась в конце, иначе кривая исчезнет в конце анимации.
Строка console.info показывает, откуда я взял номер.
console.info(document.getElementsByTagName("path")[0].getTotalLength())
<svg xmlns = "http://www.w3.org/2000/svg" version = "1.1" xmlns:xlink = "http://www.w3.org/1999/xlink" viewBox = "5 0 100 45">
<style>
.wire {
fill: none;
stroke: red;
stroke-width: 1px;
/* Stroke-dasharray property to animate */
stroke-dasharray: 118.27912902832031;
stroke-dashoffset: 118.27912902832031;
animation: move linear 5s forwards;
}
@keyframes move {
100% {
stroke-dashoffset: 0;
}
}
</style>
<path d = "M10,10 C15,50 95,50 100,10" stroke = "blue" stroke-width = "2" id = "wire" class = "wire">
<animate>
<mpath xlink:href = "#wire" />
</animate>
</path>
<!-- acceptable movement along the path but incorrect orientation -->
<polygon points = "-5,-5 5,0 -5,5 -3,0" fill = "red">
<animateMotion dur = "5s" repeatCount = "1" rotate = "auto" fill = "freeze">
<mpath xlink:href = "#wire" />
</animateMotion>
</polygon>
</svg>
Привет, Роберт, пожалуйста, проигнорируй мой предыдущий комментарий. Большое спасибо за вашу помощь. Можно ли это сделать лучше с помощью SMIL без вычисления общей длины? Пожалуйста, дайте мне знать.
Вам все равно нужно знать общую длину.
Чтобы переместить курсор и линию одновременно:
begin = "svg1.click"
и длительности dur = "5s"
Максимальная длина кривой 118.3px
так
stroke-dashoffset:118.3px;
stroke-dasharray:118.3px;
#wire {
stroke-dashoffset:118.3px;
stroke-dasharray:118.3px;
stroke:red;
stroke-width:2px;
fill:none;
}
<svg id = "svg1" xmlns = "http://www.w3.org/2000/svg" version = "1.1" xmlns:xlink = "http://www.w3.org/1999/xlink" viewBox = "5 0 100 45">
<style>
</style>
<path id = "wire" d = "M10,10 C15,50 95,50 100,10" >
<!-- Curved path growth animation -->
<animate
attributeName = "stroke-dashoffset"
begin = "svg1.click"
dur = "5s"
values = "118.3;0"
calcMode = "linear"
fill = "freeze"
restart = "whenNotActive" />
</animate>
</path>
<!-- Cursor -->
<polygon points = "-5,-5 5,0 -5,5 -3,0" fill = "red">
<!-- Animating cursor movement along a curved path -->
<animateMotion begin = "svg1.click" dur = "5s" repeatCount = "1" calcMode = "linear" rotate = "auto" fill = "freeze">
<mpath xlink:href = "#wire" />
</animateMotion>
</polygon>
<text x = "40" y = "20" font-size = "6px" fill = "dodgerblue">Click me</text>
</svg>
<script>
var path = document.querySelector('#wire');
var len = (path.getTotalLength() );
console.info("Path length - " + len);
</script>
в качестве бонуса: Движение вперед - назад
onclick
событие<div>
<button onclick = "forward.beginElement()">forward</button>
<button onclick = "back.beginElement()">back</button>
</div>
keyPoints = "0;1"
keyTimes = "0;1"
stroke-dashoffset
values = "118.3;0"
- рост линии
values = "0;118.3"
- линия убавок`
#wire {
stroke-dashoffset:118.3px;
stroke-dasharray:118.3px;
stroke:red;
stroke-width:2px;
fill:none;
}
svg {
width:50%;
height:50%;
}
<div>
<button onclick = "forward.beginElement()">forward</button>
<button onclick = "back.beginElement()">back</button>
</div>
<svg id = "svg1" xmlns = "http://www.w3.org/2000/svg" version = "1.1" xmlns:xlink = "http://www.w3.org/1999/xlink" viewBox = "5 0 100 45">
<style>
</style>
<path id = "wire" d = "M10,10 C15,50 95,50 100,10" >
<!-- Animation of filling, growing a line (`forward`)-->
<animate id = "strokeForward"
attributeName = "stroke-dashoffset"
begin = "forward.begin"
dur = "5s"
values = "118.3;0"
calcMode = "linear"
fill = "freeze"
restart = "whenNotActive" />
<!-- String decrease animation (`back`) -->
<animate id = "strokeBack"
attributeName = "stroke-dashoffset"
begin = "back.begin"
dur = "5s"
values = "0;118.3"
calcMode = "linear"
fill = "freeze"
restart = "whenNotActive" />
</path>
<!-- Cursor -->
<polygon points = "-5,-5 5,0 -5,5 -3,0" fill = "red">
<!-- Animating cursor movement along a curved path (`forward`) -->
<animateMotion
id = "forward"
begin = "indefinite"
dur = "5s"
repeatCount = "1"
calcMode = "linear"
rotate = "auto"
fill = "freeze"
keyPoints = "0;1"
keyTimes = "0;1"
restart = "whenNotActive">
<mpath xlink:href = "#wire" />
</animateMotion>
<!-- Animating cursor movement along a curved path (`back`) -->
<animateMotion
id = "back"
begin = "indefinite"
dur = "5s"
repeatCount = "1"
calcMode = "linear"
rotate = "auto"
fill = "freeze"
keyPoints = "1;0"
keyTimes = "0;1"
restart = "whenNotActive">
<mpath xlink:href = "#wire" />
</animateMotion>
</polygon>
</svg>
@Velusamy Velu Добавлено несколько строк JS, показывающих максимальную длину строки в консоли.
@Alexander_TT - я ценю вашу помощь. Спасибо вам.
Привет @Robert, я ценю ваш быстрый ответ, большое спасибо. Мне нравится результат, но я хотел бы знать, как вы получили число 118.27912902832031 для stroke-dasharray и stroke-dashoffset? Я хочу знать, как его рассчитать, потому что многие такие стрелки будут создаваться на лету, программно. Может ли это быть проще и лучше с помощью SMIL?