Responsive SVG textpath для передвижения текста
Я пытаюсь обернуть блок новостей (который будет варьироваться по ширине и высоте) с анимированным SVG-текстом вокруг него. У меня получилось вот это:
#canvas{
height: 100vh;
width: 100vw;
}
.svg-container {
display: inline-block;
position: relative;
width: 100%;
padding-bottom: 100%;
vertical-align: middle;
overflow: hidden;
}
<div class="svg-container">
<svg id="canvas" version="1.1" viewBox="0 0 500 500">
<path width="100%" id="curve" fill="none" d="M0,0 h200 a20,20 0 0 1 20,20 v200 a20,20 0 0 1 -20,20 h-200 a20,20 0 0 1 -20,-20 v-200 a20,20 0 0 1 20,-20 z" />
<text font-family="Helvetica" font-size="20" fill="black">
<textPath xlink:href="#curve" startOffset="0%" id="text">Last News</textPath>
<animate xlink:href="#text" attributeName="startOffset" from="0%" to="100%" begin="0s" dur="10s" repeatCount="indefinite"/>
</text>
</svg>
</div>
Это будет дочерний контент:
<div class="lastnews">
<div class="post-grid">
<a class="post-link" href="#">
<div class="post">
<img src="https://via.placeholder.com/768x461.png">
<h2>Some very long long title with too many words</h2>
</div>
</a>
<a class="post-link" href="#">
<div class="post">
<img src="https://via.placeholder.com/768x461.png">
<h2>Some very long long title with too many words</h2>
</div>
</a>
<a class="post-link" href="#">
<div class="post">
<img src="https://via.placeholder.com/768x461.png">
<h2>Short title</h2>
</div>
</a>
<a class="post-link" href="#">
<div class="post">
<img src="https://via.placeholder.com/768x461.png">
<h2>Some very long long title with too many words</h2>
</div>
</a>
<a class="post-link" href="#">
<div class="post">
<img src="https://via.placeholder.com/768x461.png">
<h2>Some very long long title with too many words</h2>
</div>
</a>
<a class="post-link" href="#">
<div class="post">
<img src="https://via.placeholder.com/768x461.png">
<h2>Some very long long title with too many words</h2>
</div>
</a>
<a class="post-link" href="#">
<div class="post">
<img src="https://via.placeholder.com/768x461.png">
<h2>Some very long long title with too many words</h2>
</div>
</a>
<a class="post-link" href="#">
<div class="post">
<img src="https://via.placeholder.com/768x461.png">
<h2>Some very long long title with too many words</h2>
</div>
</a>
</div>
</div>
Я нашел несколько способов сделать svg responsive, но возможно ли сделать svg путь адаптируемым к дочернему контенту div?
вот результат, который я хотел бы получить:
Свободный перевод вопроса Responsive SVG textpath wrapping dynamic content от участника @Juárez.
Ответы (1 шт):
Вот как это сделал бы я: помещаю div с текстом и svg в один родительский блок #wrap с position:relative. А блок .Text-container имеет position: absolute и располагается над элементом svg.
Также .text-container имеет ширину 100%, но height: auto, поскольку содержимое является динамическим.
Вам понадобится размер .text-container, и вы будете использовать его для вычисления нового viewBox элемента svg и нового значения атрибута d #curve - траектории движения.
let txtCont = document.querySelector(".text-container");
// получить размер текстового контейнера
let box = txtCont.getBoundingClientRect()
//установить новый viewBox элемента svg
canvas.setAttributeNS(null,"viewBox",`-50 -30 310 ${box.height}`)
//установить новый атрибут d кривой
curve.setAttributeNS(null,"d", `M0,0 h200 a20,20 0 0 1 20,20 v${box.height - 100} a20,20 0 0 1 -20,20 h-200 a20,20 0 0 1 -20,-20 v-${box.height - 100} a20,20 0 0 1 20,-20 z`)
#wrap {
height: auto;
width: 300px;
margin: 0;
padding: 0;
position: relative;
}
.text-container {
box-sizing: border-box;
padding: 30px 50px;
position: absolute;
width: 100%;
height: auto;
top: 0;
left: 0;
}
#canvas {
border: 1px solid;
margin: 0;
}
<div id="wrap">
<svg id="canvas" viewBox="-50 -30 310 310">
<path width="100%" id="curve" fill="none" stroke="gold" d="" />
<text font-family="Helvetica" font-size="20" fill="black">
<textPath xlink:href="#curve" startOffset="0%" id="text">Last News</textPath>
<animate xlink:href="#text" attributeName="startOffset" from="0%" to="100%" begin="0s" dur="10s" repeatCount="indefinite"/>
</text>
</svg>
<div class="text-container">
<p>I'm trying to wrap a block of news (which will vary on width & height) with an animated SVG textpath around it. I got this so far</p>
</div>
</div>
Пожалуйста, измените текст .text-контейнера, чтобы увидеть изменение анимации.
Свободный перевод ответа Responsive SVG textpath wrapping dynamic content от участника @enxaneta.
