第六章:坐标系统变换

想要旋转、缩放或者移动图片到新的位置。可以给对应的SVG元素添加transform属性。

6.1 translate变换

可以为<use>元素使用x和y属性,以在特性的位置放置图形对象组合:

  <svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<g id="square">
<rect x="0" y="0" width="20" height="20" style="fill:black;stroke-width:2;" />
</g>
<use xlink:href="#square" x="50" y="50" />
</svg>

效果图:

事实上,x和y值只是更常用和更强大的transform属性的一种简写形式。具体来说,x和y相当于属性transform="translate(x-value,y-value)",而translate只是一个花哨的表示“移动”的术语。x和y根据当前用户坐标系统计算。

使用transform生成另一个正方形:

  <!-- 使用translate移动坐标系统 -->
<svg width="200px" height="200px" viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<g id="square">
<rect x="0" y="0" width="20" height="20" style="fill:none;stroke:black;stroke-width:2" />
</g>
<use xlink:href="#square" transform="translate(50,50)" />
</svg>

效果和上面一致。

translate声明会获取整个网格,然后吧它移动到画布的新位置,而不是移动正方形。对于正方形而言,它仍然绘制在左上角(0,0)处。

示例网址:http://oreillymedia.github.io/svg-essentials-examples/ch06/translate.html

变换永远不会改变图形对象的网格坐标,但是它会改变网格在画布上的位置。

如果要对整个坐标系统应用其他的变换或者一系列变换的组合。会更加方便。

6.2 scale变换

它可以通过缩放坐标系统的方式让对象显示得比定义的尺寸更大或者更小。

①transform="scale(value)"

所有的x和y坐标乘以给定的value。

②transform="scale(x-value,y-value)"

所有的x坐标乘以给定的x-value,所有的y坐标乘以给定的y-value。

缩放:均匀地将两个轴放大一倍:

  <!-- 均匀的缩放图像 -->
<svg width="200px" height="200px" viewBox="0 0 200 200">
<g id="square">
<rect x="10" y="10" width="20" height="20" style="fill:none;stroke:black;" />
</g>
<use xlink:href="#square" transform="scale(2)" />
</svg>

效果图:

坐标系统的点(0,0)仍然在相同的位置。但是每个用户坐标都变成原来的两倍了。矩形的左上角在更大的新网格中仍然在(10,10)的位置,因为对象并没有移动。stroke-width仍然是一个用户单位,但是这个单位已经是原来的两倍了。因此其笔画变粗了。

缩放变换永远不会改变图形对象的网格坐标或者它的笔画宽度,但是,它会改变对应画布上的坐标系统(网格)的大小。

我们可以通过使用scale变换的第二种形式,为坐标系统的x轴和y轴指定不同的缩放比例。以下绘制了正方形的x轴被放大了3倍,y轴被放大了1.5倍。

<!-- 不均匀的缩放图形 -->
<svg width="200px" height="200px" viewBox="0 0 200 200">
<g id="square">
<rect x="10" y="10" width="20" height="20" style="fill:none;stroke:black;" />
</g>
<use xlink:href="#square" transform="scale(3,1.5)" />
</svg>

效果图:

还可以将一系列元素组合在一起,然后对组合应用变换:

  <svg width="200px" height="200px" viewBox="0 0 200 200">
<g id="group1" transform="translate(3,5)">
<line x1="10" y1="10" x2="30" y2="30" />
<circle cx="20" cy="20" r="10" />
</g>
</svg>

也可以为单个对象或者基本形状应用变换。

  <svg width="200px" height="200px" viewBox="0 0 200 200">
<rect x="15" y="20" width="10" height="5" transform="scale(3)" style="fill:none;stroke: black;" />
</svg>

SVG会计算形状的坐标之前,先对坐标系统应用变换。

单个图形对象的变换:

  <svg width="200px" height="200px" viewBox="0 0 200 200">
<!-- 未缩放坐标系统的网格参考线 -->
<line x1="0" y1="0" x2="100" y2="0" style="stroke:black;" />
<line x1="0" y1="0" x2="0" y2="100" style="stroke:black;" />
<line x1="45" y1="0" x2="45" y2="100" style="stroke:gray;" />
<line x1="0" y1="60" x2="100" y2="60" style="stroke:gray;" />
<!-- 要变换的矩形 -->
<rect x="15" y="20" width="10" height="5" transform="scale(3)" style="fill:none;stroke: black;" />
</svg>

效果图:

为形状应用变换与形状被包含在变换组合中的效果相同。在前面的例子中,被缩放的矩形等价于:

     <g transform="scale(3)">
<rect x="15" y="20" width="10" height="5" style="fill:none;stroke:black;" />
</g>

6.3 变换序列

一个图形对象上可以做多个变换。我们只需要将多个变换通过空格或者逗号分隔,依次放入transform属性即可。下面是一个矩形,它经过两个变换,先平移再缩放(通过绘制的轴可以看出来矩形确实被移动了。)

   <svg width="200px" height="200px" viewBox="0 0 200 200">
<!-- 绘制轴 -->
<line x1="0" y1="0" x2="0" y2="100" style="stroke:gray;" />
<line x1="0" y1="0" x2="100" y2="0" style="stroke:gray;" />
<rect x="10" y="10" height="15" width="20" transform="translate(30,20) scale(2)" style="fill:gray;" />
</svg>

等价于下面的嵌套组合序列:

     <g transform="translate(30,20)">
<g transform="scale(2)">
<rect x="10" y="10" height="15" width="20" style="fill:gray;" />
</g>
</g>

效果图:

【先平移后缩放的效果】

变换序列的顺序会影响结果,一般情况下,变换A然后变换B的结果与变换B然后变换A的结果不同。

变换序列——先缩放后平移:

<!-- 变换序列——先缩放后平移 -->
<svg width="200px" height="200px" viewBox="0 0 200 200">
<!-- 绘制轴 -->
<line x1="0" y1="0" x2="0" y2="100" style="stroke:gray;" />
<line x1="0" y1="0" x2="100" y2="0" style="stroke:gray;" />
<rect x="10" y="10" width="20" height="15" transform="translate(30,20) scale(2)" style="fill:gray;" />
<rect x="10" y="10" width="20" height="15" transform="scale(2) translate(30,20)" style="fill:black;" />
</svg>

效果图:

黑色矩形最终远离原始矩形是因为首先应用了缩放,因此横向平移20单位和纵向平移10单位是在单位放大一倍之后完成的。

在线示例:http://oreillymedia.github.io/svg-essentials-examples/ch06/sequence.html

6.4 技巧:笛卡儿坐标系列转换

如果从其他系统传输数据到SVG,你可能必须处理使用笛卡儿坐标表示数据的矢量图形。在这个系统中,点(0,0)位于画布的左下角,y坐标向上递增。

y轴与SVG的默认约定“上下相反”,因此需要重新计算坐标。我们可以使用变换序列让SVG做这些工作,而不是手动处理。

使用笛卡儿坐标绘制图形,图像会上下翻转,因为x轴的方向在笛卡儿坐标和默认的SVG坐标系统中的方向相同。

直接使用笛卡儿坐标:

<!-- 直接使用笛卡儿坐标绘制梯形 -->
<svg width="200px" height="200px" viewBox="0 0 200 200">
<!-- 轴 -->
<line x1="0" y1="0" x2="100" y2="0" style="stroke: black;" />
<line x1="0" y1="0" x2="0" y2="100" style="stroke: black;" />
<!-- 梯形 -->
<polygon points="40 40,100 40,70 70,40 70" style="fill:gray;stroke:black;" />
</svg>

效果图:

如果想要把图片翻转回正面朝上,我们可以利用:通过负值缩放形状会反转坐标顺序。然而,由于整个网格最终会翻转到坐标0点的另一侧,我们还需要将形状平移回画布的可视部分。

①在原始绘图中找到最大y坐标。本例中是100,也就是y轴的末端。

②将整个绘图放入<g>元素中。

③启用平移,根据最大的y值向下移动坐标系统:transform="translate(0,max-y)"。

④接下来变换就是缩放y轴-1倍,让它倒置翻转:transform="translate(0,max-y) scale(1,-1)"。

我们不希望改变x轴的值,但是仍然需要为translate和scale函数指定一个x值。

什么都不做的平移,指定0即可。什么都不做的缩放,要变换值为1。

<!--笛卡儿坐标变换-->  
  <svg width="200px" height="200px" viewBox="0 0 200 200">
<g transform="translate(0,100) scale(1,-1)">
<!-- 轴 -->
<line x1="0" y1="0" x2="100" y2="0" style="stroke: black;" />
<line x1="0" y1="0" x2="0" y2="100" style="stroke: black;" />
<!-- 梯形 -->
<polygon points="40 40,100 40,70 70,40 70" style="fill:gray;stroke:black;" />
</g>
</svg>

效果图:

6.5 rotate变换

还可以根据指定的角度旋转坐标系统。在默认的坐标系统中,角度的测量是按顺时针增加的,水平线的角度为0度。

除非另行指定,否则旋转的中心(轴心点的别称)被假定为(0,0)。

下例绘制了一个灰色的正方形,然后在坐标系统旋转45度后又绘制了一个黑色正方形。轴仍然用作参考。

在线示例:http://oreillymedia.github.io/svg-essentials-examples/ch06/rotate.html

<!-- 默认和旋转后的正方形 -->  
  <svg width="200px" height="200px" viewBox="0 0 200 200">
<!-- 轴 -->
<polyline points="100 0,0 0,0 100" style="stroke: black;fill:none" />
<!-- 默认和旋转后的正方形 -->
<rect x="70" y="30" width="20" height="20" style="fill:gray;" />
<rect x="70" y="30" width="20" height="20" transform="rotate(45)" style="fill:black;" />
</svg>

效果图:

很多时候,我们并不想围绕原点旋转整个坐标系统,而是希望围绕某个点旋转单个对象。我们可以通过一系列变换做到:translate(centerX,centerY) rotate(angle) translate(-centerX,-centerY)。

SVG提供了另一个版本的rotate。在rotate变换的第二种形式中,指定角度以及想要围绕其旋转的中心点即可:

rotate(angle,centerX,centerY)

这样的效果是以指定的x和y点作为原点临时建立一个新的坐标系统执行旋转操作,然后红心建立原始坐标。

http://oreillymedia.github.io/svg-essentials-examples/ch06/rotate-center.html

<!-- 围绕中心点旋转 -->
<svg width="200px" height="200px" viewBox="0 0 200 200">
<!-- 旋转中心 -->
<circle cx="50" cy="50" r="3" style="fill:black;" />
<!-- 未旋转的箭头 -->
<g id="arrow" style="stroke:black;">
<line x1="60" y1="50" x2="90" y2="50" />
<polygon points="90 50,85 45,85 55" />
</g>
<!-- 围绕中心点旋转 -->
<use xlink:href="#arrow" transform="rotate(60,50,50)" />
<use xlink:href="#arrow" transform="rotate(-90,50,50)" />
<use xlink:href="#arrow" transform="rotate(-150,50,50)" />
</svg>

效果图:

6.6 技巧:围绕中心点缩放

虽然可以围绕某个不是原点的点旋转,但是却不能围绕某个点缩放(scale)。然而我们可以使用一系列简单的变换制造同心符号。要围绕某个点按照给定的比例缩放对象可以这么做:

translate(-centerX*(factor-1),-centerY*(factor-1))

scale(factor)

同心矩形:

<!-- 围绕中心点缩放 -->
<svg width="200px" height="200px" viewBox="0 0 200 200">
<!-- 缩放中心 -->
<circle cx="50" cy="50" r="2" style="fill:black;" />
<!-- 未缩放的矩形 -->
<g id="box" style="stroke:black;fill:none;">
<rect x="35" y="40" width="30" height="20" />
</g> <use xlink:href="#box" transform="translate(-50,-50) scale(2)" style="stroke-width:0.5;" />
<use xlink:href="#box" transform="translate(-75,-75) scale(2.5)" style="stroke-width:0.4" />
<use xlink:href="#box" transform="translate(-100,-100) scale(3)" style="stroke-width:0.33" />
</svg>

效果图:

6.7 skewX和skewY变换

SVG还有另外两种变换:skewX和skewY,这让我们可以倾斜某个轴。其一般形式为skewX(angle)和skewY(angle)。skewX变换会按照指定的角度“推动”所有x坐标,y坐标不会改变。skewY会倾斜y坐标,而x坐标不会改变。

skewX变换保持水平线不变,skewY变换保持垂直线不变。

在线示例:http://oreillymedia.github.io/svg-essentials-examples/ch06/skew.html

<!-- skewX和skewY -->
<svg width="200px" height="200px" viewBox="0 0 200 200">
<!-- 参考线,执行变换前这些虚线绘制在默认坐标系统中 -->
<g style="stroke: gray;stroke-dasharray: 4 4;">
<line x1="0" y1="0" x2="200" y2="0" />
<line x1="20" y1="0" x2="20" y2="90" />
<line x1="120" y1="0" x2="120" y2="90" />
</g>
<g transform="translate(20,0)"><!-- 将整个倾斜“打包”移动到希望的位置 -->
<g transform="skewX(30)"><!-- 倾斜x坐标30度,这一变化不会改变原点,新坐标系统中原点仍然在(0,0)处 -->
<polyline points="50 0,0 0,0 50" style="fill:none;stroke:black;stroke-width:2;" /><!-- 在原点绘制对象 -->
<text x="0" y="60">skewX</text>
</g>
</g>
<g transform="translate(120,0)"><!-- 与上述一致,y坐标倾斜 -->
<g transform="skewY(30)">
<polyline points="50 0,0 0,0 50" style="fill:none;stroke:black;stroke-width:2;" />
<text x="0" y="60">skewY</text>
</g>
</g>
</svg>

效果图:

6.8总结

变换 描述
translate(x,y) 按照指定的x和y值移动用户坐标系统。如果没有指定y值,则假定为0。
scale(xFactor,yFactor) 使用指定的xFactor和yFactor乘以所有的用户坐标系统。比例值可以是小数或者负值。
scale(factor) 和scale(factor,factor)相同
rotate(angle) 按照指定的angle旋转用户坐标。旋转中心为原点(0,0)。在默认坐标系统中,旋转角度按顺时针方向递增,水平线的角度为0度
rotate(angle,centerX,centerY) 按照指定的angle旋转用户坐标。旋转中心由centerX和centerY指定。
skewX(angle) 根据指定的angle倾斜所有x坐标。视觉上,这会让垂直线出现角度。
skewY(angle) 根据指定的angle倾斜所有y坐标。视觉上会让水平线出现角度。
matrix(a b c d e f) 指定一个六个值组成的矩阵变换。

o'Reill的SVG精髓(第二版)学习笔记——第六章的更多相关文章

  1. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver

    1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...

  2. Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥

    1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...

  3. JVM学习笔记-第六章-类文件结构

    JVM学习笔记-第六章-类文件结构 6.3 Class类文件的结构 本章中,笔者只是通俗地将任意一个有效的类或接口锁应当满足的格式称为"Class文件格式",实际上它完全不需要以磁 ...

  4. 神经网络与机器学习第3版学习笔记-第1章 Rosenblatt感知器

    神经网络与机器学习第3版学习笔记 -初学者的笔记,记录花时间思考的各种疑惑 本文主要阐述该书在数学推导上一笔带过的地方.参考学习,在流畅理解书本内容的同时,还能温顾学过的数学知识,达到事半功倍的效果. ...

  5. 锋利的jquery第二版学习笔记

    jquery系统学习笔记 一.初识:jquery的优势:1.轻量级(压缩后不到30KB)2.强大的选择器(支持css1.css2选择器的全部 css3的大部分 以及一些独创的 加入插件的话还可支持XP ...

  6. HTML5与CSS3基础教程第八版学习笔记1~6章

    第一章,网页的构造块 网页主要包括三个部分: 1.文本内容(纯文字) 2.对其他文件的引用:图像,音频,视频,样式表文件,js文件 3.标记:对文本内容进行描述并确保引用正确地工作 注:所有这些成分都 ...

  7. C Primer Plus 学习笔记 -- 前六章

    记录自己学习C Primer Plus的学习笔记 第一章 C语言高效在于C语言通常是汇编语言才具有的微调控能力设计的一系列内部指令 C不是面向对象编程 编译器把源代码转化成中间代码,链接器把中间代码和 ...

  8. 学习笔记 第六章 使用CSS美化图片

    第六章  使用CSS美化图片 6.1  在网页中插入图片 GIF图像 跨平台能力,无兼容性问题: 具有减少颜色显示数目而极度压缩文件的能力,不会降低图像的品质(无损压缩): 支持背景透明功能,便于图像 ...

  9. Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-1-cli

    Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境 Docker Machine是一种工具,它允许你在虚拟主机 ...

随机推荐

  1. pat1006. Sign In and Sign Out (25)

    1006. Sign In and Sign Out (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...

  2. Python项目中如何优雅的import

    Python项目中如何优雅的import 前言 之前有一篇关于Python编码规范的随笔, 但是写的比较杂乱, 因为提到了import语句, 在篇文章中, 我专门来讲Python项目中如何更好的imp ...

  3. 对key中有数字的字典进行排序

    word_cloud = []cc = [{"c58":341,"c59":525,"c56":507,"c57":34 ...

  4. Android界面编程--使用活动条(ActionBar)

    ActionBar的使用 1.启动ActionBar(默认状态下是启动的) 1.1 在Android配置文件(AndroidManifest.xml)中设置应用的主题为 ***.NoActionBar ...

  5. Android活动的启动模式

    1. standard 标准模式,是活动默认的启动模式,在不进行显示指定的情况下,所有活动都会自动使用这种模式. Android使用返回栈管理活动,在standard模式下,每当启动一个新的活动,它就 ...

  6. html元素固定

    1.position 值 描述 static        默认.位置设置为 static 的元素,它始终会处于页面流给予的位置(static 元素会忽略任何 top.bottom.left 或 ri ...

  7. 【数据库】8.0 MySQL入门学习(八)——创建并使用数据库、获得数据库和表的信息

    1.0 使用SHOW语句找出服务器上当前存在什么数据库: mysql> SHOW DATABASES; 每台机器上的数据库列表是不同的,但是很可能有mysql和test数据库.mysql是必需的 ...

  8. easyui datagrid 获取行数据某个字段

    首先要能获取datagrid 的row对象 即:var row = $('#datagrid').datagrid('getData').rows[index]; 之后我们就可以通过类似row.nam ...

  9. Android 自定义View之自绘控件

    首先要提前声明一下,我对于自定义View的理解并不是很深,最近啃了几天guolin博主写的关于自定义View的博客,讲的非常棒,只不过涉及到源码和底层的一些东西,我自己就懵逼了,目前只是会了关于自定义 ...

  10. 管理uWSGI服务器

    管理uWSGI服务器 官网参考 如果您正在管理多个应用程序或高容量站点,请查看 uwsgi皇帝-多应用程序部署 虫族模式 UWSGI订阅式服务器 启动uwsgi服务器 以系统管理员身份启动 uwsgi ...