Ориентация поворота круглого изображения в SVG progress
Я пытаюсь создать круглый индикатор выполнения (как показано на изображении ниже). Прогрессия основана на процентах и будет двигаться по кругу до этого процента.
У меня прогрессия (линия) движется, но иконка, который движется вместе с ней, должна иметь правильную ориентацию. Как показано на изображении ниже, нижняя часть изображения обращена к центру, тогда как она должна быть обращена к нижней части экрана. Изображения должны двигаться вместе с полосой.
<div class="case_progress_wrapper" data-percent="80">
<svg class="case_progress_circle" height="100%" width="100%" viewBox="0 0 140 140">
<circle id="case_progress__path" cx="70" cy="70" r="54" fill="none" stroke="#EBEDF8" stroke-width="1" />
<circle class="case_progress__value" cx="70" cy="70" r="54" fill="none" stroke="#f00" stroke-width="6" />
<circle class="case_progress__inner" cx="70" cy="70" r="44" fill="#fff" stroke="#fff" stroke-width="1" />
<circle class="case_progress__start" cx="124" cy="63" r="3" fill="#fff" stroke="#fff" stroke-width="1" />
<g id='case_progress__prog_fill' class="case_progress__prog" viewBox="0 0 60 60">
<circle fill="url(#image)" cx="124" cy="63" r="8" stroke="#fff" stroke-width="1" />
</g>
<defs>
<pattern id="image" x="0%" y="0%" height="100%" width="100%" viewBox="0 0 60 60">
<image x="0%" y="0%" width="60" height="60" xlink:href="https://via.placeholder.com/150x150"></image>
</pattern>
</defs>
</svg>
</div>
(function(){
var $wrapper = $('.case_progress_wrapper'),
$progress = $('.case_progress__value'),
$circle_path = $('#case_progress__path'),
$complete_circle = $('.case_progress__prog'),
$percent = $wrapper.data('percent');
setTimeout(function () {
$progress.css('transition', 'all 2s');
$progress.css('stroke-dashoffset', 'calc(339.292 - (' + $percent + ' * 339.292 / 100))');
$complete_circle.css('transition', 'all 2s');
$complete_circle.attr("transform", 'rotate(' + (360 - ($percent - 25)) + ',' + $circle_path.attr('cx') + ',' + $circle_path.attr('cy') +')');
setTimeout(function () {
$progress.css('transition', 'none');
$complete_circle.css('transition', 'all 2s');
}, 2000);
}, 1000);
})();
Свободный перевод вопроса SVG progress circle image rotation orientation от участника @Bryan88.
Ответы (1 шт):
Решение на pure SVG и немного JS для вывода процентов.
Как и в этом вопросе
Для решения, Вам нужно объединить две анимации:
1. Анимация заполнения дуги от начала до конца
Изменяется атрибут stroke-dashoffset
<animate attributeName="stroke-dashoffset"
begin="0s" dur="10s" values="339.5;0" fill="freeze" />
2. Анимация движения окружности с иконкой внутри
Движение иконки по той же окружности, у которой идёт заполнение красным цветом
<animateMotion begin="0s" dur="10s" fill="freeze" >
<mpath xlink:href="#case_progress__path" />
</animateMotion>
Для синхронности анимаций установите одинаковое время выполнения
Прочитайте пожалуйста комментарии в коде.
var count = $(('#count'));
$({ Counter: 0 }).animate({ Counter: count.text() }, {
duration: 10000,
easing: 'linear',
step: function () {
count.text(Math.ceil(this.Counter)+ "%");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="case_progress_wrapper" data-percent="80" style="width:50vw; height:50vh;">
<svg class="case_progress_circle" viewBox="0 0 140 140">
<defs>
<pattern id="image" x="0%" y="0%" height="100%" width="100%" viewBox="1 0 58 58">
<image x="0%" y="0%" width="60" height="60" xlink:href="https://i.stack.imgur.com/uQMJ3.jpg"></image>
</pattern>
</defs>
<rect width="100%" height="100%" fill="#87CEEB" />
<g transform="rotate(-90 70 70)" >
<!-- Трек для вращения круга с изображением -->
<path id="case_progress__path"
style="fill:none;stroke:#ebedf8;stroke-width:1"
d="M 124,70 A 54,54 0 0 1 70,124 54,54 0 0 1 16,70 54,54 0 0 1 70,16 54,54 0 0 1 124,70 Z"/>
<!-- Красная окружность роста прогресс бара -->
<circle
class="case_progress__value" stroke-dashoffset="339.5" stroke-dasharray="339.5" cx="70" cy="70" r="54" fill="none" stroke="#f00" stroke-width="6" >
<!-- Анимация прогресс бара -->
<animate attributeName="stroke-dashoffset" begin="0s" dur="10s" values="339.5;0" fill="freeze" />
</circle>
<!-- Точка старта -->
<circle class="case_progress__start" cx="124" cy="70" r="3" fill="#fff" stroke="#fff" stroke-width="1" />
<g id='case_progress__prog_fill' class="case_progress__prog" viewBox="1 0 58 58">
<circle transform="rotate(90 0 0)" fill="url(#image)" cx="0" cy="0" r="8" stroke-width="0.25" stroke="#fff" >
<!-- Анимация вращения иконки -->
<animateMotion begin="0s" dur="10s" fill="freeze" >
<mpath xlink:href="#case_progress__path" />
</animateMotion>
</circle>
</g>
</g>
<circle class="case_progress__inner" cx="70" cy="70" r="44" fill="#fff" stroke="#fff" stroke-width="1" />
<text id="count" x="50%" y="50%" fill="red" text-anchor="middle" dy="7" font-size="20">100%</text>
</svg>
</div>
Свободный перевод ответа от участника @Alexandr_TT.

