在 Weex 中使用 SVG

weex-svg 介绍

近几年 SVG 逐渐成为前端开发的热门技术。咱们能够在业务场景中构建咱们的图标,以及替代部分位图,随着动画交互的普及,SVG 也成为了你们的选择之一。
今天咱们给你们带来如何在 weex 项目中经过 weex-svg 来实现 SVG 的一些图形信息的展现。html

咱们查阅 weex-svg 的文档,能够了解它目前支持的一些元素和属性有:前端

基本的图形

  • rect 矩形vue

  • circle 圆形android

  • path 路径ios

  • polyline 折线git

  • polygon 几何形github

  • line 直线npm

  • linear-gradient 线性渐变bash

  • radial-gradient 径向渐变weex

通用属性

  • fill 颜色填充

  • stroke 描边的颜色

  • stroke-width 描边的宽度

快速开始

weex-svg 在插件市场已经发布了,咱们能够经过 weex-toolkit 来添加插件。
首先咱们建立一个项目:

weex create svgapp

而后进入建立的项目,添加插件。

cd svgapp && npm install
# 添加 Android 应用模板,你也能够修改成iOS
weex platform add android 
weex plugin add weex-svg

而后咱们编辑src/index.vue 文件,若是没有,就自行建立 index.vue

<template>
  <div class="page">
    <svg style="width:300px;height:300px;">
      <rect x="20" y="20" width="100" height="45" fill="#ea6153"/> 
    </svg>
  </div>
</template

<style>
  .page{
    flex: 1;
  }
</style>

这个时候咱们就能够看到一个简单红色的矩形在界面上。接下来,咱们修改 index.vue,添加一些复杂的图形

<template>
  <div class="page">
    <scroller class="main">
      <div class="item">
        <svg style="width:300px;height:300px"
           viewBox="0 0 300 300">
          <path d="M155.3,39.7c26.9,1.1,51.2,11.9,69.7,29l0,0c-18.5,20.2-30.2,46.8-31.4,76.1h-38.3C155.3,144.7,155.3,39.7,155.3,39.7z
           M145.7,39.7v105.1h-38.3c-1.2-29.3-12.8-55.9-31.4-76.1l0,0C94.5,51.6,118.9,40.8,145.7,39.7z M155.3,259.3V154.3h38.3
          c1.2,29.3,12.8,55.9,31.4,76.1l0,0C206.5,247.4,182.1,258.2,155.3,259.3z M145.7,259.3c-26.9-1.1-51.2-11.9-69.7-29
          c18.5-20.2,30.2-46.8,31.4-76.1h38.3C145.7,154.3,145.7,259.3,145.7,259.3z M231.8,75.4c16.8,18.4,27.4,42.6,28.6,69.3l0,0h-57.2
          C204.3,118.1,214.9,93.9,231.8,75.4L231.8,75.4L231.8,75.4L231.8,75.4z M231.8,223.6L231.8,223.6L231.8,223.6
          c-16.8-18.4-27.4-42.6-28.6-69.3h57.2C259.2,180.9,248.6,205.1,231.8,223.6L231.8,223.6z M40.7,144.7c1.1-26.6,11.8-50.8,28.6-69.3
          l0,0c16.8,18.4,27.4,42.6,28.6,69.3H40.7L40.7,144.7z M40.7,154.3h57.2c-1.1,26.6-11.8,50.8-28.6,69.3
          C52.4,205.1,41.8,180.9,40.7,154.3L40.7,154.3z M150.5,269c66,0,119.5-53.5,119.5-119.5S216.5,30,150.5,30S31,83.5,31,149.5
          S84.5,269,150.5,269L150.5,269z" fill="#000000"/>
        </svg>
        <svg style="width:120px; height:120px;" viewBox="0 0 120 120">
          <path fill="#f1c40f"  d="M29.2,31.2V10h61.5L69.6,31.2l21.2,21.2H33.1V110h-3.8V31.2z M33.1,13.8v34.6h48.1L63.8,31.2l17.3-17.3H33.1z" />
        </svg>
      </div>
      
    </scroller>
    
  </div>
   
</template>

<style>
  .page{
    flex: 1;
    padding-top: 20px;
    background-color: #fff;
  }
  .main{
    padding-top: 88px;
  }
  .desc{
    margin: 20px;
    font-size: 28px;
    text-align: left;
    color: #444;
  }
  .item{
    align-items: center;
    margin: 20px;
    padding: 10px;
    border-bottom: 2px solid #ddd;
  }
</style>

预览效果:

vuedf348778b4712be475850bc37095b0f17.png

组件使用

Weex-svg 目前已经对 rectcirclepathpolylinepolygonlinear-gradientradial-gradient 的支持,考虑在下一版本继续完善,所以在使用的时候,目前只能解析上面的那些元素。

rect

绘制矩形,你能够经过 xy 来设置矩形的起点,你能够经过 widthheight 来设置矩形的大小,你能够经过fill 和 stroke 来进行填充和描边。

<svg style="width:300px;height:300px;">
  <rect x="20" y="20" width="160" height="160" fill="#f39c12"/> 
</svg>

vued1d57e449aba15c3fe8778f7a05541825.png

circle

绘制圆形, 其中 cxcy 表示圆心, r 表示半径。

<svg style="width:300px;height:300px;">
  <circle cx="150" cy="50" r="45" fill="none" stroke-width="2" stroke="#ea6153"/>
</svg>

vued385a377a46e040ab275773d538c88e82.png

line

你能够经过 line 标签来进行直线的绘制,其中 x1y1 表示起点,x2y2 表示终点。

<svg style="width:300px;height:300px;">
  <line x1="10" y1="70" x2="120" y2="70" stroke="#ea6153" stroke-width="2" />
  <line x1="70" y1="10" x2="70" y2="120" stroke="#ea6153" stroke-width="2" />
</svg>

vued7f0da5c30bde89cf80d0cabf475529c1.png

polyline

绘制折线,你能够经过points 来进行路径设置,每一组数据的坐标由逗号分隔。

<svg style="width:300px;height:300px;">
  <polyline points="0,0 100,0 100,100" fill="#ea6153"></polyline>            
</svg>

vued63089137ee5fe4ad7f8698ef29eb0cc0.png

path

你可使用 path 来定义任何形状,不管是直线仍是曲线, path 也是 svg 中最强大的工具。你能够经过 d 命令来进行设置, 它能够绘制直线,曲线,以及复杂的贝塞尔曲线。 你能够 阅读MDN -D 来了解它的具体使用。通常状况下,比较复杂的 SVG 图形,咱们都是经过第三方工具来完成的好比 Adobe Illustrator 来进行适量图形的制做。

<svg style="width:300px;height:300px;">
  <path d="M50,50 A50,50 0 0,1 150,80" stroke="#e84c3d" fill="none" />           
</svg>

vued574ca3cc6d13119caf55684e983ca521.png

fill

fill 主要用于填充不一样的颜色。

<svg style="width:300px;height:300px;">
  <circle cx="50" cy="50" r="45" style="fill:#ea6153;"/>
  <circle cx="100" cy="50" r="45" style="fill:#9b59b6;"/> 
  <circle cx="150" cy="50" r="45" style="fill:#2ecc71;"/>  
</svg>

vued3d31af635b3a2a5873822e0e8ba372c8.png

stroke

而 stroke 主要用于设置描边的颜色,而描边的宽度能够经过 stroke-width来设置。

<svg style="width:300px;height:300px;">
  <circle cx="50" cy="50" r="20" fill="none" stroke="#ea6153"/>
  <circle cx="100" cy="50" r="20" fill="none" stroke="#9b59b6"/> 
  <circle cx="150" cy="50" r="20" fill="none" stroke="#2ecc71" stroke-width="2"/>  
</svg>

vuedf4145cf4cbf4835001b4de2fb63520d4.png

使用场景对比

SVG 是矢量图形,相对于位图,它很好地解决多机型分辨率的问题。而咱们在Android开发的时候,咱们须要生成多套资源文件(Android下咱们会在hdpi,xhdpi,xxhdpi等目录存放图片资源),去克服不一样分辨率下图片可能失真的状况。咱们能够模拟这种效果,可能一个图片在 hdpi 下的用户感知图片效果参考下图上面的图标,而将它放到 xxhdpi 的分辨率下,图片就会出现一些锯齿,很是影响用户体验,而 SVG 则能够避免这种状况。(下图为测试为设置大小为都为300px,SVG 和 PNG 的对比)

vued86494f38e7981e6335a7c8701e545b47.png

咱们能够感知到下面图标在高分辨率的状况下有些模糊。 咱们经常使用的svg的场景,主要就是图标的显示和一些动画的使用。对于一些复杂的图形,首先咱们的工具不必定能够导出SVG ,第二 SVG 导出的体积可能会比优化后的位图还大。而小图标对于设计师而言,他们能够方便的导出 SVG 代码,相对而言,SVG 的代码可读性强,有利于工程师进行代码使用和编辑。

这里咱们作了一个测试,分别用使用 SVG 和 PNG 去制做一个带有 ICON 的底部导航条,预览效果以下:

vued33c84e67a635fc0fcb60551718ecf4d7.png

这个是前后扫码 PNG 和 SVG 文件的演示视频:

演示视频

在这个视频中咱们能够看到扫码 PNG 的测试文件后,能够感受到底部是由白色而后显示出图标这样的效果。而第二次扫码 SVG的测试文件则不会存在这种感受。

透过 weex debug 的功能咱们能够查看手机(测试机型 HUAWEI Honor7) 的 log 信息,了解到咱们渲染的时间。下面咱们经过一组简单的测试来看下渲染时间对比:

单位(ms) JS Bundle Networking Time Render Time Resource Networking Time
SVG 67 179 0
PNG 46 122 233

vueda5d14964721eea36db2495a43a17325f.png

接下来咱们测试比较复杂的图形,显示效果以下:

vuedd02a90b42ccb56d270a4d7c55cf5093f.png

文件源码

渲染时间对比:

单位(ms) JS Bundle Networking Time Render Time Resource Networking Time
SVG 47 235 0
PNG 29 119 798

vuedce5e5f5cdb29538f21f5ebb94cf2fed3.png

从图中咱们能够直观的看到,SVG 的优势在于节省了资源的请求,在 render 上时间则不占优点,缘由在于咱们须要花时间去进行DOM的解析而后按照命令去进行图形的绘制。
使用 weex compile 进行文件的编译后文件大小对好比图:

vued5bccb21cf015853ae62c1b790dba285a.png

由此也发现了使用 SVG 一些须要注意的点,好比咱们的 JS Bundle 的文件会相对增大。所以也不太建议特别复杂的图形使用 SVG 去进行绘制,这会形成性能的开销。

不过对于动态类数据的图形展现,咱们也但是尝试使用SVG,好比咱们前端常用的 d3.js ,它能够生成不少漂亮的图表,而咱们能够利用 D3 这个 JS 库,经过一些 hack 技巧,结合咱们的 weex-svg ,在手机上展现一些漂亮的图标,手机运行的截图以下:

vued2ede28df2537bc6e9b81302487e730e7.png

使用项目 Demo

Demo 里面包含了目前所支持的特性的的案例。你只须要

git clone https://github.com/weex-plugins/weex-svg.git

而后进行项目的 demo文件拷贝到 你建立的项目 src 目录下, 运行 weex run android 或者 weex run ios 便可。

视频演示

小结

本文只是粗浅的介绍了 weex-svg 的基本用法,咱们能够尝试在咱们的 weex 项目中引进 svg ,它能够帮助咱们去完成一些图标的展现和基本图形的页面展现,它还能够实现一些简单的图形动画。固然在实际使用过程当中,你有事吗想法和建议也能够反馈到 项目issue ,从而帮助开发者进一步完善。

扩展阅读

原文同步: http://www.jackpu.com/weex-sv...