学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

时间:2023-03-09 03:17:55
学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

(原文地址:http://www.cnblogs.com/idealer3d/p/LearningRaphaelJSVectorGraphics.html

前面3篇博文里面,我们讲解了一本叫做《Instant RaphaelJS Starter》的书,那本书里我们将RaphaelJS里面的基本内容都进行了比较详细的讲解。但是,坦白的说,那本书通俗易懂却太过浅显。现在我们下一本叫做《Learning Raphael JS Vector Graphics》的书,算是上一本的进阶。当然,它里面大部分篇幅也是基本内容。因为一本书不能去讲一个写复杂的业务问题,你所要做的也是学会基本内容然后自己去活用。我这里翻译此书的目的,第一是想加深对于RaphaelJS的理解,第二是本来也是要读这本书的,就顺带翻译了,或许还能给英语不拿手的同志们有点帮助,第三就是寻找一些突破的契机去解决我现在碰到的问题。好了,废话少说。新的一本书,大家可以去网上搜索一下,应该可以找到下载。

和上本书一样,本书前面的几页是一些序言、版权声明等东西,这里我也略过不讲了。我们从目录页开始讲。如果你认真学习过前面3篇翻译上本书博文的内容,这本书的目录写出来的时候,你就应该能明白每个章节讲的是什么内容。

                         目录

序言 --------------------------------------------------- 1

第一章: Web图形---------------------------------------- 5

在Web上绘制矢量图---------------------------------- 6

矢量图形绘制包-----------------------------------7

详述SVG-------------------------------------------- 8

使用RaphaelJS包而不是直接使用SVG-------------- 9

RaphaelJS的应用--------------------------------------9

下载RaphaelJS-------------------------------------- 10

创建RaphaelJS的Js项目------------------------------ 11

项目的构建与优化 --------------------------------11

小结-------------------------------------------------11

第二章: RaphaelJS基本图形绘制 --------------------------13

绘制环境------------------------------------------- 13

画布坐标系-------------------------------------- 15

绘制基本图形---------------------------------------- 16

导入图片--------------------------------------------18

Raphael元素属性------------------------------------ 18

简单(基础)填充-------------------------------- 19

图片填充---------------------------------------- 19

应用笔画---------------------------------------- 20

其它属性---------------------------------------- 21

超链接--------------------------------------21

透明度--------------------------------------22

矩形裁剪------------------------------------22

渐变应用----------------------------------------23

线性渐变------------------------------------ 23

径向渐变------------------------------------ 25

元素分组---------------------------------------- 27

使用文本-------------------------------------------- 28

引用常用字体------------------------------------ 29

小结-------------------------------------------------30

第三章: 绘制Path(路径)---------------------------- ----31

Path绘制概念--------------------------------------- 32

Path绘制命令--------------------------------------- 33

"移动到"命令------------------------------------34

"连接到"命令----------------------------------- 35

"关闭路径"命令--------------------------------- 37

绘制曲线------------------------------------------- 38

二次贝塞尔曲线--------------------------------- 38

三次贝塞尔曲线--------------------------------- 41

绘制弧线--------------------------------------- 43

Path中比较实用的方法------------------------------- 46

Element.getTotalLength() ---------------------46

Element.getPointAtLength(length) -------------47

Element.getSubpath(from, to)----------------- 48

Catmull-Rom弧线------------------------------- 49

小结----------------------------------------------- 50

第四章: 变形转换和事件处理------------------------------ 51

基本图形变换和事件处理------------------------------52

基本图形变换------------------------------------52

平移----------------------------------------53

旋转--------------------------------------- 53

缩放----------------------------------------55

基本事件响应----------------------------------- 55

注册基本事件响应 ---------------------------55

注销基本事件响应----------------------------57

使用矩阵------------------------------------------- 58

转换矩阵--------------------------------------- 58

使用转换矩阵----------------------------------- 58

拖放功能------------------------------------------- 60

Element.drag() 方法 ---------------------------60

onstart事件----------------------------------- 60

onend事件------------------------------------ 60

onmove事件---------------------------------- 60

拖动的例子-------------------------------- 61

丢下元素------------------------------------------ 62

边界框覆盖 -----------------------------------62

边界框中的边界框 -----------------------------63

小结--------------------------------------------- 64

第五章: 向量动画--------------------------------------- 65

基本动画 ---------------------------------------66

变换路径------------------------------------------ 67

缓动类型 ------------------------------------------70

内建的缓动算法规则 ----------------------------70

使用三次贝塞尔公式的缓动 ----------------------71

动画转换 ------------------------------------------72

动画常用属性-------------------------------------- 73

常用属性 --------------------------------------73

随着一个长路径动画-----------------------------76

动画的暂停和重新开始-----------------------78

小结------------------------------------------------79

第六章: 使用已经存在的SVG文件--------------------------81

Inkscape ------------------------------------------82

下载Inkscape-----------------------------------82

开始使用Inkscape-------------------------------82

检查path------------------------------------------87

Inkscape的XML编辑器-------------------------87

从存在的SVG图片中提取path-------------------89

SVG转换到raphael对象的工具-----------------------90

Ready Set Raphael ---------------------------90

其它转换工具 ----------------------------------91

等值域图 ------------------------------------------92

创建等值域图 ----------------------------------92

开源SVG文件---------------------------------- 96

小结-----------------------------------------------96

第七章: 创建一个可视化社交媒体--------------------------97

社交媒体应用--------------------------------------- 97

开始--------------------------------------------98

使用JQeury-------------------------------------99

系统可用数据------------------------------------99

绘制人型图表-----------------------------------100

图表点击响应-----------------------------------101

绘制一把钥匙-----------------------------------102

随时间发布消息-------------------------------------103

开始-------------------------------------------104

推送的数据-------------------------------------104

(第七章这里有些专业术语,我在没读到这里之前,暂时不能获得准确的意思,抱歉,翻译到这里的时候讲把这里补充一下。)

我们从正文第一章开始讲。

Web图形

在当前浏览器的领域,图形的绘制是非常重要的。从图表到简单图片,从数学到视觉艺术,哪里都需要图形的绘制。所以浏览器对于这块功能的需求大增。所以以此衍生了很多相关技术。不止VML和SVG,HTML5 Canvas和WebGL.每个都有它们适用的领域,VML和SVG处理2D矢量图,HTML5Canvas的位图绘制以及WebGL的3D绘制渲染。

本书讲述一个开源和轻量级的JS库,Raphael,它使用SVG和VML在浏览器中绘制矢量图形。 它提供了很多非常方便的用户绘制和变换矢量图的方法,在支持直接操作DOM的同时还支持导入位图以及文本的绘制。它就是SVG和VML的优秀合体。一位内它已经将底层封装完善,我们在使用时不需要去考虑SVG和VML的方面问题,只要集中精力搞好我们的Raphael就可以了。

VML是微软设计并且在1998年提交给W3C,基于XML技术的在IE版本5+后绘制矢量图形。SVG使用W3C组织在2001自己推出的适量绘制图形技术。也是基于XML的文件组织,但是它适用于所有主流浏览器。IE在9以后的版本也开始支持SVG。

矢量图形绘制包

现在有很多比较成熟可用的矢量图形绘制JS包。除了RaphaelJS,还有两个非常流行的矢量图形绘制工具包,Paper.js和D3.js,每个都有它们各种优缺点。下面有一个简单的比较:

包名称          IE6,7,8支持            开箱即用(个人理解是开源)   低层次包(意味着你可以操作的空间更大)

Raphael           Yes                        Yes                                   Yes

D3.js               No                         No                                     No

Paper.js           No                         No                                     No

Raphael是为一个支持VML的矢量图形绘制包,其余的包都支持SVG,但是由于是高级包,在使用虽然可能简单一些,但是你操作性大减。当我们可以直接对底层内容进行操作时,你会发现我们可以做的事情要远比其它的多,当然代价就是学习周期长,难度大(实话说,如果你只是做比较普通的功能,Raphael还是非常简单的,但是对于复杂的操作有些引擎操作需要自己去实现,还是有难度的)。

 SVG说明

SVG是当今Web应用最广泛的矢量图形绘制技术。所有主流浏览器都提供了全方位的支持,甚至最新的手机浏览器都已经加入对SVG的支持。

SVG是基于XML的,就是标签对格式的。比如我们要画从坐标(50,50)的点画一个黑色实心线段到点(10,10)可以用下面的代码:

<path d="M50 50 L10 10" stroke-width="1" stroke="#000" />

除了路径path之外,SVG还支持图形绘制、文本、填充、渐变、动画以及用户绑定的事件响应。你可以在http://raphaeljsvectorgraphics.com/the-graphical-web/raw-svg/网站上查看一些SVG的例子。

Raphael基本XML语言,所以这本书看完后,你会非常熟悉一些SVG的语法,特别是和path有关的。

使用Raphael而不要直接使用SVG

撇开浏览器支持不说,有一个非常好的原因让我们使用Raphael而不是直接写原生态的SVG,因为它让矢量绘制简单更多。举个例子,我门要画一个矩形并且让它的宽度从50px动画变成100px。原生态的SVG代码:

<rect x="10" y="10" width="50" height="30">

<animate attributeType="XML"

attributeName="width"

to="100"

fill="freeze"

dur="1s" />

</rect>

我们在(10,10)坐标位置开始画一个宽50px,高30px的矩形也就是<rect>标签,然后需要在内部、嵌入一个<animate>标签,然后在animate标签里面,并且进行说明哪里要变、怎么变。还要有fill="freeze"来保持变换的形状,否则会被重置。这样看上去代码冗长而且不易操作。但是我们使用Raphael的话,只需要:

var rect = paper.rect(10, 10, 50, 30);

rect.animate({

width: 100

}, 1000);

我们的矩形创建和动画变动都更加简洁,而且如果你要变动的内容更多,那就对比更明显。另外Raphael可以很好与其它包整合,比如jQeury,这归功于Raphael声明一个全局的变量Raphael。

Raphael的应用

Raphael现在已经广泛应用在从地图制图Town Hall @ the White House event(http://askobama.twitter.com/)到网络小游戏比如Ebocs(http://www.dejapong.com/ebocs/).

Raphael特别适用于制图方面,因为RaphaelJS库为我们提供了直接操作DOM元素的能力并且我们还可以随意缩放而不担心图片的失真。你可以在http://raphaeljs.com/australia.html 找到一些很好的例子。

(接下来讲的内容是如何下载RaphaelJS并且搭建起来环境,我们在第一篇博文里面已经有说明大家可以去看那个,这里不再赘述。地址:http://www.cnblogs.com/idealer3d/p/Instant_RaphaelJS_Starter.html)。还有大家搭建项目的时候要规划好,特别是文件夹以及路径要管理规范。

第二章 使用Raphael绘制基本图形

Raphael提供了图形绘制的基本元素:形状、图片和文本。图形有预定义的矩形、圆形、椭圆以及组合图形等。图形和文本是可以填充的。变框的填充只能是单色但是可以修改。填充可以是线性也可以是渐变的。

绘制环境

要绘制图形,我们需要一个绘制的环境。我们需要创建一个空间供我们去绘制和储存。就像艺术家一样,我们需要一个画布。浏览器的视口,就是我们的画布。SVG标准把视口认为是绘制区域自己,我们一般认为浏览器区域就是视口了。我们利用Raphael去创建画布的代码如下:

var paper= Raphael(50,100,500,300);

它的效果如下:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

如上图所示,我们在视口的区域,离左上角x轴(横轴)50px,y轴(竖轴)100px的位置开始创建一个宽500,高300的矩形框,这就是我们的画布。也就是说,paper对象,就是我们的画布。我们更推荐,我们利用已经存在的dom元素来建立画布而不是直接利用视口。在这种情况下,我们的画布的位置就是相对DOM元素的位置来讲的:

<div id="my-canvas"></div>

我们可以根据如下代码来建立画布:

var paper=Raphael("my-canvas",500,300);

也就是我们根据一个DOM的id去建立画布。当然直接用Id也可以,获得DOM对象也可以:

Raphael(document.getElementById("my-canvas"),500,300);

画布坐标系

我们可以根据下面的插图来理解画布的坐标系:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

看图我们可以发现,坐标系原点在画布的左上角。(0,0)开始,x轴为从左到右,y轴为从上到下。另外如果出现负值,则位置如下:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

这里是比较好理解的,但是需要注意的是,在负值的区域是不可见的:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

Hidden:隐藏;Visible:可见的。

坐标系弄清楚以后,我们就可以开始绘制我们的图形了。

绘制基本图形

Raphael提供了矩形、圆形、椭圆的作为基本图形的预定义绘制方法。我们创建的画布对象可以调用这些方法。Rect矩形的绘制语法:

Paper.rect(x,y,width,height,[r]);

我们可以看到paper.rect共有5个参数,其中前4个为必须参数,第五个为可选参数。前两个,x,y 其实参照我们创建画布就可以理解,这里的x,y是在画布坐标系的(x,y)位置开始绘制,绘制一个宽度为第三个参数width、高度为第四个参数height的矩形。如果第5个参数设置并且大于0,则为圆角矩形。[r]以为圆角的半径。代码示例将在下面贴出。我们先讲解圆形和椭圆。圆形的绘制语法:

Paper.circle(x,y,r);

在(x,y)位置绘制一个半径为r的的圆。椭圆的语法:

Paper.ellipse(x,y,x-radius,y-radius);

在(x,y)位置绘制一个横向半径为x-radius,竖向半径y-radius的椭圆。代码如下:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Raphael Test</title>
</head>
<body>
<div id="my-canvas" style="padding:0px;margin:0px;border:solid;">
</div>
<!--some html doms-->
<!--some scripts-->
<script type="text/javascript" src="../js/lib/raphael.js">
</script>
<script type="text/javascript">
//在my-canvas节点上面创建画布
var paper = Raphael("my-canvas", 500, 300);
//在(20,20)位置创建一个宽100,高60的直角矩形
var rect = paper.rect(20, 20, 100, 60);
//在(140,20)位置创建一个宽100,高60,圆角半径10的圆角矩形
var rectR = paper.rect(160, 20, 100, 60, 10);
//在(50,150)位置绘制一个半径为40的圆形
var cir = paper.circle(50, 150, 40);
//在(150,150)绘制一个横向半径50,竖向半径35的椭圆
var ellipse = paper.ellipse(150, 150, 50, 35);
//位置提示
var tip = paper.text(5, 20, "(10,20)");
var tipR = paper.text(145, 20, "(160,20)");
var tipC = paper.text(50, 150, "(100,50)");
var tipE = paper.text(150, 150, "(100,140)");
</script>
</body>
</html>

效果图如下:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

如上图,我们在代码中有每个图形的详细解释,这里不多解释,大家可以阅读代码中的注释。这里再引用原书的椭圆图形加深理解:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

导入图片

Raphael允许我们导入位图至画布中。语法如下:

paper.image("a.png",50,50,200,200);

意味着我们在(50,50)的位置导入一个图片,图片被缩放到长200,宽200.图片的路径和名字为:"a.png"。我们在上面的那段代码中加入:

//导入图片
var agirl=paper.image("../images/mm.jpg",300,100,200,300);

效果如下:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

接下来我们继续介绍每个我们创建的元素自带的属性。

元素属性

我们绘制的图形都可以有填充、边框属性以及其它的很多属性。我们创建图形的时候,每个方法返回一个图形对象,而这些对象就可以去赋予我们想要的属性。这些对象都有一个attr()方法,里面参数为键值对(json),键为元素属性名称,值为属性取值。

填充

我们首先介绍填充属性。填充可以是基本填充或者图形填充。基本填充我们使用颜色去填充一个形状,颜色的格式可以是#rrggbb、简写#rgb、rgb(r,g,b)甚至是颜色的英文单词red、green等。我们在前面那段代码中添加如下代码测试:

  rect.attr({
fill: "#000"
});
rectR.attr({
fill:"rgb(0,0,0)"
});
cir.attr({
fill: "green"
});
ellipse.attr({
fill: "url(../images/mm.jpg)"
});

效果图如下:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

不过我们使用位图填充椭圆的时候,由于椭圆太小我们这里只有原位图的右上角被填充到了椭圆中。这里大家理解就好啦。

处理笔画(边框)

元素的笔画有很多属性,最常用的是颜色和宽度。属性的键名就是"stroke","stroke-width"。因此,我们把刚才代码中添加几行新的代码:

var newcir = paper.circle(50, 250, 40);
newcir.attr({
fill: "green",
stroke: "red",
'stroke-width': "10"
});

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

我们可以通过比叫两个圆的不同来看到stroke笔画设置的不同。这里需要知道的是,我们代码里面的笔画宽度是10,其实这个10有一半也就是5是在图形内部,而剩余的则是在图形的外面。也就是在你设置的笔画宽度的中间是图形的真是大小(准确的说,是你期望的图形大小)。其实,即便我们不设置笔画属性,我们所绘制的所有图形都有自带的笔画属性,他们的宽度是1px。如果你确实不想设置笔画属性,那么你需要显式地设置stroke-width:none。当然还有其它一些stroke属性这里没有提及,大家如果想了解可以到RaphaelJS的官方网站去查阅资料。

其它属性

      herf

      元素上面添加一个链接,允许这个dom元素扮演一个超链接的角色。当点击这个图形时,它将打开一个新的链接。(为了演示方便,我们另起一份代码,刚才的代码内容已经比较繁杂)。代码:

 var paper = Raphael("my-canvas", 500, 400);
var rect = paper.rect(30, 30, 140, 140);
rect.attr({
fill: "green",
href: "http://www.baidu.com"
});

原书上讲,这里将创建一个表现为超链接的矩形。但是我实际测试中点击并没有作用,这里我还需要找找问题。我们暂时记下来,继续往下走。

透明度

元素透明度键名opacity,取值范围为0(完全不透明)到1(完全透明),也可以分别设置stroke-opacity和fill-opacity。我们前面说过,stroke是以中心来还,一半在外,一半在内。这里就会出现副作用,因为可以分别设置透明度而导致分开设置透明度会有一些限制。这里我们不再贴代码,原书的例子很好,我就直接贴出来了:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

矩形切割

Raphael支持通过clip-rect属性来进行元素的矩形切割,它允许我们将图形切割出一部分下来。我们可以按照下面的代码来进行图形区域切割:

 var paper = Raphael("my-canvas", 500, 400);
var circle = paper.circle(100, 100, 80);
//原书是在attr里面直接加入了'clip-rect'属性,将圆的1/4切割下来,我们分开两步加入动画,以便理解。这里最终达到的效果与原书一致
circle.attr({
fill: "pink",
'stroke-width': 0,
});
circle.animate({
'clip-rect': '20,20,80,80'
}, 2000,'easeIn');

大家将这段代码替换上面那大段代码的js部分就可以看到效果了。效果如下:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)2秒后:学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

clip-rect属性的4个参数与矩形创建是一致的,x,y坐标开始宽、高定制的矩形。原书辅助解释的图:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

虚线圆就是我们创建的circle对象,粉红色的部分就是设置该属性后剩余的部分。

渐变

Raphael支持线性和梯度渐变去填充图形,要达到这个效果,而不是直接用一个颜色的字符串去设置fill属性。我们需要指定了下面这种字符串的格式去做到线性渐变:

<angle>-<color>[-<color>[:<offset>]]*-<color>

下面的语法就是达到径向渐变的效果:

r[(<fx>,<fy>)]<color>[-<color>[:<offset>]]*-<color>

好吧,我承认我也没看懂。我们来看例子帮助我这智五渣理解一下。

线性渐变

      最基本的线性渐变的格式:

<angle>-<color1>-<color2>

比如:

var rect=paper.rect(20,20,160,160);

rect.attr({

'stroke-width':0,

fill:'0-#f00-#000'

})

我们去实验一下:

            var paper = Raphael("my-canvas", 500, 400);
var rect = paper.rect(50, 50, 100, 100);
var rect1 = paper.rect(200, 50, 100, 100);
var rect2 = paper.rect(350, 50, 100, 100);
rect.attr({
'stroke-width': 0,
fill: '0-#f00-#000'
});
rect1.attr({
'stroke-width': 0,
fill: '90-#f00-#000'
});
rect2.attr({
'stroke-width': 0,
fill: '45-#f00-#000'
})

还是把这段复制到js部分就可以了,我们的运行效果图:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

3个矩形,我们分别按照0度角、90度角、45度角实现从红色到黑色的渐变。嘿嘿,似乎上面那段奇怪的代码也不怎么难嘛。

注意,我们的角度计算是从x轴正方向沿逆时针方向来定义角度(--这句话其实就是说角度和我们脑子里的原始想法一致,不要去纠结其它)。

线性渐变可以有任意个数的颜色和这些颜色组成线性渐变的点,定义为offsets 。也就是有了下面的语法结构:

[-<color>[:<offset>]]*

在这里,任何个数的-color:offset组合可以用来创建。比如,我们使用下面的string来看看:

fill:"0-#00a9e0-#323490:20-#ea1688:40-#eb2e2e:60-#fde92d:80-#009e54"

我们用上面那行字符串可以建立一个彩虹样式的矩形,每个颜色相比前一个颜色多占据20%。下面的字符串可以达到相同效果:

"0-#00a9e0-#323490-#ea1688-#eb2e2e-#fde92d-#009e54"

这里只要把字符串贴到上面我们js代码的fill属性就行了,就不再截图举例了。

径向渐变

径向渐变与线性渐变相似,但是径向渐变绘制的时候是放射式的,从一个点开始(默认图形的中心点),最基本的径向渐变的语法:

r<color>-<color>

比如,我们在代码里面加入:

    var paper = Raphael("my-canvas", 500, 400);
var circle = paper.circle(150, 150, 100);
circle.attr({
'stroke-width': 0,
fill: 'r#f00-000'
})

我们可以得到:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

我们得到一个从中心为红色渐变到边缘为黑色的圆形。根据我们上面线性渐变的描述,我们根据offsets属性去“分段”定义颜色渐变,我们试验一下径向渐变的offsets效果:

  circle.attr({
'stroke-width': 0,
fill: 'r#f00-000:80-#f00'
})

我们把上面的circle对象attr方法修改为上面的这句,效果如下:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

呶?看出来区别了吧。那么估计有童鞋要问了,我不想从中心点开始画啊,我想随意的点,记得前面语法出现的fx和fy吗,它们就是来做这个的。这里我就不详细举代码例子了,袁术的配图真是不错,一看就可以明白:

学习RaphaelJS矢量图形包--Learning Raphael JS Vector Graphics中文翻译(一)

我们发现我在r命令后面的括号里面添加好fx和fy的值,可以获得不同效果。fx和fy很容易能看出来取值范围为[0,1],其实就是中心点在图形的x和y最大值的比例位置。这里很容易理解,不多做解释了。

最后,提一点,path对象是不能用径向渐变的。这是因为VML在这里有bug,所以这里的径向渐变只适用于基本图形。