您的位置:首页 > 编程语言 > Go语言

026-使用 go 输出 svg 图形

2018-03-04 01:00 260 查看
SVG 是使用 XML 来描述二维图形和绘图程序的语言。

部分同学可能都没听说过 svg。你可以简单的理解为它是一种图片格式,这种图形是矢量图。比较厉害的是,svg 这种文件可以使用记事本打开直接编辑,因为它使用 xml 来描述图形。

本文通过几个例子来告诉你如何简单的编辑 svg 图形。如果你想更加详细的学习 svg 语法,参考这个教程:svg 教程

使用 Chrome 可以打开 svg 格式的文件。

有人会问,不是讲 go 的数据类型吗,为什么要讲 svg?这里解释一下,因为后面有一个学习浮点数的例子,这个例子输出了一个相当复杂的 svg 图形。所以为了那个例子,我不得不提前准备一些预备知识。

1. 使用 go 程序输出的 svg

下面是使用 go 语言输出的几个 svg 图形:



图1 使用 go 程序输出 svg 图形

浏览器的源码如下:



图2 上面输出的 svg 图形的源码

再来看看代码,简单了解一下都干了些啥。下面的代码路径是
gopl/basictypes/svg
.

package main

import (
"fmt"
"io"
"net/http"
)

func draw(w io.Writer) {
fmt.Fprintf(w, "<svg xmlns='http://www.w3.org/2000/svg' style='stroke: black; fill: red; stroke-width: 1.7' width='1000' height='1000'>\n")
fmt.Fprintf(w, "<circle cx='100' cy='50' r='40' fill='yellow'/>")
fmt.Fprintf(w, "<rect x='400' y='200' width='300' height='100' style='fill:rgb(0,0,255);stroke-width:1;stroke:rgb(0,0,0)'/>\n")
fmt.Fprintf(w, "<ellipse cx='300' cy='80' rx='100' ry='50' style='fill:#eeeeee;stroke:purple;stroke-width:2'/>\n")
fmt.Fprintf(w, "<line x1='300' y1='350' x2='400' y2='400' style='stroke:rgb(255,0,0);stroke-width:2'/>\n")
fmt.Fprintf(w, "<polyline points='20,20 40,25 60,40 80,120 120,140 200,180' style='fill:none;stroke:black;stroke-width:3' />\n")
fmt.Fprintf(w, "<polygon points='%g,%g %g,%g %g,%g' />\n", 10.0, 210.0, 100.0, 400.0, 20.0, 300.0)
fmt.Fprintf(w, "<path d='M 100 350 q 150 -300  300 0 q 150 -300' stroke='blue' stroke-width='5' fill='none' />")

// 绘制控制线
fmt.Fprintf(w, "<path d='M500 500 L500 600' stroke='#000000' fill='none' style='stroke:red;stroke-width: 2px;'/>\n")
fmt.Fprintf(w, "<path d='M600 600 L700 500' stroke='#000000' fill='none' style='stroke:red;stroke-width: 2px;'/>\n")
fmt.Fprintf(w, "<path d='M700 500 L800 400' stroke='#000000' fill='none' style='stroke:blue;stroke-width: 2px;'/>\n")
fmt.Fprintf(w, "<path d='M900 500 L900 600' stroke='#000000' fill='none' style='stroke:red;stroke-width: 2px;'/>\n")
// 绘制曲线
fmt.Fprintf(w, "<path d='M500 500 C500 600 600 600 700 500 S900 500 900 600' stroke='#000000' fill='none' style='stroke-width: 2px;'/>\n")
fmt.Fprintf(w, "</svg>\n")
}

func handle(w http.ResponseWriter, r *http.Request) {
// 一定要设置这个 header,不然浏览器不会把输出的 xml 解释成 svg.
w.Header().Set("Content-Type", "image/svg+xml")
draw(w)
}

func main() {
http.HandleFunc("/", handle)
http.ListenAndServe(":8080", nil)
}


2. svg 绘图指令

从第 1 节的代码里你也看到了,svg 可以输出线段(line),多边形(上面的三角形,polygon),圆形(circle),椭圆形(ellipse),多段线(polyline),曲线(path),长方形(rect)。

通过不同的标签指令,你就可以绘制不同的图形。在 svg 里,你可以把标签理解为绘制图形的函数。比如
circle
函数,它需要三个参数,
cx, cy, r
三个,比如下面的语句,表示在坐标 100,50 为圆心的地方,以半径 40 绘制一个圆。

<circle cx='100' cy='50' r='40' fill='yellow'/>


2.1 path 指令

大多数 svg 的绘图指令都相当简单,基本上你看看就能明白就能干啥。比较难的是 path 指令,它用于绘制路径。path 指令的参数 d 的下面还有还有很多不同的子命令,比如 M 命令,L 命令。以这两个为例:

<path d='M 100 100 L 200 200'/>


M 表示 MoveTo 的意思,
M 100 100
表示将当前坐标点移动到 (100, 100)。L 表示 LineTo,
L 200 200
表示绘制路径到 (200, 200)。

另外 path 的子命令可以使用小写字母,这样它后面的坐标就表示相对坐标(相对第一个坐标, M 后面的坐标)。

更多的子命令在这里:

M = moveto
L = lineto
H = horizontal lineto
V = vertical lineto
C = curveto
S = smooth curveto
Q = quadratic Bézier curve
T = smooth quadratic Bézier curveto
A = elliptical Arc
Z = closepath


这里有两篇关于 path 的博客:

《深度掌握SVG路径path的贝塞尔曲线指令》

《SVG主要的画图元素以及几个基本的几何图形介绍》

不要跑太远啊^_^!!!

2.2 polygon 指令

polygon 指令的参数是 points,它接受一个 points 数组。比如:

// 三个点构成三角形
<polygon points='10,210 100,400 20,300' />


所有这些点连接成一个封闭图形,构成多边形。后面的文章里,我们需要使用到
polygon
指令,所以你重点学习一下这个指令。

3. 总结

简单了解 svg 语法

掌握 polygon 指令

练习:1. 使用 polygon 绘制一个五边形。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  go svg polygon