serveAspectRatio =“ xMinYMax slice”不会将SVG带到Viewbox的底部

时间:2018-07-12 18:20:03

标签: svg vue.js

尝试使用Vue制作具有动态更改svg为条形图的条形图,但preserveAspectRatio并未将它们设置为我为其分配的css Grid列的底部。仅显示剩余的列剩余部分。与覆盖svg Viewbox值的动态变量是否存在冲突?我只是傻吗?

                                                   
      <div class="openedBar">
        <svg width="36px" height="200px" viewbox="0 0 36 200" preserveAspectRatio="xMidYMax slice">
          <rect v-bind:height="svgHeights.openedBar * 2 + 'px'" width="36px"></rect>
        </svg>
      </div>
      <div class="linkClicksBar">
        <svg width="36px" height="200px" viewbox="0 0 36 200" preserveAspectRatio="xMidYMax slice">
          <rect v-bind:height="svgHeights.linksBar * 2 + 'px'" width="36px"></rect>
        </svg>
      </div>

1 个答案:

答案 0 :(得分:0)

原始代码中有多个问题

viewBox拼写错误

区分大小写对于html无关紧要,但对svg规范很重要。对于Vue的创建者来说,这甚至是一个陷阱,因为Vue在使用html模板时会犯错(您可能不使用它们,但是让我措手不及试图复制它)

应将其拼写为viewBox(注意大写B)

preserveAspectRatio应该设置为meet而不是slice

您的preserveAspectRatio告诉代码将图像中多余的部分剪掉,而不是尝试将其适合页面底部(我不得不说,有关此问题的MDN文章确实使他们的示例感到困惑)

preserveAspectRatio影响viewBox,而不是页面的绘制部分

由于viewBox的大小为36 x 200像素,因此它将完全位于大小完全相同的svg的中心。

您可以通过动态更改视图框的大小来解决此问题,以确保内容始终位于您期望的位置。

var app = new Vue({
  el: '#app',
  template: '#app-template',
  data: {
    svgHeights: {
        linksBar: 10
    }
  }
})
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- Require an script tag for the vue content here for the case sensitivity issue of the svg viewBox attribute -->
<script type="test/plain" id="app-template">
    <div class="linkClicksBar" >
        <input type=number v-model="svgHeights.linksBar">
        <svg
            width="36px"
            height="200px"
            :viewBox="`0 0 36 ${svgHeights.linksBar * 2}`"
            preserveAspectRatio="xMidYMax meet"
        >
            <rect v-bind:height="svgHeights.linksBar * 2 + 'px'" width="36px"></rect>
        </svg>
    </div>
</script>

<div id="app">
</div>

使其变得不那么复杂

虽然这一切看起来都很复杂,但是有一个甚至更简单的解决方案,可以解决问题,并且可以使用 ab ,而svg会自动裁剪在底部。使用此方法,我们可以制作100%高的rect,并根据需要在其上更改其y属性

var app = new Vue({
  el: '#app',
  template: '#app-template',
  data: {
    svgHeights: {
        linksBar: 10
    }
  }
})
<!-- development version, includes helpful console warnings -->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- Require an script tag for the vue content here for the case sensitivity issue of the svg viewBox attribute -->
<script type="test/plain" id="app-template">
    <div class="linkClicksBar" >
        <input type=number v-model="svgHeights.linksBar">
        <svg
            width="36px"
            height="200px"
            viewBox="0 0 100 100"
            preserveAspectRatio="none"
        >
            <rect :y="100 - svgHeights.linksBar" height="100" width="100"></rect>
        </svg>
    </div>
</script>

<div id="app">
</div>