o'Reill的SVG精髓(第二版)学习笔记——第六章
第六章:坐标系统变换
想要旋转、缩放或者移动图片到新的位置。可以给对应的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精髓(第二版)学习笔记——第六章的更多相关文章
- Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-2-driver
1>使用的driver 1〉generic 使用带有SSH的现有VM/主机创建机器. 如果你使用的是机器不直接支持的provider,或者希望导入现有主机以允许Docker Machine进行管 ...
- Docker技术入门与实战 第二版-学习笔记-8-网络功能network-3-容器访问控制和自定义网桥
1)容器访问控制 容器的访问控制,主要通过 Linux 上的 iptables防火墙来进行管理和实现. iptables是 Linux 上默认的防火墙软件,在大部分发行版中都自带. 容器访问外部网络 ...
- JVM学习笔记-第六章-类文件结构
JVM学习笔记-第六章-类文件结构 6.3 Class类文件的结构 本章中,笔者只是通俗地将任意一个有效的类或接口锁应当满足的格式称为"Class文件格式",实际上它完全不需要以磁 ...
- 神经网络与机器学习第3版学习笔记-第1章 Rosenblatt感知器
神经网络与机器学习第3版学习笔记 -初学者的笔记,记录花时间思考的各种疑惑 本文主要阐述该书在数学推导上一笔带过的地方.参考学习,在流畅理解书本内容的同时,还能温顾学过的数学知识,达到事半功倍的效果. ...
- 锋利的jquery第二版学习笔记
jquery系统学习笔记 一.初识:jquery的优势:1.轻量级(压缩后不到30KB)2.强大的选择器(支持css1.css2选择器的全部 css3的大部分 以及一些独创的 加入插件的话还可支持XP ...
- HTML5与CSS3基础教程第八版学习笔记1~6章
第一章,网页的构造块 网页主要包括三个部分: 1.文本内容(纯文字) 2.对其他文件的引用:图像,音频,视频,样式表文件,js文件 3.标记:对文本内容进行描述并确保引用正确地工作 注:所有这些成分都 ...
- C Primer Plus 学习笔记 -- 前六章
记录自己学习C Primer Plus的学习笔记 第一章 C语言高效在于C语言通常是汇编语言才具有的微调控能力设计的一系列内部指令 C不是面向对象编程 编译器把源代码转化成中间代码,链接器把中间代码和 ...
- 学习笔记 第六章 使用CSS美化图片
第六章 使用CSS美化图片 6.1 在网页中插入图片 GIF图像 跨平台能力,无兼容性问题: 具有减少颜色显示数目而极度压缩文件的能力,不会降低图像的品质(无损压缩): 支持背景透明功能,便于图像 ...
- Docker技术入门与实战 第二版-学习笔记-10-Docker Machine 项目-1-cli
Docker Machine 是 Docker 官方编排(Orchestration)项目之一,负责在多种平台上快速安装 Docker 环境 Docker Machine是一种工具,它允许你在虚拟主机 ...
随机推荐
- java并发编程 - Exexctor简介
Exexctor 常用类关系图 Executor 接口 Excutor 接口定义如下 ExecutorService ExecutorService 是一个比 Executor 使用更广泛的子类接口, ...
- Windows映射网络驱动器提示错误
问题描述:Windows映射网络驱动器的时候,提示文件和打印机共享资源处于联机状态未对连接尝试检测到做出响应 解决方法:不同情况可能不一样,我的原因是,映射的Linux,防火墙处于开启状态,关闭了就可 ...
- Bitmap图片查看器
在Android 应用中使用assets目录下存放的资源文件,assets目录下存放的资源代表应用无法直接访问的原生资源,应用程序通过AssetManager以二 进制流的形式来读取资源.此应用是查看 ...
- Scala 知识点掌握1
Scala知识点巩固 1.Scala简介 Scala是一门面向对象和面向函数的编程语言,是一门静态编程语言,如 Java Scala(变量类型在编译阶段确定):源码文件需要基于 JVM 运行的. 动态 ...
- javaSystem.out.println()输出byte[]和char[]异常的问题
javaSystem.out.println()输出byte[]和char[]异常的问题 今天 突然有人问我他写的byte[]和char[],在用System.out.println()输出的时候所得 ...
- 2018.10.16 NOIP模拟赛解题报告
心路历程 预计得分:\(100 + 100 + 20 = 220\) 实际得分:\(100 + 100 + 30 = 230\) 辣鸡模拟赛.. T1T2都是一眼题,T3考验卡常数还只有一档暴力分. ...
- 【数据库】7.0 MySQL入门学习(七)——MySQL基本指令:帮助、清除输入、查询等
1.0 help == ? 帮助指令,查询某个指令的解释.用法.说明等.详情参考博文: [数据库]6.0 MySQL入门学习(六)——MySQL启动与停止.官方手册.文档查询 https://www. ...
- 关于input 中 hidden属性在后台作用的实例
在双模的项目中,我遇到了一个问题,我公司的双模项目是基于ECShop的框架,在完成订单列表的页面时,我写了两个form表单来单独传输数据,第一个表单是用来做搜素的,第二个表单是用来显示表单信息的,在控 ...
- 转:SQL Server附加数据库提示“版本为661,无法打开,支持655版本……”
在我们使用别人导出的数据库的时候,有时候我们会通过附加数据库的方法,把别人导出的数据库附加到我们的电脑中,这时,或许你会遇到这种问题,附加时,提示版本为XXX,无法打开,支持AAA版本. 这是怎么回事 ...
- greenplum维护
1.用户管理 psql -d sea CREATE DATABASE BI; CREATE USER ubi WITH PASSWORD 'pwdbi' NOSUPERUSER; GRANT ALL ...