【问题标题】:SVG translate to bottom edge in pixel unitsSVG 以像素为单位转换为底边
【发布时间】:2021-02-10 19:03:48
【问题描述】:

我们的目标是制作一个 SVG 形状,它的容器垂直大小,但在顶部和底部边缘具有像素完美的多边形。看起来像这样的东西:

无论容器在垂直方向上有多大,顶部和底部的三角形都应保持相同大小(8 像素高)。从概念上讲,我想要的是一个 100% 高的实心矩形,以及用于切掉 4 个角的白色小三角形。理想情况下是这样的:

    <div style="position:relative;padding-left:20px;width:200px;border:1px solid black;">
            <svg  style="position:absolute;top:0;left:0;height:100%;width:16px;">
                <rect x="0" y="0" width="16" height="100%" style="fill:green"/>
                <polygon points="0,0 8,0 0,8"   style="fill:white"/>
                <polygon points="8,0 16,0 16,8" style="fill:white"/> 
                <polygon points="0,0 8,0 0,-8"   style="fill:white" transform="translate(0, 100%)"/>
                <polygon points="8,0 16,0 16,-8" style="fill:white" transform="translate(0, 100%)"/> 
            </svg>
            This is the<br>div content<br>of some random<br>vertical size.
    </div>

但这当然行不通,因为您不能在 translate() 中使用百分比值。显而易见的解决方案是一个 100 单位高的 viewBox:

<div style="position:relative;padding-left:20px;width:200px;border:1px solid black;">
        <svg  style="position:absolute;top:0;left:0;height:100%;width:16px;" viewBox="0 0 16 100" preserveAspectRatio="none">
            <rect x="0" y="0" width="16" height="100%" style="fill:green"/>
            <polygon points="0,0 8,0 0,8"   style="fill:white"/>
            <polygon points="8,0 16,0 16,8" style="fill:white"/> 
            <polygon points="0,0 8,0 0,-8"   style="fill:white" transform="translate(0, 100)"/>
            <polygon points="8,0 16,0 16,-8" style="fill:white" transform="translate(0, 100)"/> 
        </svg>
        This is the<br>div content<br>of some random<br><br><br><br><br><br><br><br><br>vertical size.
</div>

结果是正常的,但现在所有的多边形点都被垂直缩放,导致容器变大时顶部和底部的三角形会拉伸:

如何让顶部/底部三角形多边形保持(准确)8 像素高,同时允许整体尺寸垂直拉伸?如果有一种方法可以在没有 viewBox 的情况下转换到底部边缘(保留浏览器的像素单位),那么第一个代码 sn-p 就可以了。

【问题讨论】:

  • 每次容器使用 javascript 拉伸时,您都需要重新计算多边形

标签: svg


【解决方案1】:

方法一、嵌套&lt;svg&gt;s

可以在另一个&lt;svg&gt; 元素中包含一个&lt;svg&gt; 元素,因此您可以将底部的两个矩形放在它们自己的&lt;svg&gt; 和它们自己的viewBox 中,如下所示:

            <svg preserveAspectRatio="xMidYMax meet" viewBox="0 -0.1 16 0.1">
                    <polygon points="0,0 8,0 0,-8"   style="fill:white"/>
                    <polygon points="8,0 16,0 16,-8" style="fill:white"/> 
            </svg>

包含底部三角形的 viewBox 将放置在视口底部的中心 (xMidYMax) 并将尽可能地缩放以适应视口 (meet)。由于 viewBox 只有 0.1 个单位高,它几乎不能超过被缩放的视口的高度,所以它会以它的宽度为界。更多关于preserveAspectRatiohere

方法 2. CSS 转换

与 svg 转换不同,CSS 转换允许使用百分比,因此您可以使用 style="transform:translateY(100%);" 代替 transform="translate(0, 100)",但是,您需要给您的 &lt;svg&gt; 一个合适的 viewBox,同样非常低高度。这是因为如果 viewBox 高于容器,则三角形最终会在 viewBox 的底部,在容器底部下方。

参见代码sn-p中的示例:

<style>
div {position:relative;padding-left:20px;width:130px;height:100px;border:1px solid black;resize:vertical;overflow:auto;float:left;}
svg {position:absolute;top:0;left:0;height:100%;width:16px;}
</style>
These 4 methods all work as static but only the left 2 work if the height changes.<br>
The &lt;div&gt;s are resizable, so you can see for yourself. 
<br>
<div>
        <svg>
        <rect x="0" y="0" width="16" height="100%" style="fill:green"/>
            <polygon points="0,0 8,0 0,8"   style="fill:white"/>
            <polygon points="8,0 16,0 16,8" style="fill:white"/>
        <svg preserveAspectRatio="xMidYMax meet" viewBox="0 -0.1 16 0.1">
                <polygon points="0,0 8,0 0,-8"   style="fill:white"/>
                <polygon points="8,0 16,0 16,-8" style="fill:white"/> 
        </svg>
        </svg>
        <span style="color:green">nested &lt;svg&gt;s</span>
</div>

<div>
        <svg viewBox="0 0 16 0.1" preserveAspectRatio="xMidYMin slice">
        <rect x="0" y="0" width="16" height="100%" style="fill:green"/>
            <polygon points="0,0 8,0 0,8"   style="fill:white"/>
            <polygon points="8,0 16,0 16,8" style="fill:white"/> 
            <polygon points="0,0 8,0 0,-8"   style="fill:white;transform:translateY(100%);"/>
            <polygon points="8,0 16,0 16,-8" style="fill:white;transform:translateY(100%);"/> 
        </svg>
    <span style="color:green">CSS transforms,<br>viewBox height 0.1</span>
</div>

<div>
        <svg viewBox="0 0 16 100" preserveAspectRatio="xMidYMin slice">
        <rect x="0" y="0" width="16" height="100%" style="fill:green"/>
            <polygon points="0,0 8,0 0,8"   style="fill:white"/>
            <polygon points="8,0 16,0 16,8" style="fill:white"/> 
            <polygon points="0,0 8,0 0,-8"   style="fill:white;transform:translateY(100%);"/>
            <polygon points="8,0 16,0 16,-8" style="fill:white;transform:translateY(100%);"/> 
        </svg>
    <span style="color:red">CSS transforms,<br>viewBox height 100</span>
</div>

<div>
        <svg>
        <rect x="0" y="0" width="16" height="100%" style="fill:green"/>
            <polygon points="0,0 8,0 0,8"   style="fill:white"/>
            <polygon points="8,0 16,0 16,8" style="fill:white"/> 
            <polygon points="0,0 8,0 0,-8"   style="fill:white;transform:translateY(100%);"/>
            <polygon points="8,0 16,0 16,-8" style="fill:white;transform:translateY(100%);"/> 
        </svg>
    <span style="color:red">CSS transforms<br>without viewBox</span><br>Chrome and Firefox<br>behave differently!
</div>

【讨论】:

    猜你喜欢
    • 2012-08-25
    • 2011-12-06
    • 2014-05-13
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 2014-10-12
    • 2012-08-19
    相关资源
    最近更新 更多