(目前发现一些文章被盗用的情况,我们将在每篇文章前面添加原文地址,本文源地址:http://www.cnblogs.com/idealer3d/p/Instant_RaphaelJS_Starter2.html )

上篇博文我们讲述了使用RaphaelJS去绘制一些静态矢量图的知识,从现在开始我们来讲述如何去操作这些画好的矢量图。本篇内容对应原书的33页及以后内容。已经拿到英文原版书的同学们也可以对应着去试读这篇博文。我也是边学边写,所以如果发生一些错误翻译和理解偏差,还得请大家及时指出以便修改。

操作Raphael元素的样式

在上篇的内容中,我们已经提到了一个方法是attr()方法,是给一个Raphael图形添加样式及属性定义的方法。我们要修改一个元素的样式和属性也可以使用attr方法来进行。上篇中我们声明了一个rect对象,这里我们可以来修改它的样式:

rect.attr('fill','#ddd');

这行代码将会把我们绘制好的矩形修改成为内部填充褐色。也就是说,attr()其实相当于mysql里面的insert into语句中的on duplicate key update,没有我就添加有我就更新这样子执行方式。

      Raphael元素的变换

      Raphael其实提供了好几个方法供大家调用来变换元素,但是其中几个的方法都是不推荐的。唯一推荐的元素变换方法是transform()方法。transform方法的参数与上篇最后的path命令串很相似,只不过这是transform命令串。它有4个命令:

T     平移

S     缩放

R     按角度旋转

M     变换矩阵

比如:"t100,100r30,100,100s2,2,100,100r45s1.5"

每个字母是一个命令。t是平移,r是旋转,s是缩放,m是矩阵。

也有另类的“绝对”平移、旋转和缩放:TRS。他们不会考虑到以前的变换。例如:...T100,0总会横向移动元素100px,而...t100,0会移动垂直移动如果之前有r90,则发生了垂直移动,这个后面会有强调。上面的例子可以读作“平移100,100;围绕100,100旋转30°;围绕100,100缩放两倍;围绕中心旋转45°;相对中心缩放1.5倍“。正如你可以看到旋转和缩放命令的原点坐标为可选参数,默认的是该元素的中心点。

有一点需要注意,transform方法并不改变元素本身的任何状态!无论你平移多少,transform执行后你获得坐标信息仍旧创建元素时的坐标,但是transform的参数在变化。也就是transform的内容是你可以获得的。无论你执行多少次transform,它保存着现在状态和创建状态之间的转换内容,其实transform就是元素本身的一个属性,而不是去改变元素的其它属性。

原书中不介绍m矩阵的内容,这里我们暂时也不说这个命令,有时间补上。

这里的命令也有大小写之分,也就是大小写的执行结果可能会不同。比如我们执行r90t100 和r90T100结果是不同的,我们在代码里面执行一下就一目了然了:

<!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="width:140px;padding:0px;margin:0px;">
</div>
<!--some html doms-->
<!--some scripts-->
<script type="text/javascript" src="../js/lib/raphael.js">
</script>
<script type="text/javascript">
var paper = Raphael("my-canvas", 650, 400);
var rect = paper.rect(20, 20, 60, 40).attr({
"stroke": "red"// border color of the rectangle
});
var rect1 = paper.rect(20, 70, 60, 40, 20).attr({
"stroke": "yellow"// border color of the rectangle
});
var rect2 = paper.rect(20, 20, 60, 40).attr({
"stroke": "red"// border color of the rectangle
}).transform("r90t100,0");
var rect3 = paper.rect(20, 70, 60, 40, 20).attr({
"stroke": "yellow"// border color of the rectangle
}).transform("r90T100,0");
console.log("第一个矩形坐标是:(" + rect.attr('x') + "," + rect.attr('y') + ")");
console.log("第三个矩形坐标是:(" + rect2.attr('x') + "," + rect2.attr('y') + ")");
console.log("第三个矩形的转换属性是:"+rect2.transform());
console.log("第四个矩形的转换属性是:"+rect3.transform());
</script>
</body>
</html>

效果图如下:

代码里面我们一共画了4个矩形,2个直角矩形,2个圆角矩形。我们发下代码里面创建矩形的时候,2个直角矩形的坐标是相同的,2个圆角矩形也是相同的。但是我们在创建的时候,其中一个直角和圆角矩形都执行了transform方法。直角执行了

transform("r90t100,0");

圆角执行了:
transform("r90T100,0");

   但是我们发现两个参数出了大小写不一致其余相同的,但是执行结果却大相径庭。是因为T执行了绝对平移而t是相对平移。什么意思?我想可能很多人会比较疑惑。绝对,就是无论其它什么变换我都不管不顾只会去执行我后面紧跟的参数,所以T执行的是不管你前面转了90度还是没转,我都x轴平移100px。而相对,则是我转了90度,我的头部(假设元素都有一个头部)本来朝右变成了朝下,x轴平移100px,好吧我向着x平移100px,但是实际是去y轴平移了100px,因为我本来指向x轴的头部变成了y轴方向。我在浏览器控制台打印了4句话,分别是2个直角矩形的坐标和2个矩形转换后的transform的值。我们发现不论是不是发生了变换,并不改变元素的本身其它属性。那么转换属性是怎么在dom里面体现的?我们通过firebug的dom查看机制来查看一下:

我们的svg标签里面建立了4个rect节点,后面2个有transfrom属性,里面的值存储在一个矩阵里面。但是其它的属性你比较一下就会发现没发生改变,got it?

下面贴个动画变动的代码,有兴趣的同学可以执行一下,因为我截图无法体现动画效果,就不截图了。

<!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="width:140px;padding:0px;margin:0px;">
</div>
<!--some html doms-->
<!--some scripts-->
<script type="text/javascript" src="../js/lib/raphael.js">
</script>
<script type="text/javascript">
var paper = Raphael("my-canvas", 650, 400);
var rect = paper.rect(20, 20, 60, 40).attr({
"stroke": "red"// border color of the rectangle
});
rect.animate({
transform: "r90t100,0s1.5"
}, 1000);
// rect.animate({
// transform:"r90T100,0s1.5"
// },1000);
</script>
</body>
</html>

上面的动画能够很清晰的看到变换的过程。讲到这里,我们引出了Raphael的动画方法animate。下面我们就开始讲Raphael图形的动画效果。

Raphael图形的动画效果

Raphael的图形动画效果可以达到非常平滑的程度,并且任何属性都可以,不论是颜色、透明度、宽度、高度还是其它细节。如果运行了上面那段小程序的,你就能感觉到了。简单的方法,简单的参数,却收获了很好的效果。Raphael的动画效果方法是animate(),语法如下:

Element.animate({动画属性的键值对},动画时间,缓动类型,回调函数);

缓动类型其实就是动画过渡公式,是哪种类型的。主要有以下这些类型:

  • “linear”(线性)
  • “<”或“easeIn”或“ease-in” (由慢到快)
  • “>”或“easeOut”或“ease-out”(又快到慢)
  • “<>”或“easeInOut”或“ease-in-out”(由慢到快再到慢)
  • “backIn”或“back-in”(开始时回弹)
  • “backOut”或“back-out”(结束时回弹)
  • “elastic”(橡皮筋)
  • “bounce”(弹跳)

具体类型大家其实根据上面那个代码就可以试验一下。动画时间是动画的持续时间,毫秒为单位。回调函数是动画执行完成后调用的函数。

   rect.animate({transform: "r90t100,0s1.5"}, 1000,"bounce",function(){console.log("finish");});

大家可以将上面我那段代码的动画效果改成上面这句话来看一下效果,发现矩形在变换过去之后会像小球落地一样跳几下才停下来。并且动画完成后会执行回调函数,在firebug控制台打印finish。其它的几个效果,大家复制上面类型的内容到bounce位置替换它就可以了。

这里需要注意的是,开始那个动画效果的键值对,里面除了transform还是可以其它属性,高度、宽度、填充颜色、透明度等等都可以。里面的值是动画完成后的最终属性,比如我们在键值对里面有个"width":200,其意思就是动画执行完时矩形的宽度变成200px。这个地方不要以为只有transform属性才可以,其实所有属性都可以的。不过最后还是要强调一下,尽管动画效果看上去很好玩,但是这个方法是使用代价还是很高的,它相比其它方法要消耗更多的浏览器等资源。所以要有选择地去使用这个方法,不要滥用。

小结一下,本篇到现在位置已经讲了attr()方法修改元素属性,transform()方法执行元素变化,animate()方法制造动画效果。重要的是,如果你亲自去执行了那么动画和变换,你会发现Raphael在这个方面做的非常好,动画以及变换都非常平滑,没有任何突兀的感觉。那么动画和元素变换到此为止,我们接下来就要讲到元素的事件绑定了,也就是业务开发中的核心部分,与用户的交互才是任何程序最迷人同时也是最为难开发者的地方。但是这本书,坦白地说,这个地方做的比较差。它就讲了一个click()和鼠标悬停mouseover()方法,而且都是一个例子就带过了。本书其实比较短就短在这个地方了。摊开了讲,这里讲个百八十页都没问题,但是本书就讲了一页多点。我先照着书上面的代码写个我们的测试代码贴出来:

 <script type="text/javascript">
var paper = Raphael("my-canvas", 650, 400);
var rect = paper.rect(20, 20, 60, 40).attr({
"fill": "green",
"stroke": "red" // border color of the rectangle
});
rect.click(function(){
alert("hahah!");
});

// rect.mouseover(function(){
             // alert("wow");
             // });

</script>

大家把上面任意贴出来的代码的Script内的内容换成这个即可,我们点击矩形会发生alert事件,跳出提示框:"hahah!"。其实后面那个mouseover()和mouseout()等一样处理方式。代码是不是看上去很简单?哪里有我说的那么复杂,还得百八十页才能讲明白?我这么说,是因为我从开始学习Raphael开始就一直在鼓捣事件问题并且还没搞定。我们想象一下,我可以对面前的图形做什么操作:点击、双击、左键单击、右键单击、鼠标悬停、鼠标移出、鼠标按下、鼠标摁住拖动、鼠标按下的键抬起······你也许会说这都是日常js开发中会碰到的鼠标事件,花点时间总是能搞定的?这是实话,只要你仔细去研究一下,这些都不是什么大问题。但是,如果我还要用鼠标拉长图形怎么办?我拖动图形的同时,如果覆盖或者说碰撞了别的图形怎么办?我怎么确定我的点是不是点到一个复杂图形里面了?我要点击选择一个元素然后键盘修改图形的属性能不能做到?当一个图形被另外一个图形包裹,我点击操作怎么确定是哪个元素?这里究竟有多少个坑,我想想都头大。最令人头疼的是,我刚才问的所有问题,都是我现在的工作需要解决的问题。这段话,如果你只是用Raphael去绘制图形,并不对它做什么复杂操作,那么你可以无视它了。我们还是要先把书翻译完成。为了不打断本书的翻译流程,我们的元素事件的话题将会另起一篇博文来进行讲解和探讨。

快速上手RaphaelJS--Instant RaphaelJS Starter翻译(二)的更多相关文章

  1. Kafka快速上手(2017.9官方翻译)

    为了帮助国人更好了解.上手kafka,特意翻译.修改了个文档.官方Wiki : http://kafka.apache.org/quickstart 快速开始 本教程假定您正在开始新鲜,并且没有现有的 ...

  2. 快速上手RaphaelJS-Instant RaphaelJS Starter翻译(一)

       (目前发现一些文章被盗用的情况,我们将在每篇文章前面添加原文地址,本文源地址:http://www.cnblogs.com/idealer3d/p/Instant_RaphaelJS_Start ...

  3. Netron开发快速上手(二):Netron序列化

    Netron是一个C#开源图形库,可以帮助开发人员开发出类似Visio的作图软件.本文继前文”Netron开发快速上手(一)“讨论如何利用Netron里的序列化功能快速保存自己开发的图形对象. 一个用 ...

  4. UnityShader快速上手指南(二)

    简介 前一篇介绍了如果编写最基本的shader,接下来本文将会简单的深入一下,我们先来看下效果吧 呃,gif效果不好,实际效果是很平滑的动态过渡 实现思路 1.首先我们要实现一个彩色方块 2.让色彩动 ...

  5. socket网络编程快速上手(二)——细节问题(5)(完结篇)

    6.Connect的使用方式 前面提到,connect发生EINTR错误时,是不能重新启动的.那怎么办呢,是关闭套接字还是直接退出进程呢?如果EINTR前,三次握手已经发起,我们当然希望链路就此已经建 ...

  6. socket网络编程快速上手(二)——细节问题(4)

    5.慢系统调用及EINTR 还记得前面readn和writen函数么?里面有个EINTR,现在就来谈谈这个,这个很重要. Linux世界有个叫信号的东西,感觉他就像一位隐士,很少遇到他,而他又无处不在 ...

  7. 快速上手最新的 Vue CLI 3

    翻译:疯狂的技术宅 原文:blog.logrocket.com/getting-sta- 概要:本文将指导你快速上手 Vue CLI 3,包括最新的用户图形界面和即时原型制作功能的使用步骤. 介绍 尤 ...

  8. 【Python五篇慢慢弹】快速上手学python

    快速上手学python 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多 ...

  9. 快速上手Unity原生Json库

    现在新版的Unity(印象中是从5.3开始)已经提供了原生的Json库,以前一直使用LitJson,研究了一下Unity用的JsonUtility工具类的使用,发现使用还挺方便的,所以打算把项目中的J ...

  10. Netron开发快速上手(一):GraphControl,Shape,Connector和Connection

    版权所有,引用请注明出处:<<http://www.cnblogs.com/dragon/p/5203663.html >> 本文所用示例下载FlowChart.zip 一个用 ...

随机推荐

  1. textbox button 模拟fileupload

    方案一:  <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test.asp ...

  2. EF6 CodeFirst+Repository+Ninject+MVC4+EasyUI实践(九)

    前言 这一篇我们将完成系统的权限设置功能以及不同角色用户登录系统后动态加载菜单.注意:此示例权限只针对菜单级,如果园友需要更复杂的系统权限设置,可以拓展到按钮级或属性级. 用户的登录采用Form认证来 ...

  3. 忠告初学者学习Linux系统的8点建议

    导读 新手或者说即将要入坑的小伙伴们,常常在QQ群或者在Linux论坛问一些问题,不过,其中大多数的问题都是很基础的.例如:如何给添加的用户归属用户组,复制整个文件到另一个目录下面,磁盘合理划分,甚至 ...

  4. IOS Core Animation Advanced Techniques的学习笔记(五)

    第六章:Specialized Layers   类别 用途 CAEmitterLayer 用于实现基于Core Animation粒子发射系统.发射器层对象控制粒子的生成和起源 CAGradient ...

  5. ubuntu 下安装mysql,以及配置远程登录

    安装MysQL 在Ubuntu14.04下安装MySQL比较简单,只需下面这条命令就行了: 1.输入 sudo apt-get install mysql-server 2.继续执行后,需要设定MyS ...

  6. IE下new Date不支持传参数的解决

    在FF gloogle浏览器中 用js实例化Date对象时 各种参数都可以换传啊. var date = new Date("2014-10-1 10:24:31"); var d ...

  7. PHPExcel读取Excel文件的实现代码

    <?php require_once 'PHPExcel.php'; /**对excel里的日期进行格式转化*/ function GetData($val){ $jd = GregorianT ...

  8. Android中的布局动画

    简介 布局动画是给布局的动画,会影响到布局中子对象 使用方法 给布局添加动画效果: 先找到要设置的layout的id,然后创建布局动画,创建一个LayoutAnimationController,并把 ...

  9. java基础之 序列化

    一.序列化和反序列化的概念 把对象转换为字节序列的过程称为对象的序列化.       把字节序列恢复为对象的过程称为对象的反序列化. 对象的序列化主要有两种用途: 1) 把对象的字节序列永久地保存到硬 ...

  10. UI数据库

    一.数据库 SQL: SQL是Structured Query Language(结构化查询语言)的缩写.SQL是专为数据库而建立的操作命令集, 是一种功能齐全的数据库语言. 二.数据库管理系统 数据 ...