Как заставить circle двигаться по path с определенного места?
Как заставить красный шарик #circle следовать по окружности, начиная с позиции #mainCircle по нажатию?
<svg class="skillSvg" width="430" height="430" viewBox="0 0 430 430" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d)">
<path id="motionPath" fill="none" stroke="#6699FC" stroke-width="3" stroke-miterlimit="10" d="M16.5,215a198.5,198.5 0 1,0 397,0a198.5,198.5 0 1,0 -397,0"/>
</g>
<g filter="url(#filter1_d)">
<circle id="mainCircle" cx="371.408" cy="110.368" r="45" fill="#9CBEFF"/>
</g>
<circle class="circleSvg" id="circle" cx="0" cy="0" r="15" fill="tomato" />
<animateMotion from="371.408, 110.368" to="0, 0" href="#circle" dur="5s" begin="mainCircle.click" fill="freeze">
<mpath href="#motionPath" />
</animateMotion>
<!-- Style path -->
<defs>
<filter id="filter0_d" x="11" y="15" width="408" height="408" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter1_d" x="322.408" y="65.3682" width="98" height="98" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
</defs>
<!-- ********** -->
</svg>
P.s.: делаю сначала скрытым, тк по дефолту #circle в точке 0,0 (угол документа), при нажатии на #mainCircle он появляется и движется, но не с того места. Для появления по нажатию использую js:
<script>
$(document).ready(function() {
$('#mainCircle').click(function() {
var circle = $('.skillSvg').find('.circleSvg').first();
circle.show();
circle.removeClass('circleSvg');
})
})
</script>
И строчку css:
.circleSvg {
display: none;
}
Ответы (2 шт):
При анимации animateMotion элемент (красный шарик) будет двигаться из начальной точки патча M16.5,215 и вернется в ту же точку, сделав полный круг.
<svg class="skillSvg" width="430" height="430" viewBox="0 0 430 430" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d)">
<path id="motionPath" fill="none" stroke="#6699FC" stroke-width="3" stroke-miterlimit="10" d="M16.5,215a198.5,198.5 0 1,0 397,0a198.5,198.5 0 1,0 -397,0"/>
</g>
<g filter="url(#filter1_d)">
<circle id="mainCircle" cx="371.408" cy="110.368" r="45" fill="#9CBEFF"/>
</g>
<circle class="circleSvg" id="circle" cx="0" cy="0" r="15" fill="tomato" />
<animateMotion from="371.408, 110.368" to="0, 0" href="#circle" dur="5s" begin="mainCircle.click" fill="freeze">
<mpath href="#motionPath" />
</animateMotion>
<!-- Style path -->
<defs>
<filter id="filter0_d" x="11" y="15" width="408" height="408" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter1_d" x="322.408" y="65.3682" width="98" height="98" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
</defs>
<!-- ********** -->
</svg>
Один из способов изменить точку старта - перерисовать патч, сделав начальной точкой патча (M) ту, которая необходима. (смотрите ответ 2)
Использовать пару аргументов
keyPointskeyTimes, которые позволяют перенести точку старта
<animateMotion
id="an1"
dur="2.5s"
begin="mainCircle.click"
fill="freeze"
keyPoints="0.6;1"
keyTimes="0;1">
<div>
<button onclick="an1.beginElement()">forward </button>
</div>
<svg class="skillSvg" width="430" height="430" viewBox="0 0 430 430" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d)">
<path id="motionPath" fill="none" stroke="#6699FC" stroke-width="3" stroke-miterlimit="10" d="M16.5,215a198.5,198.5 0 1,0 397,0a198.5,198.5 0 1,0 -397,0">
</path>
</g>
<g filter="url(#filter1_d)">
<circle id="mainCircle" cx="371.408" cy="110.368" r="45" fill="#9CBEFF"/>
</g>
<circle class="circleSvg" id="circle" opacity="0" cx="0" cy="0" r="15" fill="tomato" >
<!-- До начала анимации красный шарик скрыт-->
<animate
attributeName="opacity" begin="an1.begin"
dur="0.01s"
to="1"
fill="freeze" />
<!-- Первая половина анимации от синего круга до начальной точки патча M16.5,215 -->
<animateMotion
id="an1"
dur="2s"
begin="indefinite"
repeatCount="1"
keyPoints="0.6;1"
keyTimes="0;1"
calcMode="linear"
fill="freeze" >
<mpath href="#motionPath" />
</animateMotion>
</circle>
<!-- Style path -->
<defs>
<filter id="filter0_d" x="11" y="15" width="418" height="418" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter1_d" x="322.408" y="65.3682" width="98" height="98" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
</defs>
<!-- ********** -->
</svg>
Как видно, что начальную точку старта сдвинули назад keyPoints="0.6;1" к синему кругу, но красный шарик закончил свою анимацию в той точке откуда должен был начать движение без сдвига.
- Чтобы заставить шарик делать полный круг от синей окружности до синей, необходимо добавить вторую анимацию
<animateMotion
id="an2"
dur="5s"
begin="an1.end"
fill="freeze"
keyPoints="0;0.6"
keyTimes="0;1">
<mpath href="#motionPath" />
</animateMotion>
<div>
<button onclick="an1.beginElement()">forward </button>
</div>
<svg class="skillSvg" width="430" height="430" viewBox="0 0 430 430" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d)">
<path id="motionPath" fill="none" stroke="#6699FC" stroke-width="3" stroke-miterlimit="10" d="M16.5,215a198.5,198.5 0 1,0 397,0a198.5,198.5 0 1,0 -397,0">
</path>
</g>
<g filter="url(#filter1_d)">
<circle id="mainCircle" cx="371.408" cy="110.368" r="45" fill="#9CBEFF"/>
</g>
<circle class="circleSvg" id="circle" opacity="0" cx="0" cy="0" r="15" fill="tomato" >
<!-- До начала анимации красный шарик скрыт-->
<animate
attributeName="opacity" begin="an1.begin"
dur="0.01s"
to="1"
fill="freeze" />
<!-- Первая половина анимации от синего круга до начальной точки патча M16.5,215 -->
<animateMotion
id="an1"
dur="2s"
begin="indefinite"
repeatCount="1"
keyPoints="0.6;1"
keyTimes="0;1"
calcMode="linear"
fill="freeze"
>
<mpath href="#motionPath" />
</animateMotion>
<!-- Вторая половина анимации от начальной точки патча M16.5,215 до синего круга Начинается после окончания первой анимации -->
<animateMotion
id="an2"
dur="5s"
begin="an1.end"
fill="freeze"
keyPoints="0;0.6"
keyTimes="0;1"
>
<mpath href="#motionPath" />
</animateMotion>
</circle>
<!-- Style path -->
<defs>
<filter id="filter0_d" x="11" y="15" width="418" height="418" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter1_d" x="322.408" y="65.3682" width="98" height="98" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
</defs>
<!-- ********** -->
</svg>
UPDATE
Можно попробовать вариант вместо вращения красного шарика, вращать группу, в которой будет и путь и красный шарик. Выглядеть будет точно также, если бы вращался только один шарик вдоль пути. И в этом варианте можно использовать вашу версию патча для траектории движения шарика.
Для этого создаем группу и вращаем её
<g filter="url(#filter0_d)">
<path id="motionPath" transform="rotate(135 215 215)" fill="none" stroke="#6699FC" stroke-width="3" stroke-miterlimit="10" d="M16.5,215a198.5,198.5 0 1,0 397,0a198.5,198.5 0 1,0 -397,0"/>
<circle class="circleSvg" id="circle" cx="378" cy="105" r="15" fill="tomato" />
<!-- Анимация вращения группы -->
<animateTransform attributeName="transform" type="rotate" begin="mainCircle.click" dur="4s" values="0 215 215;-360 215 215" fill="freeze" restart="whenNotActive" />
</g>
<svg class="skillSvg" width="430" height="430" viewBox="0 0 430 430" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d)">
<path id="motionPath" transform="rotate(135 215 215)" fill="none" stroke="#6699FC" stroke-width="3" stroke-miterlimit="10" d="M16.5,215a198.5,198.5 0 1,0 397,0a198.5,198.5 0 1,0 -397,0">
</path>
<circle class="circleSvg" id="circle" cx="378" cy="105" r="15" fill="tomato" />
<!-- Анимация вращения группы -->
<animateTransform attributeName="transform" type="rotate" begin="mainCircle.click" dur="4s" values="0 215 215;-360 215 215" fill="freeze" restart="whenNotActive" />
</g>
<g filter="url(#filter1_d)">
<circle id="mainCircle" cx="371.408" cy="110.368" r="45" fill="#9CBEFF"/>
</g>
<!-- Style path -->
<defs>
<filter id="filter0_d" x="11" y="15" width="408" height="408" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter1_d" x="322.408" y="65.3682" width="98" height="98" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
</defs>
<!-- ********** -->
</svg>
Вариант с Path у которого начальная точка находится в центре синего круга
В векторном редакторе рисуем новый path. Первая узловая точка наносится внутри синего круга и поэтому начало движения красного шарика начнется и закончится именно из этой точки.
Далее заменяем в программе path на новый
Анимация после клика по синей окружности
<svg class="skillSvg" width="430" height="430" viewBox="0 0 430 430" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_d)">
<path id="motionPath" fill="none" stroke="#6699FC" stroke-width="3" stroke-miterlimit="10" d="M 381.35827,107.26268 365.8978,86.648722 348.50477,67.96732 324.66988,49.285919 300.83498,36.402193 273.77916,24.806841 246.72334,18.364978 216.44658,15.788233 184.23727,19.009164 149.45121,27.383586 123.03958,38.978938 96.627939,55.727781 77.946538,71.832438 61.197695,89.225467 47.669783,107.90687 34.786058,130.45339 25.767451,153.64409 18.037215,185.85341 16.5,215 l 2.181402,26.89761 6.441862,30.92094 9.018608,25.12327 12.883725,22.54652 14.172098,19.32558 15.46047,17.39303 15.460471,14.81629 19.969774,11.59535 25.12326,14.81628 22.54652,7.08605 25.76745,6.44186 27.70001,1.93256 29.63257,-1.93256 26.41164,-5.79767 27.70001,-10.30698 23.83489,-12.88373 22.54652,-17.39303 21.90233,-20.61396 18.6814,-27.05582 14.81629,-27.05582 9.66279,-29.63257 5.15349,-34.14187 -1.28837,-32.8535 -5.15349,-32.20932 -11.59535,-29.63256 z">
</path>
</g>
<g filter="url(#filter1_d)">
<circle id="mainCircle" cx="371.408" cy="110.368" r="45" fill="#9CBEFF"/>
</g>
<circle class="circleSvg" id="circle" opacity="0" cx="0" cy="0" r="15" fill="tomato" >
<!-- До начала анимации красный шарик скрыт-->
<animate
attributeName="opacity" begin="mainCircle.click"
dur="0.01s"
to="1"
fill="freeze" />
<!-- анимация от синего круга из начальной точки патча M 381.35827,107.26268 -->
<animateMotion
id="an1"
dur="2.5s"
begin="mainCircle.click"
fill="freeze"
keyPoints="0;1"
keyTimes="0;1">
<mpath href="#motionPath" />
</circle>
<!-- Style path -->
<defs>
<filter id="filter0_d" x="11" y="15" width="418" height="418" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
<filter id="filter1_d" x="322.408" y="65.3682" width="98" height="98" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
<feOffset dy="4"/>
<feGaussianBlur stdDeviation="2"/>
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow"/>
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
</filter>
</defs>
<!-- ********** -->
</svg>

