svg入门 第一节

目录

什么是SVG?

viewport和viewBox

preserveAspectRatio

Mid,Min,Max

meet,slice

demo案例


什么是SVG?

  • SVG 指可伸缩矢量图形 (Scalable Vector Graphics)
  • SVG 用来定义用于网络的基于矢量的图形
  • SVG 使用 XML 格式定义图形
  • SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
  • SVG 是万维网联盟的标准
  • SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体
     

viewport和viewBox

学好svg需要先了解svg中的viewport和viewBox这两个概念。

  • viewpart是整个svg的可见区域即svg标签的宽高。
  • viewBox是svg在绘图过程中使用的坐标系,viewBox存在于viewPort中。可以通过viewBox属性设置viewBox的大小和在viewPort中的相对位置。如:下面的标签表是svg画布的大小为200px*200px,view Box位于viewpart坐标中的(0, 0)位置并且大小为100*100。
<svg width='200px' height='200px' viewBox='0 0 100 100'></svg>

 

preserveAspectRatio

svg除了viewport和viewBox外还有一个比较重要的参数preserveAspectRatio主要是用在viewport和viewBox宽高比不一致的情况,宽高比会影响svg的渲染。
默认情况下preserveAspectRatio="xMidYMid meet"表示viewBox位于viewport的中心位置,并且采用viewport和viewBox最小的宽高比。

Mid,Min,Max

对于x轴Mid表示viewBox位于viewport横向位置的中间,Min表示位于viewport的最左边,Max表示位于viewport的最右边
对于y轴Mid表示viewBox位于viewport横向位置的中间,Min表示位于viewport的最上边,Max表示位于viewport的最下边

meet,slice

meet代表选择viewport和viewBox宽高比例较小的一个图形可以按照比例缩小显示。
slice代表选择viewport和viewBox宽高比例较大的一个这可能会造成svg图形过大最终超出viewport图形被裁切。

demo案例

在了解完preserveAspectRatio和viewBox、viewport后基本上对svg的布局就可以大致理解svg的布局原理了,下面是几个demo
svg.vue

<template>
  <div>
    <svg
      width="100"
      height="100"
      style="display: none"
      viewBox="0 0 100 100"
      preserveAspectRatio="xMidYMid meet"
    >
      <defs>
        <g id='more'>
          <line x1='40' y1='25' x2='90' y2='25' stroke-width='8' stroke='currentColor'></line>
          <line x1='40' y1='50' x2='80' y2='50' stroke-width='8' stroke='currentColor'></line>
          <line x1='40' y1='75' x2='90' y2='75' stroke-width='8' stroke='currentColor'></line>
          <circle r='5' cx='20' cy='25' fill='currentColor'></circle>
          <circle r='5' cx='20' cy='50' fill='currentColor'></circle>
          <circle r='5' cx='20' cy='75' fill='currentColor'></circle>
        </g>
        <symbol id='more1' viewBox='0 0 100 100'>
          <line x1='40' y1='25' x2='90' y2='25' stroke-width='8' stroke='currentColor'></line>
          <line x1='40' y1='50' x2='80' y2='50' stroke-width='8' stroke='currentColor'></line>
          <line x1='40' y1='75' x2='90' y2='75' stroke-width='8' stroke='currentColor'></line>
          <circle r='5' cx='20' cy='25' fill='currentColor'></circle>
          <circle r='5' cx='20' cy='50' fill='currentColor'></circle>
          <circle r='5' cx='20' cy='75' fill='currentColor'></circle>
        </symbol>
        <symbol id='filledArrowRight' viewBox='0 0 100 100'>
          <polyline points='20 10, 80 50, 20 90' fill='currentColor'></polyline>
        </symbol>
        <symbol id='arrowRight' viewBox='0 0 100 100'>
          <polyline points='20 10, 60 50, 20 90' fill='transparent' stroke-width='8' stroke='currentColor'></polyline>
        </symbol>
        <linearGradient id='linearGradient'>
            <stop offset='0' stopColor='red'></stop>
            <stop offset='50%' stopColor='green' stopOpacity='0.5'></stop>
            <stop offset='100%' stopColor='blue'></stop>
        </linearGradient>
        <radialGradient r='50%' cx='50%' cy='50%' fx='50%' fy='50%' id='radialGradient'>
            <stop offset='0' stopColor='red'></stop>
            <stop offset='50%' stopColor='green' stopOpacity='0.5'></stop>
            <stop offset='100%' stopColor='blue'></stop>
        </radialGradient>
        <symbol id='linearGradientBox' viewBox='0 0 100 100'>
            <rect x='0' y='0' height='100' width='100' fill='url(#radialGradient)'></rect>
        </symbol>
      </defs>
    </svg>
    <span :style="{color: 'green'}">
      <svg width='100' height='100' viewBox='0 0 100 100'>
        <use href='#more'></use>
      </svg>
      <Icon :style="{width: 100, height: 100, color: 'red'}" :svgId="'more1'" />
      <Icon :style="{width: 100, height: 100, color: 'blue'}" :svgId="'arrowRight'" />
      <Icon :style="{width: 100, height: 100, color: 'yellow'}" :svgId="'filledArrowRight'" />
      <Icon style={{width: 100, height: 100}} svgId='linearGradientBox' />
    </span>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import Icon from '@src/components/icon.vue'

export default defineComponent({
  name: "SVG",
  components: {
    Icon
  },
  setup: () => {
    return {};
  },
});
</script>

<style scoped>
</style>

icon.vue

<template>
  <svg :style="style">
    <use :href="`#${svgId}`"></use>
  </svg>
</template>

<script lang="ts">
import { defineComponent } from "vue";

export default defineComponent({
  name: "icon",
  props: {
    svgId: {
      type: String,
      required: true,
    },
    style: {
      type: CSSStyleDeclaration, // CSSStyleDeclaration
      require: false
    }
  }
});
</script>

demo中用到了几个比较常用的svg基本图形
  line线
  rect矩形
  circle圆型
  defs可以将写好的svg组件隐藏起来
    g可以设置id属性即这是一个svg组合可以直接显示symbol不能直接显示
    symbol和g类似但是可以传递viewBox属性这样在使用的时候就不用再写viewbox去适应图标(实现的原理就是在套一层svg标签)
  use可以使用定义好的svg组合(通过href='#id'使用)
  polyline多边形
path
    d属性
      M为开始Z为结束,没有Z的话路径就不回闭合。L10 10表示点坐标(10, 10)
mask蒙版类似ps的蒙版可以混合颜色 
linearGradient渐变色
  通过fill='url(#linearGradient)'的方式设置
  stop
    需要连续多个stop标签,有offset='50%'位置、stop-color='red'对应的颜色、stop-opacity='0.5'透明度
radialGradient
  放射性渐变属性同linearGradient
   r='50%'辐射半径 cx='50%'外圈辐射 cy='50%'外圈辐射 fx='50%'内圈辐射 fy='50%'内圈辐射,默认都是50%
几个值的注意的地方
  1.对线来说填充颜色不能用fill来填充需要用stroke来填充颜色,并且如果将颜色设置成currentColor即为继承父元素的颜色(css中的color属性)
  2.当我们自己想要写svg样式库的时候可以使用defs将svg库隐藏起来但是这里仍然会占用文档流的位置,可以将display:none将其隐藏掉
  3.封装svg图形的时候尽量使用symbol代替g(这也是iconfont建议的),因为为了在使用编辑好的svg图标时g标签还要额外去写viewBox去适应图标的缩放大小而symbol可以直接设置viewBox,这样我们使用封装好的svg组合时就可以直接通过组合的id使用图标并且保证图标的正常显示。
  4.viewport是可以继承父元素的宽高的只要将svg标签的width和height设置成100%即可

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值