Benoit
Benoit

Reputation: 21

Transform SVG shapes from Viewbox Space to Space of Source Background Image Dimensions

I have a series of SVG documents. Each document consists of an <image> which is the background. Against this background are rendered a number of shapes, either <rect>, <polygon>, or <path>. The shapes are rendered within a viewBox whose dimensions are the scale of the <image> source by a factor of 0.24. The <image>, thus, has a transform attribute with a value of scale(0.24).

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2881.44 209.28">
<title>14-23</title>
<style type="text/css"><![CDATA[
  .shape {
    fill: none;
    pointer-events: visible;
  }
]]></style>
<image width="12006" height="872" transform="scale(0.24)" xlink:href="14-23.png"/>
<g id="_x31_000_East_Ohio_St_Year_Built:_196_x2A_-1968">
    <rect x="144.5" y="180.3" class="shape" width="44.3" height="15"/>
</g>
...
</svg>

Now, what I would like to do is transform the vertices of each shape from the coordinate space of the viewbox to a new coordinate space which bears the dimensions of the image source. My goal is to render the source image as the background-image of a div that bears the source image dimensions, scale the div to fit an abitrary viewport while keeping the aspect ratio, then render the shapes against that fitted scale of the X- and Y-axis.

My first thought is to run each vertex through a scale transform by a factor of 1.76, or, as I think, the current scale plus the difference between the transformed image scale and 1. This does not give me the desired output however. Could anyone clarify where I'm going wrong?

Upvotes: 2

Views: 44

Answers (1)

ccprog
ccprog

Reputation: 21856

You can achieve your goal without computing the factors yourself, simply describe them and let the renderer do the transformations for you.

Thw container <div> gets the background image such that it fits inside at the largest possible size, without loosing the aspect ratio, and it gets positioned in the middle.

The same can be done for the <svg> element by defining it its width and height as 100% of the container. The viewbox gets scaled into that space following the same rules as the backgrounf image, just written down with a slightly different syntax. (The quoted value for preserveAspectRatio is the default, you can leave it off):

<style type="text/css">
  #container {
    background-image: url(14-23.png);
    background-size: contain;
    background-position: center;
  }
  .shape {
    fill: none;
    pointer-events: visible;
  }
</style>
<div id="container">
  <svg xmlns="http://www.w3.org/2000/svg"
       width="100%" height="100%" viewBox="0 0 2881.44 209.28"
       preserveAspectRatio="xMidYMid meet">
    <g id="_x31_000_East_Ohio_St_Year_Built:_196_x2A_-1968">
      <rect x="144.5" y="180.3" class="shape" width="44.3" height="15"/>
    </g>
    ...
  </svg>
</div>

All that still needs to be done now is to describe the size of the container div.

Upvotes: 0

Related Questions