0

I am searching for the best way to dynamically change an svg shape based on browser width. Setting the width to 100% stretches the shape to follow the width of the browser, but it also scales or distorts the shape... What I am after: sketch

Is it possible to do this with Javascript or is there a better approach? HTML canvas? thanks!

C.Lamb
  • 1
  • Are you saying that you never want the height of the svg to update, and just have the right side of it stretch to fill the screen? – Spangle Oct 13 '20 at 04:03
  • Essentially yes... the effect I'm after is used on the shape/background of nav bar of the site inholland.nl that site uses HTML canvas to achieve that effect, but I was wondering if there was a easier way... – C.Lamb Oct 13 '20 at 20:09

1 Answers1

0

As you're after an alternative approach involving SVGs, here's one. Unfortunately I wouldn't say it's easier than using a canvas though.

Anyway - to be able to stretch one part of a shape independently from the other we actually need to divide that shape in two. That way the left part can remain static.

If we take a look at the shape you're after:

we can easily see that there's a quarter circle

and a right trapezoid

Constructing them using the drawing commands is rather straight-forward - simply putting those side-by-side won't do the job though.

The trick here is to make the quarter circle a fixed-size - e.g. 80 x 80 pixels - and don't give the trapezoid a size at all. Instead we need to populate the CSS background-image property of a plain <div> element with an URL to the shape. This can be done in-line too. To make it stretch to the browser window, we need to make it's width 100% of the remaining space - which can be done by setting the overflow property of the element to hidden. Now just make the background's height equal to the quarter circle's height and set the background-repeat property to no-repeat.

Now the browser stretches the background image to whatever the remaining width beside the static quarter circle is and the fixed 80 pixels height.

Here's an example:

.svgB {
  overflow: hidden;
  background-image: url("data:image/svg+xml;utf8,<svg viewBox='0 0 5 5' xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='none'><polygon points='0,0 5,0 5,2.5 0,5' style='fill:grey;'/></svg>");
  background-repeat: no-repeat;
  background-size: 100% 80px;
}

.svgB>* {
  color: white;
  padding-left: 5px;
}

.svgA {
  float: left;
  width: 80px;
  height: 80px;
}
<div class="svgA">
  <svg viewBox="0 0 5 5" xmlns="http://www.w3.org/2000/svg">
    <path fill="black" d="M5,5 a5,5 0 0,1 -5,-5 L5,0" />
  </svg>
</div>
<div class="svgB" style="height:80px;">
  <p>Here's some text</p>
</div>
obscure
  • 11,916
  • 2
  • 17
  • 36
  • Thanks for your reply. Yes my next idea was to try something like this with the shape cut into two parts. But I guess I wrote my question poorly... After thinking about it some more I searched 'control svg d attribute via javascript' and that delivered results more like I was thinking...(see: https://stackoverflow.com/questions/31977330/how-to-add-a-path-with-d-attributes-to-a-svg-dynamically) I'm just more familiar with SVG so Was leaning in that direction... – C.Lamb Oct 18 '20 at 22:15
  • Any thoughts as ti with approach might be 'better' svg vs. HTML5 canvas? As this is for a nav bar, there need to be elements, inside (or under) (like the inHolland example...) – C.Lamb Oct 18 '20 at 22:17