理解SVG坐标系统和变换: transform属性

2015/09/23 · HTML5 ·
SVG

原文出处:
SaraSoueidan   译文出处:Blueed@Ivan_z3   

SVG元素可以通过缩放,移动,倾斜和旋转来变换-类似HTML元素使用CSS
transform来变换。然而,当涉及到坐标系时这些变换所产生的影响必然有一定差别。在这篇文章中我们讨论SVG的transform属性和CSS属性,包括如何使用,以及你必须知道的关于SVG坐标系变换的知识。

这是我写的SVG坐标系统和变换部分的第二篇。在第一篇中,包括了任何要理解SVG坐标系统基础的需要知道的内容;更具体的是,
SVG viewport, viewBox 和 preserveAspectRatio 属性。

  • 理解SVG坐标系和变换(第一部分)-viewport,viewBox,和preserveAspectRatio
  • 理解SVG坐标系和变换(第二部分)-transform属性
  • 理解SVG坐标系和变换(第三部分)-建立新视窗

这一部分我建议你先阅读第一篇,如果没有,确保你在阅读这篇之前已经读了第一篇。

HTTP/2 头部压缩技术介绍

2015/11/03 · HTML5 ·
HTTP/2

原文出处:
imququ(@屈光宇)   

我们知道,HTTP/2 协议由两个 RFC 组成:一个是 RFC
7540,描述了 HTTP/2
协议本身;一个是 RFC
7541,描述了 HTTP/2
协议中使用的头部压缩技术。本文将通过实际案例带领大家详细地认识 HTTP/2
头部压缩这门技术。

SVG 线条动画入门

2016/12/29 · HTML5 ·
SVG,
动画

本文作者: 伯乐在线 –
chokcoco
。未经作者许可,禁止转载!
欢迎加入伯乐在线 专栏作者。

通常我们说的 Web 动画,包含了三大类。

  • CSS3 动画
  • javascript 动画(canvas)
  • html 动画(SVG)

个人认为 3
种动画各有优劣,实际应用中根据掌握情况作出取舍,本文讨论的是我认为 SVG
中在实际项目中非常有应用价值 SVG 线条动画。

transform属性值

tranform属性用来对一个元素声明一个或多个变换。它输入一个带有顺序的变换定义列表的<transform-list>值。每个变换定义由空格或逗号隔开。给元素添加变换看起来如下:

有效地SVG变换有:旋转缩放移动,
倾斜transform属性中使用的变换函数类似于CSS中transform属性使用的CSS变换函数,除了参数不同。

注意下列的函数语法定义只在transform属性中有效。查看section about
transforming SVGs with CSS
properties获取关于CSS变换属性中使用的语法信息。

为什么要压缩

在 HTTP/1 中,HTTP 请求和响应都是由「状态行、请求 /
响应头部、消息主体」三部分组成。一般而言,消息主体都会经过 gzip
压缩,或者本身传输的就是压缩过后的二进制文件(例如图片、音频),但状态行和头部却没有经过任何压缩,直接以纯文本传输。

随着 Web 功能越来越复杂,每个页面产生的请求数也越来越多,根据 HTTP
Archive 的统计,当前平均每个页面都会产生上百个请求。越来越多的请求导致消耗在头部的流量越来越多,尤其是每次都要传输
UserAgent、Cookie 这类不会频繁变动的内容,完全是一种浪费。

以下是我随手打开的一个页面的抓包结果。可以看到,传输头部的网络开销超过
100kb,比 HTML 还多:

澳门微尼斯人手机版 1

下面是其中一个请求的明细。可以看到,为了获得 58
字节的数据,在头部传输上花费了好几倍的流量:

澳门微尼斯人手机版 2

HTTP/1
时代,为了减少头部消耗的流量,有很多优化方案可以尝试,例如合并请求、启用
Cookie-Free
域名等等,但是这些方案或多或少会引入一些新的问题,这里不展开讨论。

举个栗子

SVG 线条动画,在一些特定的场合下可以解决使用 CSS
无法完成的动画。尤其是在进度条方面,看看最近项目里的一个小需求,一个这种形状的进度条:

澳门微尼斯人手机版 3

把里面的进度条单独拿出来,也就是需要实现这样一个效果:

澳门微尼斯人手机版 4

脑洞大开一下,使用 CSS3 如何实现这样一个进度条呢。

CSS3 是可以做到的,就是很麻烦。但是如果采用 SVG 的话,迎刃而解。

See the Pen 不规则进度条 by
Chokcoco (@Chokcoco) on
CodePen.

我们假定你在阅读本文的时候有了一定的 SVG
基础,上面代码看看就懂了,好了,本文到此结束。

澳门微尼斯人手机版 5

好吧,还是一步一步解释,上面进度条的主要 SVG 代码如下:

<svg version=”1.1″ xmlns=””
xmlns:xlink=”” xml:space=”preserve”
class=”circle-load-rect-svg” width=”300″ height=”200″ viewbox=”0 0 600
400″> <polyline points=”5 5, 575 5, 575 200, 5 200″
class=”g-rect-path”/> <polyline points=”5 5, 575 5, 575 200, 5
200″ class=”g-rect-fill”/> </svg>

1
2
3
4
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" class="circle-load-rect-svg" width="300" height="200" viewbox="0 0 600 400">
  <polyline points="5 5, 575 5, 575 200, 5 200" class="g-rect-path"/>
  <polyline points="5 5, 575 5, 575 200, 5 200" class="g-rect-fill"/>
</svg>

Matrix

你可以使用matrix()函数在SVG元素上添加一个或多个变换。matrix变换语法如下:

matrix(<a> <b> <c> <d> <e> <f>)

1
matrix(<a> <b> <c> <d> <e> <f>)

上述声明通过一个有6个值的变换矩阵声明一个变换。matrix(a,b,c,d,e,f)等同于添加变换matrix[a b c d e f]

如果你不精通数学,最好不要用这个函数。对于那些精通的人,你可以在这里阅读更多关于数学的内容。因此这个函数很少使用-我将忽略来讨论其他变换函数。

压缩后的效果

接下来我将使用访问本博客的抓包记录来说明 HTTP/2
头部压缩带来的变化。如何使用 Wireshark 对 HTTPS
网站进行抓包并解密,请看我的这篇文章。本文使用的抓包文件,可以点这里下载。

首先直接上图。下图选中的 Stream 是首次访问本站,浏览器发出的请求头:

澳门微尼斯人手机版 6

从图片中可以看到这个 HEADERS 流的长度是 206 个字节,而解码后的头部长度有
451 个字节。由此可见,压缩后的头部大小减少了一半多。

然而这就是全部吗?再上一张图。下图选中的 Stream
是点击本站链接后,浏览器发出的请求头:

澳门微尼斯人手机版 7

可以看到这一次,HEADERS 流的长度只有 49 个字节,但是解码后的头部长度却有
470 个字节。这一次,压缩后的头部大小几乎只有原始大小的 1/10。

为什么前后两次差距这么大呢?我们把两次的头部信息展开,查看同一个字段两次传输所占用的字节数:

澳门微尼斯人手机版 8

澳门微尼斯人手机版 9

对比后可以发现,第二次的请求头部之所以非常小,是因为大部分键值对只占用了一个字节。尤其是
UserAgent、Cookie
这样的头部,首次请求中需要占用很多字节,后续请求中都只需要一个字节。

SVG 为何

可缩放矢量图形,即SVG,是W3C
XML的分枝语言之一,用于标记可缩放的矢量图形。(摘自MDN)

上面代码中,先谈谈 svg 标签:

  • version: 表示 “ 的版本,目前只有 1.0,1.1 两种
  • xmlnshttp://www.w3.org/2000/svg 固定值
  • xmlns:xlinkhttp://www.w3.org/1999/xlink 固定值
  • xml:spacepreserve 固定值,上述三个值固定,表示命名空间,当数据单独存在svg文件内时,这3个值不能省略
  • class:就是我们熟悉的 class
  • width | height: 定义 svg 画布的大小
  • viewbox: 定义了画布上可以显示的区域,当 viewBox 的大小和 svg
    不同时,viewBox 在屏幕上的显示会缩放至 svg
    同等大小(暂时可以不用理解)

有了 svg 标签,我们就可以愉快的在内部添加 SVG 图形了,上面,我在 svg 中定义了两个 polyline 标签。

Translation

要移动SVG元素,你可以用translate()函数。translate函数的语法如下:

CSS

translate(<tx> [<ty>])

1
translate(<tx> [<ty>])

translate()函数输入一个或两个值得来声明水平和竖直移动值。tx代表x轴上的translation值;ty代表y轴上的translation值。

ty值是可选的,如果省略,默认值为0txty值可以通过空格或者逗号分隔,它们在函数中不代表任何单位-它们默认等于当前用户坐标系单位。

下面的例子把一个元素向右移动100个用户单位,向下移动300个用户单位。

<circle cx=”0″ cy=”0″ r=”100″ transform=”translate(100 300)” />

1
<circle cx="0" cy="0" r="100" transform="translate(100 300)" />

上述代码如果以translate(100, 300)用逗号来分隔值的形式声明一样有效。

技术原理

下面这张截图,取自 Google 的性能专家 Ilya Grigorik 在 Velocity 2015 • SC
会议中分享的「HTTP/2 is here, let’s
optimize!」,非常直观地描述了
HTTP/2 中头部压缩的原理:

澳门微尼斯人手机版 10

我再用通俗的语言解释下,头部压缩需要在支持 HTTP/2 的浏览器和服务端之间:

  • 维护一份相同的静态字典(Static
    Table),包含常见的头部名称,以及特别常见的头部名称与值的组合;
  • 维护一份相同的动态字典(Dynamic Table),可以动态的添加内容;
  • 支持基于静态哈夫曼码表的哈夫曼编码(Huffman Coding);

静态字典的作用有两个:1)对于完全匹配的头部键值对,例如 :
method :GET
,可以直接使用一个字符表示;2)对于头部名称可以匹配的键值对,例如 cookie :xxxxxxx,可以将名称使用一个字符表示。HTTP/2
中的静态字典如下(以下只截取了部分,完整表格在这里):

Index Header Name Header Value
1 :authority
2 :method GET
3 :method POST
4 :path /
5 :path /index.html
6 :scheme http
7 :scheme https
8 :status 200
32 cookie
60 via
61 www-authenticate

同时,浏览器可以告知服务端,将 cookie :xxxxxxx 添加到动态字典中,这样后续整个键值对就可以使用一个字符表示了。类似的,服务端也可以更新对方的动态字典。需要注意的是,动态字典上下文有关,需要为每个
HTTP/2 连接维护不同的字典。

使用字典可以极大地提升压缩效果,其中静态字典在首次请求中就可以使用。对于静态、动态字典中不存在的内容,还可以使用哈夫曼编码来减小体积。HTTP/2
使用了一份静态哈夫曼码表(详见),也需要内置在客户端和服务端之中。

这里顺便说一下,HTTP/1 的状态行信息(Method、Path、Status 等),在
HTTP/2
中被拆成键值对放入头部(冒号开头的那些),同样可以享受到字典和哈夫曼压缩。另外,HTTP/2
中所有头部名称必须小写。

SVG 基本形状

polyline:是SVG的一个基本形状,用来创建一系列直线连接多个点。

其实,polyline 是一个比较不常用的形状,比较常用的是pathrectcircle 等。这里我使用polyline 的原因是需要使用 stroke-linejoin 和 stroke-linecap 属性,在线段连接处创建圆滑过渡角。

SVG
中定义了一些基本形状,在继续下文之前,建议点进去先了解一些基本图形的标签及写法:

澳门微尼斯人手机版 11

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章