Responsive SVG textpath wrapping dynamic content

Viewed 586

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:

 #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>

working animation: https://jsfiddle.net/xebfjL1p/

This would be the child content:

<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>

I've found some ways to make svg responsive, but is it posible to make an svg path adaptable to a div child content?

this is the result I would like to get: enter image description here

thank you in advance

1 Answers

This is how I would do it: I'm putting both the div with the text and the svg in the same parent position:relative. The .text-container have position absolute and lays over the svg element.

Also the .text-container have a width but the height:auto since the content is dynamic.

You will need the size of the .text-container and you'll use this to calculate the new viewBox of the svg element and the new value of the d attribute of the #curve

let txtCont = document.querySelector(".text-container");
// get the size of the text container
let box = txtCont.getBoundingClientRect()

//set the new viewBox of the svg element
canvas.setAttributeNS(null,"viewBox",`-50 -30 310 ${box.height}`)
//set the new d attribute of the curve
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>

Please change the text of the .text-container to see the animation change.

Related