第五章 文档结构

5.1 结构与表现

XML的目标之一便是提供一种能将结构从视觉表示中独立出来的方法。

但是不幸的是,关于XML的很多讨论都强调结构而非表现。

我们将通过详细讨论如何在SVG中指定表现来纠正这一错误。

5.2在SVG中使用样式

SVG允许我们使用四种方式指定图形表现方面的信息:内联样式、内部样式表、外部样式表以及表现属性。

5.2.1 内联样式

我们设置style属性的值为一系列视觉属性。

<circle cx="20" cy="20" r="10" style="stroke:black;stroke-width:1.5;fill:blue;fill-opacity:0.6;" />

5.2.2 内部样式表

可以通过一个内部样式表来罗列常用的样式,而无需在每个SVG元素内植入样式。这样可以为所有某一类元素应用样式,也可以使用命名类为特定元素应用样式。

  <svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<defs>
<style type="text/css"><![CDATA[
circle{
fill:#ffc;
stroke: blue;
stroke-width:2;
stroke-dasharray: 5 3;
}
]]></style>
</defs>
<circle cx="20" cy="20" r="10" />
<circle cx="60" cy="20" r="15" />
<circle cx="20" cy="60" r="10" style="fill:#cfc" />
<circle cx="60" cy="60" r="15" style="stroke-width:1;stroke-dasharray: none;" />
</svg>

效果图:

5.2.3外部样式表

如果想要为多个SVG文档应用一组样式,可以通过为每个SVG元素复制和粘贴内部样式表的方式俩实现。但是如果你希望能统一修改这些文档的样式,则发现这种方式是不切实际的。我们应该吧开始和结束<style>标签(不包括<![CDATA[ ]]> )之间的所有样式信息保存在一个外部文件,然后把其变成一个外部样式表。

XML:

<?xml version="1.0"?>
<?xml-stylesheet href="ext_style.css" type="text/css"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" width="200px" height="200px" viewBox="0 0 200 200">
<line x1="10" y1="10" x2="40" y2="10" />
<rect x="10" y="20" width="40" height="30" />
<circle class="yellow" cx="70" cy="20" r="10" />
<polygon class="thick" points="60 50,60 80,90 80" />
<polygon class="thick semiblue" points="100 30,150 30,150 50,130 50" />
</svg>

外部样式表CSS:

*{fill:none;stroke:black;}/* 所有元素默认样式 */
rect{
stroke-dasharray:7 3;
}
circle.yellow{
fill:yellow;
}
.thick{
stroke-width:;
}
.semiblue{
fill:blue;
fill-opacity:0.5;
}

效果图:

内联样式几乎总是比内部或者外部样式表渲染得更快,这是因为样式表和类增加了渲染时的查询和解析时间,然而样式表更容易管理,更小的文件体积和可缓存的特性可以加快文档加载速度。

5.2.4 表现属性

虽然大多数SVG文档都使用样式来表达表现信息,但是SVG的确允许我们使用表现属性指定这些信息:

<circle cx="10" cy="10" r="5" fill="red" stroke="black" stroke-width="2" />

这样做混合了结构与表现。当我们通过将XML数据源转换为SVG的方式来创建SVG文档时,表现属性会派上用场。在这些情况下,为每个表现属性创建独立的属性,要比为一个style属性创建内容更容易。如果使用SVG的环境下不支持样式表,可能需要使用表现属性。

表现属性位于优先级别列表的最底部。任何来自内联样式、内部样式或者外部样式表的样式声明都会覆盖表现属性,但表现属性会覆盖继承的样式。

强调:指定表现信息的首选应该是使用style属性或者样式表。样式表允许我们为文档中的某些元素应用一系列复杂的填充和笔画特性,而不必为每个元素复制一遍表现信息,这正是表现属性所应该有的效果。样式表的能力和灵活性允许我们花最少的经理就能改变对多个文档的外观。

5.3 分组和引用对象

我们通常认为大多数非抽象的艺术作品都是由一系列命名对象组成的,而这些对象由形状和线条组合而成。SVG提供一些元素,允许我们对元素进行这样的分组,从而使文档更加架构化、更易理解。

5.3.1<g>元素

<g>圆度会将其所有子元素作为一个组合,通常组合还会有一个唯一的id作为名称。每个组合还可以拥有自己的<title>和<desc>来供基于文本的XML应用程序识别。需索SVG渲染代理都会在鼠标悬停或者轻触组合内的图形时显示一个提示框,显示<title>元素的内容。屏幕阅读器也会读取<title>和<desc>元素的内容。

<g>元素可以组合元素,并为他们提供一些注解,这使得我们的文档结构更为清晰。<g>元素还提供了一些书写上的便利。在其实<g>标签中指定的所有样式会应用于组合内的所有子元素。而且组合还可以彼此嵌套。

  <svg width = "240px" height = "240px" viewBox = "0 0 240 240" xmlns="http://www.w3.org/2000/svg">
<title>Grouped Drawing</title>
<desc>Stick-figure drawings of a house and people</desc>
<g id="house" style="fill:none;stroke:black;">
<desc>House with door</desc>
<rect x="6" y="50" width="60" height="60" />
<polyline points="6 50,36 9,66 50" />
<polyline points="36 110,36 80,50 80,50 110" />
</g> <g id="man" style="fill:none;stroke: black;">
<desc>Male human</desc>
<circle cx="85" cy="56" r="10" />
<line x1="85" y1="66" x2="85" y2="80" />
<polyline points="76 104,85 80,94 104" />
<polyline points="76 70,85 76,94 70" />
</g> <g id="woman" style="fill:none;stroke: black;">
<desc>Female human</desc>
<circle cx="110" cy="56" r="10" />
<polyline points="110 66,110 80,100 90,120 90,110 80" />
<line x1="104" y1="104" x2="108" y2="90" />
<line x1="112" y1="90" x2="116" y2="104" />
<polyline points="101 70,110 76,119 70"/>
</g>
</svg>

效果图:

5.3.2 <use>元素

SVG使用<ues>元素,为定义在<g>元素内的组合或者任意独立图形元素提供了类似于复制粘贴的能力。

定义了一组图形对象以后,可以使用<use>标签再次显示它们。要指定想要重用的组合,给xlink:href属性指定URI即可。同时还要指定x和y的位置以表示组合的(0,0)应该移动到的位置。因此为了创建另一个和上一个一样的房子和一组小人,只要把这些线条放到闭合的</svg>标签之前即可。

     <use xlink:href="#house" x="70" y="100" />
<use xlink:href="#woman" x="-80" y="100" />
<use xlink:href="#man" x="-30" y="100" />

效果图:

5.3.3<defs>元素

<defs>(定义)元素可以通过在起始和结束<defs>标记之间放置这些组合对象,我们可以告诉SVG只定义但不现实它们。

http://oreillymedia.github.io/svg-essentials-examples/ch05/defs-example.html

  <svg width = "480px" height = "240px" viewBox = "0 0 480 240" xmlns="http://www.w3.org/2000/svg">
<title>Grouped Drawing</title>
<desc>Stick-figure drawings of a house and people</desc>
<defs>
<g id="house" style="stroke:black;">
<desc>House with door</desc>
<rect x="0" y="41" width="60" height="60" />
<polyline points="0 41,30 0,60 41" />
<polyline points="30 101,30 71,44 71,44 101" />
</g> <g id="man" style="fill:none;stroke: black;">
<desc>Male human</desc>
<circle cx="10" cy="10" r="10" />
<line x1="10" y1="20" x2="10" y2="44" />
<polyline points="1 58,10 44,19 58" />
<polyline points="1 24,10 30,19 24" />
</g> <g id="woman" style="fill:none;stroke: black;">
<desc>Female human</desc>
<circle cx="10" cy="10" r="10" />
<polyline points="10 20,10 34,0 44,20 44,10 34" />
<line x1="4" y1="58" x2="8" y2="44" />
<line x1="12" y1="44" x2="16" y2="58" />
<polyline points="1 24,10 30,19 24"/>
</g>
<g id="couple">
<desc>Male and female stick figures</desc>
<use xlink:href="#woman" x="0" y="0" />
<use xlink:href="#man" x="25" y="0" />
</g>
</defs>
<!-- 利用组合定义 -->
<use xlink:href="#house" x="0" y="0" style="fill:#cfc;" />
<use xlink:href="#couple" x="70" y="40" /> <use xlink:href="#house" x="120" y="0" style="fill:#99f;" />
<use xlink:href="#couple" x="190" y="40" /> <use xlink:href="#woman" x="0" y="145" />
<use xlink:href="#man" x="25" y="145" />
<use xlink:href="#house" x="65" y="105" style="fill:#c00;" />
</svg>

效果图:

<use>元素并不限制只能使用同一文件内的对象,事实上xlink:href属性可以指定任意有效的文件或者URI。这使得我们可以将一组公用元素集合在一个SVG文件内,然后在其他文件中选择性地使用它们。比如嗯嘛可以创建一个名为identity.svg的文件,该文件包含你的组织要使用的所有标识图形:

        <g id="company_mascot">
<!-- 绘制企业吉祥物 -->
</g> <g id="company_logo" style="stroke: none;">
<polygon points="0 20,20 0,40 20,20 40" style="fill:#696;" />
<rect x="7" y="1" width="26" height="26" style="fill:#c9c;" />
</g>
<g id="partner_logo">
<!-- 绘制合作伙伴的logo -->
</g>

然后用如下方式引用它们:

<use xlink:href="identity.svg#company_logo" x="200" y="200" />

出于安全问题,并非所有的SVG阅读器都支持外部引用,尤其是Web浏览器。有些浏览器(尤其是IE)完全不支持外部文件引用。其他浏览器也只允许<use>元素引用同一域下的文件或者专门配置了允许跨域使用的Web服务器上的文件。

5.3.4 <symbol>元素

<symbol>元素提供了另一种组合元素的方式。和<g>元素不同,<symbol>元素永远不会显示。因此我们无需把它放在<defs>规范内。然而,我们仍习惯将它放到<defs>中,因为symbol也是我们定义的供后续使用的元素。symbol还可以指定viewBox和preserveAspectRatio属性,通过给<use>元素添加width和height属性就可以让symbol适配视口大小。

  <svg width = "200px" height = "200px" viewBox = "0 0 200 200" xmlns="http://www.w3.org/2000/svg">
<title>Symbols vs.groups</title>
<desc>Use</desc>
<defs>
<g id="octagon" style="stroke: black;">
<desc>Octagon as group</desc>
<polygon points="36 25,25 36,11 36,0 25,0 11,11 0,25 0,36 11" />
</g>
<symbol id="sym-octagon" style="stroke: black;" preserveAspectRatio="xMidYMid slice" viewBox="0 0 40 40">
<desc>Octagon as symbol</desc>
<polygon points="36 25,25 36,11 36,0 25,0 11,11 0,25 0,36 11" />
</symbol>
</defs>
<g style="fill:none;stroke:gray;">
<rect x="40" y="40" width="30" height="30" />
<rect x="80" y="40" width="40" height="60" />
<rect x="40" y="110" width="30" height="30" />
<rect x="80" y="110" width="40" height="60" />
</g>
<use xlink:href="#octagon" x="40" y="40" width="30" height="30" style="fill:#c00;" />
<use xlink:href="#octagon" x="80" y="40" width="40" height="60" style="fill:#cc0;" />
<use xlink:href="#sym-octagon" x="40" y="110" width="30" height="30" style="fill:#cfc;" />
<use xlink:href="#sym-octagon" x="80" y="110" width="40" height="60" style="fill:#699;" />
</svg>

效果图:

5.3.5<image>元素

<use>元素允许我们复用SVG文件的一部分,而<image>元素可以包含一个完整的SVG或者栅格文件。如果包含一个SVG文件,其视口会基于引用文件的x、y、width和height属性来建立。如果包含一个栅格文件,它会被缩放以适配该属性指定的矩形。

以下实例展示如何在SVG文件内包含JPEG文件。

使用<defs>元素:

  <svg width = "310px" height = "310px" viewBox = "0 0 310 310" xmlns="http://www.w3.org/2000/svg">
<ellispse cx="154" cy="154" rx="150" ry="120" style="fill:#999999;" /><!-- 创建一个灰色椭圆模拟投影 -->
<ellispse cx="152" cy="152" rx="150" ry="120" style="fill:#cceeff;" /><!-- 创建主蓝色椭圆形。因为它在灰色椭圆之后出现,因此它显示在灰色椭圆之上。 -->
<image xlink:href="kwanghwamun.jpg" x="72" y="92" width="160" height="120" /><!-- 指定要包含文件的URI、图像左上角位置,应该被缩放的宽度和高度 -->
</svg>

如果图像文件的尺寸与元素的宽度和高度不匹配,<image>元素可以使用preserveAspectRatio属性只是浏览器应该怎么处理。其默认值是xMIdYMid meet,这会缩放图像并居中显示在指定的矩形中。如果包含一个SVG文件,还可以在preserveAspectRatio值的开头添加defer关键字(比如defer xMidYMid meet);这样如果包含的图像也有preserveAspectRatio属性,则会使用图像的属性来替代默认值。

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. Programming Entity Framework-dbContext 学习笔记第五章

    ### Programming Entity Framework-dbContext 学习笔记 第五章 将图表添加到Context中的方式及容易出现的错误 方法 结果 警告 Add Root 图标中的 ...

  4. [HeadFrist-HTMLCSS学习笔记]第五章认识媒体:给网页添加图像

    [HeadFrist-HTMLCSS学习笔记]第五章认识媒体:给网页添加图像 干货 JPEG.PNG.GIF有何不同 JPEG适合连续色调图像,如照片:不支持透明度:不支持动画:有损格式 PNG适合单 ...

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

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

  6. 《Spring实战》学习笔记-第五章:构建Spring web应用

    之前一直在看<Spring实战>第三版,看到第五章时发现很多东西已经过时被废弃了,于是现在开始读<Spring实战>第四版了,章节安排与之前不同了,里面应用的应该是最新的技术. ...

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

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

  8. HTML5与CSS3基础教程第八版学习笔记11~15章

    第十一章,用CSS进行布局 开始布局注意事项 1.内容与显示分离 2.布局方法:固定宽度和响应式布局 固定宽度,整个页面和每一栏都有基于像素的宽度 响应式布局也称为流式页面,使用百分数定义宽度 3.浏 ...

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

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

随机推荐

  1. C++程序设计基础(6)内存分配

    1.知识点 三步走:申请,释放,指针置空. 1.1malloc.free函数 在C语言中内存malloc函数申请动态空间,以下展示其基本用法: int *p = NULL; p = ();//申请 f ...

  2. Mysql数据库死锁分析相关概念

    参考博客: mysql死锁问题分析(https://www.cnblogs.com/LBSer/p/5183300.html) mysql insert锁机制(http://yeshaoting.cn ...

  3. 为什么C语言会有头文件

    前段时间一个刚转到C语言的同事问我,为什么C会多一个头文件,而不是像Java和Python那样所有的代码都在源文件中.我当时回答的是C是静态语言很多东西都是需要事先定义的,所以按照惯例我们是将所有的定 ...

  4. JavaScript彻底搞懂apply和call方法

    彻底搞懂JavaScript中的apply和call方法 call和apply都是为了改变某个函数运行的context上下文而存在的,即为了改变函数体内部this的指向.因为JavaScript的函数 ...

  5. 打杂程序员之ftp换成外网ip咋就登陆不上?

    主动模式ftp N连接到ftp的21端口.然后客户端开端口监听,并通过N+1端口发送命令给FTP服务器.服务器反过来连接用户本地端口. 被动模式解决从服务器到客户端数据端口的入口反向连接被防火墙过滤掉 ...

  6. IntelliJ、ReSharper 6折 加入慧都“惊喜惠”

    慧都2013岁末回馈惊喜不断!著名的软件开发公司JetBrains旗下所有产品加入"惊喜惠"活动环节, JAVA IDE——IntelliJ IDEA,.NET效率工具集——ReS ...

  7. Android.mk添加第三方jar包

    最近引入第三方的jar包进工程,发现光红色的两条并不起作用,加入include $(BUILD_MULTI_PREBUILT) 才起作用,而且顺序很重要,在这里把我参考的两个例子都列出来. 以下为引用 ...

  8. 【Leetcode】【Easy】Remove Nth Node From End of List

    Given a linked list, remove the nth node from the end of list and return its head. For example, Give ...

  9. JavaScript模块化编程之AMD - requireJS基础使用

    JavaScript模块化编程之AMD requireJS基础使用 标签(空格分隔): JavaScript 参考文章 AMD规范 AMD是"Asynchronous Module Defi ...

  10. laravel 接入蚂蚁金服SDK(以支付宝APP支付为例)开发步骤

    一.创建应用及配置 首先需要到蚂蚁金服开放平台(https://docs.open.alipay.com)注册应用,获取应用id(APP_ID),并且配置应用,主要是签约应用,这个需要审核,一般2-5 ...