Можно ли добиться такого же эффекта?
Появился вопрос не по теме SVG => Как анимировать последовательно UIBezier линии
Разумеется что это можно реализовать на smil
Вот что я сделал
<svg viewBox="0 0 500 150" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<marker id="dot" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="5" markerHeight="5">
<circle cx="5" cy="5" r="5" fill="#fff" stroke="red" stroke-width="1" />
</marker>
</defs>
<path d="" fill="none" stroke="#000" stroke-width="1.2" marker-start="url(#dot)" marker-mid="url(#dot)" marker-end="url(#dot)">
<animate attributeName="d" begin="0s" dur="4s" attributeType="XML" values="
M20,120 50,130 120,120 180,100 220,130 300,120 340,125 410,90 490,140;
M20,120 50,50 120,120 180,100 220,130 300,120 340,125 410,90 490,140;
M20,120 50,50 120,120 180,20 220,130 300,120 340,125 410,90 490,140;
M20,120 50,50 120,40 180,20 220,130 300,120 340,125 410,90 490,140;
M20,120 50,50 120,40 180,20 220,50 300,120 340,125 410,90 490,140;
M20,120 50,50 120,40 180,20 220,50 300,70 340,125 410,90 490,140;
M20,120 50,50 120,40 180,20 220,50 300,70 340,55 410,90 490,140;
M20,120 50,50 120,40 180,20 220,50 300,70 340,55 410,90 490,30;
M20,120 50,50 120,40 180,20 220,50 300,70 340,55 410,40 490,30;
M20,120 50,50 120,40 180,20 220,50 300,70 340,85 410,40 490,30;
M20,120 50,130 120,120 180,100 220,130 300,120 340,125 410,90 490,140;" repeatCount="indefinite" keyTimes="0; 0.1; 0.15; 0.27; 0.30; 0.40; 0.45; 0.80; 0.90; 0.97; 1"/>
</path>
</svg>
Но как видно их анимированной картинки что присутствует некое дрожание
Можно ли средствами SVG animation - smil добиться такого поведения ?
Ответы (1 шт):
Автор решения: UModeL
→ Ссылка
Анимация точек с равными интервалами будет выглядеть примерно так:
<svg viewBox="0 0 600 278" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<marker id="dot" viewBox="0 0 20 20" refX="10" refY="10" markerWidth="10" markerHeight="10">
<circle cx="10" cy="10" r="3" fill="#fff" stroke="#485d7e" stroke-width="2" />
</marker>
</defs>
<path d="" fill="none" stroke="#485d7e" stroke-width="3" marker-start="url(#dot)" marker-mid="url(#dot)" marker-end="url(#dot)">
<animate attributeName="d" begin="0s" dur="2s" repeatCount="indefinite" attributeType="XML"
values="
M19,250 70,250 121,250 171,250 222,250 273,250 323,250 374,250 424,250 475,250 526,250 576,250;
M19,185 70,250 121,250 171,250 222,250 273,250 323,250 374,250 424,250 475,250 526,250 576,250;
M19,202 70,14 121,250 171,250 222,250 273,250 323,250 374,250 424,250 475,250 526,250 576,250;
M19,198 70,76 121,212 171,250 222,250 273,250 323,250 374,250 424,250 475,250 526,250 576,250;
M19,199 70,60 121,222 171,181 222,250 273,250 323,250 374,250 424,250 475,250 526,250 576,250;
M19,199 70,64 121,219 171,199 222,67 273,250 323,250 374,250 424,250 475,250 526,250 576,250;
M19,199 70,64 121,220 171,195 222,115 273,67 323,250 374,250 424,250 475,250 526,250 576,250;
M19,199 70,64 121,220 171,196 222,103 273,115 323,179 374,250 424,250 475,250 526,250 576,250;
M19,199 70,64 121,220 171,196 222,106 273,103 323,198 374,218 424,250 475,250 526,250 576,250;
M19,199 70,64 121,220 171,196 222,106 273,106 323,193 374,227 424,247 475,250 526,250 576,250;
M19,199 70,64 121,220 171,196 222,106 273,106 323,194 374,224 424,248 475,43 526,250 576,250;
M19,199 70,64 121,220 171,196 222,106 273,106 323,194 374,225 424,248 475,98 526,94 576,250;
M19,199 70,64 121,220 171,196 222,106 273,106 323,194 374,225 424,248 475,83 526,135 576,209;
M19,199 70,64 121,220 171,196 222,106 273,106 323,194 374,225 424,248 475,87 526,124 576,220;
M19,199 70,64 121,220 171,196 222,106 273,106 323,194 374,225 424,248 475,87 526,127 576,217;
M19,199 70,64 121,220 171,196 222,106 273,106 323,194 374,225 424,248 475,87 526,127 576,218;"
keyTimes="
0; 0.066; 0.133; 0.2; 0.266; 0.333; 0.4; 0.466; 0.533; 0.6; 0.666; 0.733; 0.8; 0.866; 0.933; 1"
/>
</path>
</svg>
Считал отскоки простейшим скриптиком:
document.querySelector('div.calc').addEventListener('input', function(ev) {
p1.value = Math.round(+pe.value - (+pb.value - +pe.value) / 3.72);
p2.value = Math.round(+pe.value + (+pb.value - +pe.value) / 15.5);
p3.value = Math.round(+pe.value - (+pb.value - +pe.value) / 46.5);
});
.calc { display: flex; flex-flow: column nowrap; width: 400px; }
<div class="calc">
<label>Исходная точка <input id="pb" type="number" max=250 value=250></label>
<label>Точка отскока 1 <input id="p1" type="number" value=0 readonly></label>
<label>Точка отскока 2 <input id="p2" type="number" value=0 readonly></label>
<label>Точка отскока 3 <input id="p3" type="number" value=0 readonly></label>
<label>Конечная точка <input id="pe" type="number" max=250 value=100></label>
</div>
Конечно, на основе этого, можно сделать автоматический расчёт координат и таймингов, а передавать только массив конечных значений. Это уже целый плагин получится, но задача такая в вопросе не стояла ;-)
