简介svg的核心能力——矢量缩放

大家都知道svg图像之所以能被随意拉伸且保持不失真,主要原因是它能进行矢量缩放,而这种特性主要取决于两个属性,即viewBox和preserveAspectRatio。这  篇文章就svg的这两个属性进行简要讲解。

1、viewBox

viewBox定义了svg中的内容可画的区域(相当于放在视口底下的一块画布),它的语法是:

viewBox = "<min-x> <min-y> <width> <height>"

其中min-x和min-y代表绘画区域的左上角坐标,width和height代表绘画区域的宽高。

视口指的是svg的实际可见区域,它的大小是由svg元素的width和height两个属性来决定的。注意width、height属性与viewBox值中对应成分的区别,viewBox的值中的成分只表示svg中的内容的理论可画区域的大小,即一块假想画布的大小;这块画布在作完画后会放到svg的实际可见区域(即视口)中,并且会根据另一个属性preserveApsectRatio进行缩放以及放到视口的正确位置,这在之后的内容中会提到。当然,有时候svg元素上不会设置width和height属性,此时svg的实际尺寸应当由包裹它的外部元素来确定;也可能不设置viewBox属性,此时该属 性的值中min-xmin-y都为0,width、height等于svg元素的实际width、height。

viewBox是一个通用属性,可以在以下元素中使用:

  • <marker>
  • <pattern>
  • <svg>
  • <symbol>
  • <view>

接下来的例子为了方便就以<svg>元素为例(这些案例的preserveAspectRatio都为默认值):

①先来看显示设置svg宽高的情况:

    <div style="
     width: 240px;
     height: 100px;
     background-color: rgb(127,255,212);
    ">
      <svg viewBox="0 0 50 50" 
        width="80" height="80" 
        xmlns="http://www.w3.org/2000/svg" 
        style="float: left;border: 1px dashed gray;margin-right: 10px;"
      >
        <circle cx="50%" cy="50%" r="10" fill="red"></circle>
      </svg>
      <svg viewBox="-10 -10 60 80" 
        width="120" height="160" 
        xmlns="http://www.w3.org/2000/svg" 
        style="float: left;border: 1px dashed gray;"
      >
        <circle cx="20" cy="30" r="20" fill="gold"></circle>
      </svg>
    </div>

 

第一个svg的宽高被设置为80、80,其viewBox被设置为"0 0 50 50",它们的宽高比都为1 : 1,这意味着viewBox定义的区域经缩放会完全拟合(区域的四个角与视口重合)到视口中,不受preserveAspectRatio的影响。容易得出viewBox的缩放率为1.6,并且与视口左上角重合的viewBox左上角的坐标为(0, 0)。在svg中画了一个圆,圆心坐标使用的是百分比值,它表示viewBox中定义的宽或高的百分比,当然,在视口中实际呈现时还要乘上缩放率。这个例子上的圆心坐标在viewBox中即为cx=50*50%=25、cy=50*50%=25。

第二个svg的宽高被设置为120、160,其viewBox被设置为"-10 -10 60 80",它们的宽高比同样都为1 : 1,意味着viewBox的缩放不受preserveAspectRatio的影响。此时,viewBox定义区域的左上角为坐标系的(-10, -10)点,x轴和y轴的长度分别为60、80,viewBox在视口中的缩放率为2。viewBox中的圆其圆心坐标为(20, 30),注意在这里设置坐标为(30, 40)则无法居中,因为左上角的坐标为(-10, -10)而不是(0, 0);再根据坐标系宽高,其右下角的坐标应该为(50, 70)而不是(60, 80)。这个svg的实际视口高度超过了外部div元素的高度但还是完整地显示了出来,要把超出部分隐藏掉可以在div元素上设置css属性overflow: hidden。

②第二种情况,不设置宽高:

    <div style="
      width: 80px;
      height: 80px;
      border: 1px dashed gray;
    ">
      <svg viewBox="-10 -10 40 60" 
        xmlns="http://www.w3.org/2000/svg"
        style="background-color: rgba(128, 254, 195, 0.4);" 
      >
        <rect x="0" y="5" width="20" height="35" fill="burlywood"></rect>
      </svg>
    </div>

 

这幅图中的svg未设置width和height,只设置了viewBox为"-10 -10 40 60",在其外部有一个宽高分别为80、80的div元素(用虚线框包裹)。可以看到,在未显式设置宽高时,svg视口的宽度取决于外部元素的宽度,宽高比与viewBox的一致(在这里是40 : 60 = 2 : 3)。viewBox经过缩放,它的宽紧随视口的变化,被缩放到与外部div的宽同样大小(在这里是放大80/40=2倍),且宽高比保持不变。

2、preserveAspectRatio

该属性表示当svg元素中viewBox定义区域的宽高比与视口的宽高比不同时,viewBox定义区域拟合到视口中的方式。该属性的语法为:

preserveAspectRatio = "<align> [<meetOrSlice>] "

它包含两个成分,align表示当viewBox的宽高比不匹配视口的实际宽高比时的对齐方式,它有10个可能值:

  • none:对viewBox进行不规则缩放,使其边界矩形完全充满整个视口。设置该值时对<meetOrSlice>的设置无效。
  • xMinYMin:对viewBox进行规则缩放,把viewBox的<min-x>与视口的最小x值对齐,把viewBox的<min-y>与视口的最小y值对齐。这相当于把viewBox的左上角与视口的左上角对齐。
  • xMidYMin:对viewBox进行规则缩放,把viewBox的中点x值与视口的中点x值对齐,把viewBox的<min-y>与视口的最小y值对齐。这相当于viewBox在视口的顶部居中。
  • xMaxYMin:对viewBox进行规则缩放,把viewBox的<min-x>+<width>值与视口的最大x值对齐,把vie
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值