как сделать анимацию текста без прерываний и пробелов?
Вот верстка:
<div class="promo__img">
<svg viewBox="0 0 479 479" class="circle-text">
<defs>
<path id="circlePath<?= $key ?>" d="M150,150 m-100,0 a100,100 0 1,1 200,0 a100,100 0 1,1 -200,0" />
</defs>
<text>
<textPath id="circleTextPath<?= $key ?>" href="#circlePath<?= $key ?>" startOffset="0%"> КВИЗДЛЯМЕДИЦИНСКОГОСООБЩЕСТВА•КВИЗДЛЯМЕДИЦИНСКОГОСООБЩЕСТВА•
</textPath>
</text>
</svg>
<?= Html::img($info['logo'], ['alt' => $info['alt']]); ?>
</div>
Вот js анимация:
document.querySelectorAll('.circle-text').forEach((svg, i) => {
const path = svg.querySelector(`#circlePath${i}`);
const textPath = svg.querySelector(`#circleTextPath${i}`);
if (!path || !textPath) {
console.warn(`SVG path or textPath not found for index ${i}`);
return;
}
let offset = 0;
let pathLength = 0;
function animate() {
if (!pathLength) {
pathLength = path.getTotalLength();
}
offset += 1; // скорость
if (offset >= pathLength) offset = 0;
textPath.setAttribute('startOffset', offset);
requestAnimationFrame(animate);
}
animate();
});
Вот стили:
.promo__img {
position: relative;
}
.promo__img svg {
position: absolute;
z-index: -1;
/* top: -139px;
left: 900px;
transform: rotate(-23deg); */
top: -131px;
left: 127px;
transform: rotate(-23deg);
}
.circle-text {
width: 100%;
height: 100%;
transform-origin: center;
}
.circle-text text {
font-weight: 400;
font-size: 16px;
line-height: 18px;
text-transform: uppercase;
fill: #0086015C;
}
C помощью JS текст вращается по кругу как мне и нужно, но есть такие пробелы и исчезновение анимации (см.фото), так как он куда-то скрывается, после по новой запускается снова анимация и так циклично.
Как убрать эти прерывания и пробелы?
Должно быть так, без прерываний и пробелов идет вращение текста по кругу (см. второе изображение)
Так же, текст должен вращаться по кругу, как и реализовали тут вращение пунктиров по кругу:
Пример того , что мне нужно сделать с текстом
Ответы (2 шт):
Ну естественно, у вас же path не бесконечный, а вы текст относительно его начала всё сдвигаете и сдвигаете, вот он и уходит вдаль, туда, где path уже закончился. Зачем вам вообще здесь анимация через requestAnimateFrame(), если здесь всё можно через CSS сделать? Единственное, чего я не знаю (я вообще в CSS слабо разбираюсь), так это то, как правильно центр вращения поставить, поэтому я его вычисляю и ставлю через JS. Ну, может подтянутся более сведущие люди, объяснят.
document.querySelectorAll('.circle-text').forEach((svg, i) => {
const path = svg.querySelector(`#circlePath${i}`);
const text = svg.querySelector(`#circleText${i}`);
if (!path || !text) {
console.warn(`SVG path or text not found for index ${i}`);
return;
}
const bbox = path.getBBox();
const cx = bbox.x + bbox.width / 2;
const cy = bbox.y + bbox.height / 2;
text.style.transformOrigin = `${cx}px ${cy}px`;
});
.circle-text text {
animation: roll 10s linear infinite;
font-weight: 400;
font-size: 16px;
line-height: 18px;
text-transform: uppercase;
fill: #0086015C;
}
@keyframes roll {
from { transform: rotate(0); }
to { transform: rotate(360deg); }
}
<svg viewBox="0 0 479 479" class="circle-text">
<defs>
<path id="circlePath0" d="M150,150 m-100,0 a100,100 0 1,1 200,0 a100,100 0 1,1 -200,0" />
</defs>
<text id="circleText0">
<textPath href="#circlePath0">
КВИЗДЛЯМЕДИЦИНСКОГОСООБЩЕСТВА•КВИЗДЛЯМЕДИЦИНСКОГОСООБЩЕСТВА•
</textPath>
</text>
</svg>
Раз у вас круг имеет центр в координатах 150,150 то ViewBox делаем 300*300 Тогда картинка получается в центре svg и крутить можно относительно середины, то есть по 50%. И JS не надо. И шрифт чуть уменьшаем, а то текст по кругу внахлёст идёт.
Саму svg я сделал поменьше, чтоб в сниппет влезла
.circle-text{
width:250px;
}
.circle-text text {
animation: roll 10s linear infinite;
transform-origin: 50% 50%;
font-weight: 400;
font-size: 15.5px;
fill: #0086015C;
}
@keyframes roll {
100% { transform: rotate(360deg); }
}
<svg viewBox="0 0 300 300" class="circle-text">
<defs>
<path id="circlePath0" d="M150,150 m-100,00 a100,100 0 1,1 200,0 a100,100 0 1,1 -200,0" />
</defs>
<text id="circleText0">
<textPath href="#circlePath0">
КВИЗДЛЯМЕДИЦИНСКОГОСООБЩЕСТВА•КВИЗДЛЯМЕДИЦИНСКОГОСООБЩЕСТВА•
</textPath>
</text>
</svg>

