1
votes

I want to display an svg shape on an html page where certain points should have a fixed position.

In the images below, the red circles represent points that should keep their exact position. Beyond the green points, on the left and right side, is where points are not fixed and can scale. How could this be achieved?

I tried various forms of scaling, as well as experimenting with the viewbox and preserveAspectRatio attributes, but none have had the desired effect.

enter image description here enter image description here

EDIT

here is the svg definition. I'm not sure the order of the points, but the top left is 13,-12. I tried changing these to percentages, but doing so in my svg editor, inkscape, deletes the point and several others around it.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="none">
  <path d="m 32.043776,21.922259 c -4.3888,32.42227 33.58333,44.38479 62.94249,61.98573 64.330284,22.939391 72.648644,69.263531 22.383804,131.433121 -25.509995,25.04202 -103.692494,7.65258 -127.798134,-15.30517 -20.8697,-57.14796 -21.34432,-171.108891 -20.66205,-174.861331 8.03521,-44.19367 13,-12 47.82864,-18.5575098 8.45282,0 15.30525,6.8523498 15.30525,15.3051598 z" fill="#f9fdfd"/>
</svg>
3
does it have to scale or could you mask it? My understanding is that you want the center area to remain while the rest is scaled (cut off). Is that correct? - Bryce Howitson
I think it has to scale. The design should look like the top image on mobile, but as it scales to tablet and desktop sizes, it should start to look more like the bottom image - slanden
Do you have the actual image you can share? I have a few ideas but they're all dependent on what's actually being scaled - Bryce Howitson
I tried your solution below, to no avail. I edited my post to include the svg. - slanden

3 Answers

2
votes

I'm not very sure I understand you but, in my opinion in this case I would animate the viewBox attribute and the width.

itr.addEventListener("input",()=>{
  let val = parseInt(itr.value);
  let vb = `${-val} 50 ${2*val} 200`
  let w = 2*val;
  test.setAttributeNS(null,"viewBox",vb)
  test.setAttributeNS(null,"width",w)
})
svg {
  border: 1px solid;
  display: block;
  margin: 1em auto;
}
p {
  text-align: center;
}
<p><input id="itr" type="range" min="100" max="250" value="250" /></p>
<svg id="test" width="500" height="200" viewBox="-250 50 500 200">
<path fill="lightgrey" d="M-250,0C-250,0,-130,35,-91,51C-52,67,-23,78,-1,81C21,84,29,78,34,81C39,84,42,86,43,105C44,124,51,133,43,136C35,139,-30,103,-38,165C-46,227,75,207,127,208C179,209,239,212,257,236C257,266,257,296,257,326C88,326,-81,326,-250,326C-250,217.333,-250,108.667,-250,0z"/>
</svg>
1
votes

It seems that you are looking to slice the svg with preserveAspectRatio.

body {
  margin: 0;
}

#test {
  width: 100%;
  height: 100%;
  position: absolute;
}

.content {
  position: relative;
  padding: 30px;
}
<svg id="test" viewBox="-250 0 500 300" preserveAspectRatio="xMidYMin slice">
<path fill="lightgrey" d="M-250,0C-250,0,-130,35,-91,51C-52,67,-23,78,-1,81C21,84,29,78,34,81C39,84,42,86,43,105C44,124,51,133,43,136C35,139,-30,103,-38,165C-46,227,75,207,127,208C179,209,239,212,257,236C257,266,257,296,257,326C88,326,-81,326,-250,326C-250,217.333,-250,108.667,-250,0z"/>
</svg>
<div class="content">
  <h1>HTML Ipsum Presents</h1>
  <p><strong>Pellentesque habitant morbi tristique</strong> senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. <em>Aenean ultricies mi vitae est.</em>    Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, <code>commodo vitae</code>, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci,
    sagittis tempus lacus enim ac dui. <a href="#">Donec non enim</a> in turpis pulvinar facilisis. Ut felis.</p>
</div>
0
votes

You won't be able to do this very well if the "fixed" areas are in the center. IE if the left points AND right points need to scale. The problem is that fixed points are referenced from the top left.

Fix: SVGs support both percentage based and fixed unit (px) measurements. Simply crack open the SVG code and add/change units where necessary.

Tip: remake the image with a viewbox of 100px x 100px so you have valid values to convert to percents.