Raphaël-JavaScript Library-javascript矢量绘图

你是不是经常究竟在用到javascript绘图时纠结于IE的不支持canvas,纠结于canvas绘图API的繁琐纠结?现在你可以从这种纠结中摆脱出来了。

对,Raphaël是一款轻量的用于web的矢量绘图javascript库,用它你可以很简单的创建各类矢量图形,而且它本身还支持丰富的接口以及各种事件处理。更关键的是它绘出的图像都是矢量的。当然你也可以创建一个包含位图的图像。

Raphaël是使用SVG和VML进行绘图的,所以不要担心兼容性,它支持FireFox3.0+,Chrome5.0+,Opera9.0+以及Internet Explorer6.0+,对你没看错,它完美支持IE6+。而且Sencha Labs也使用了这个库。

怎么样心动了吧?心动不如行动,赶快拿起手中的电话订购吧,呃,赶快用你的鼠标点击下载使用吧!

简单的使用方法:

// Creates canvas 320 × 200 at 10, 50
var paper = Raphael(10, 50, 320, 200);
// Creates circle at x = 50, y = 40, with radius 10
var< circle = paper.circle(50, 40, 10);
// Sets the fill attribute of the circle to red (#f00)
circle.attr("fill", "#f00");
// Sets the stroke attribute of the circle to white
circle.attr("stroke", "#fff");

这里是我写的一个示例文件,点击查看

官方网址

官方使用手册

转载请注明原文出处《Raphaël-JavaScript Library-javascript矢量绘图》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

commonjs-module1.1.1-draft-中文版

Contract 约定

Require

    o

  1. requrie是一个函数
      o

    1. require函数接受一个模块标识符
    2. o

    3. require返回外部模块的输出API
    4. o

    5. 如果有一个依赖循环,那么外部模块在它被另外一个依赖请求时,可能并没有完成执行;在这种情况下,在调用require请求当前模块执行之前,require返回的对象必须至少包含外部模块准备好的输出接口。
    6. o

    7. 如果请求的模块无法获取,require必须抛出一个错误
    8. o

    9. require函数可以有一个main属性
        o

      1. 这个属性可行时,应该是只读的且不能被删除
      2. o

      3. main属性必须是undefined或者与一个已加载的模块上下文中的module相等
    10. o

    11. require函数可以有一个paths属性,它是一个优化过的路径字符串数组,从高到低,到最顶层的模块路径。
        o

      1. paths属性不能存在在沙箱(sandbox,一种安全的模块系统)中
      2. o

      3. paths属性必须在所有模块中的引用必须一致
      4. o

      5. 使用替换对象取代paths属性可能没有任何作用
      6. o

      7. 如果paths属性存在,paths属性内容的修改必须被相应模块的搜索行为所体现
      8. o

      9. 如果paths属性存在,它可能不是一个搜索路径的详细清单,加载器可能在提及的路径之前或之后在内部查找其他位置
      10. o

      11. 如果paths属性存在,它是加载器解决,标准化及规范化提供的路径的优先选择。

Module Context 模块上下文

    o

  1. 在模块中有一个符合上述定义的自由变量require
  2. o

  3. 在模块中有一个自由变量exports,模块可以向其添加自己的API作为自己的执行方法。
      o

    1. 模块必须使用exports对象作为对外的唯一途径
  4. o

  5. 在模块中必须要有个自由变量,module对象
      o

    1. module对象必须有一个id属性作为顶层的模块id。这个id属性必须能够通过使用require(module.id)返回module.id来源所对应的导出对象。
    2. o

    3. module对象可以有一个uri字符串,它应该是一个合格的指向模块被创建的资源的URI(统一资源标示符).uir属性不应该出现在沙箱中。

Module Identifiers 模块标示符

    o

  1. 模块的标示符(id)是一个以斜线分割的协议字符串
  2. o

  3. 一个协议必须是驼峰式的标示符,“.”或者“..”
  4. o

  5. 模块标示符可以没有文件名后缀例如“.js”
  6. o

  7. 模块标示符可以是相对路径,也可以是绝对路径。如果一个模块标示符是以“.”或者“..”开始的,那么它是相对的。
  8. o

  9. 绝对标示符用于解决概念模块命名空间的根。
  10. o

  11. 相对标示符被解决相对于requrie被写和调用的模块标示符

Unspecified 未指明
标准中留下了一下未作说明的几个要点:

    o

  1. 模块是否存储在数据库中,文件系统中,或者工厂方法,或是互换链接库
  2. o

  3. 是否支持的路径是为解决模块加载器模块标示符

转载请注明原文出处《commonjs-module1.1.1-draft-中文版》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

关于JavaScript加载的思考-建设高性能网站

JavaScript加载很多时候能够决定用户从打开页面看到页面的时间,JavaScript的加载与样式表和DOM以及图片等资源的加载既有相同之处,又有很大的不同之处。最大的不同就是JavaScript的加载完成后会立即执行并阻塞页面的渲染,这就让脚本的加载与其他资源的加载有了很大的不同。

在页面中直接引用的JavaScript会阻塞整个页面的加载,这就意味着每加载一个script标签就会有两种副作用:

    o

  1. 多占用一个Http的请求资源;
  2. o

  3. 加载完成后阻塞页面,直到JavaScript执行完毕。

HTTP/1.1的标准建议浏览器对同一个主机名只能并行下载不超过2个文件(事实上现在的浏览器的限制的数目都超过2个),这就意味着你引用的文件越多页面加载的速度将会变得越慢,因为很多文件都处于等待下载的状态中。要解决HTTP请求这个问题可以从两个方面着手:

    o

  1. 从多个主机名加载资源,这个可以使用多个二级域名的办法来实现,但是增加的引用文件的混乱程度;
  2. o

  3. 减少引用的资源数目。

具体到JavaScript的载入,当前比较常用的方法是使用压缩工具将多个JavaScript合并成一个文件,同时也能减小JavaScript文件的体积。另外一个是通过统一的接口加载Script资源,后台程序将请求的文件合并成一个文件输出,并按照版本号进行缓存,后台判断如果有缓存的版本且缓存未过期将直接输出缓存文件。后一种方法在wordpress中有类似的使用,但是未见wordpress进行文件的缓存,我曾经写过一个类似的实现,将在后续的文章中放出。但是这个方法也有一个问题,因为要对文件进行合并,读写操作,另外考虑到后台语言的运行效率,所以对服务器也将增加不少压力。

至于JavaScript加载过程中会阻塞页面,这个问题可以通过把JavaScript放到页面代码的最底部进行加载,这样会在页面显示完成之后在执行JavaScript。当然script标签有个defer属性,可以让script标签在页面DOM加载完成之后执行,但是由于浏览器的支持程度不同,所以使用defer属性不是一个稳妥的解决方案。

事实上当前还有一种比较流行的解决方案,就是使用JavaScript动态生成script节点,然后将其插入到文档中。动态的生成script节点插入文档的加载方式可以实现无阻塞的加载脚本资源,提高了下载的效率。通过两幅图对比一下:

图1:静态引入script标签时页面加载的时间条

静态引入script标签时页面加载的时间条

图2:动态引入script标签时页面加载的时间条

图3:使用后台程序(PHP)合并之后输出

通过一次的测试并不能证明载入速度的快慢,所以载入时间在这里是无意义的。但是,通过查看载入的方式可以了解到,动态加载脚本的模式下,脚本的加载未阻塞图片的加载,而传统的方式则会在脚本加载完成之后再加载下面的内容。

动态载入script节点能够解决并行下载的问题,但是并无法解决JavaScript执行阻塞的问题,上面两图时间线中土黄色部分即为脚本执行的阻塞时间,可以看到阻塞的时间甚至比加载的时间要长。上面提到了,解决这个问题的办法是把JavaScript放到文档的结尾处。如果使用script标签动态加载的话这里就很方便,可以在DOM Ready或者Page onload的时候加载脚本,或者按需加载即什么时候用到什么时候加载,这样就不会阻塞页面的渲染。当然这个加载的时机还是要慎重考虑,根据脚本的作用进行不同的调整。

抛砖引玉,如有谬误还请不吝赐教。

转载请注明原文出处《关于JavaScript加载的思考-建设高性能网站》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

JavaScript弹出窗口控件

JavaScript实现的弹出窗口是我们常用的控件之一,当然实现也有很多,这里把我写的控件整理一下发出来。

请参看API及演示页面

这里实现了五种弹出窗口,继承自BasePopBox。分别为DialogBox,FrameBox, AlertBox, ConfirmBox,ToastBox。

    o

  1. DialogBox主要用于显示一般性内容,可以传入页面中的一个Dom对象的Id,也可以是一个Dom对象或者一段HTML字符串用于显示在弹出框中。
  2. o

  3. FrameBox需要传入一个URL地址,用于在弹出窗口中显示一个iFrame页面。
  4. o

  5. AlertBox用于显示一般的提示信息,类似于JavaScript中的alert弹出框。传入的参数为需要显示的信息。
  6. o

  7. ConfirmBox用于显示需要用户需要做出判断的信息,当用户点击“确定”或者“取消”时会触发用户传入的确定事件或者取消事件。
  8. o

  9. ToastBox用于显示可以一个可以自动消失的提示信息。

另外系统还提供了一个可配置参数集合用于界面,以及自定义按钮等的配置。

这里没有使用同一个对象,通过传入不同状态参数的方式来实现不同效果的弹出窗口,而是通过采用继承自相同的父对象,在子对象中通过重载相关的方法来实现不同的效果。这样提高组件的可重用性和可扩展性,甚至如果你的页面只需要一种弹出窗口你可以只引用一种弹出窗口的实现,相应的也减少了文件的体积。

在易用性方面,系统提供了基本的五种模式用于选择,基本可以满足大部分情况的需求。当然一个控件不可能同时满足所有用户的需求,所以一个控件的可扩展性也是很重要的。可以在继承基础类的基础上通过重载需要的方法来实现自己需要的效果,其它相应的处理交给基类来实现,减少开发的代码量,提高了重复使用的效率(当然需要看一下基类中有哪些方法是需要付出的代价:P)。

目前尚未做IE6的兼容测试

使用JavaScript模仿消息提示框效果(兼容IE6+,FireFox)

点击下载popbox源代码

如有谬误请不吝赐教。

2011.08.18更新

    o

  1. 修正FrameBox拖动时容易丢失mouseup事件的bug
  2. o

  3. 更新dragmanaer,添加拖动开始,进行,结束事件回调,添加setCapture和releaseCapture相关处理

转载请注明原文出处《JavaScript弹出窗口控件》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

Android学习笔记(1)—边框

在进行Android界面开发的时候,你想给TextView加个边框,找了半天发现没有这个属性,是不是有点蛋疼呢。下面就总结一下有哪些方法能够实现边框效果。

1.嵌套一层,利用内容的margin或者padding的留白加容器的背景来实现边框效果。

其实这个道理很简单,很早的时候那时候我们还用table做html页面布局的时候,我们就是使用cellspacing来实现table的边框的。现在我们也利用同样的想法来实现。

Android下实现边框效果 方案一

Android下实现边框效果 方案一

其中padding产生留白,就形成类似边框的效果。

<LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="2px" android:background="#f00">
    <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Hello world!" android:background="#000"></TextView>
</LinearLayout>

当然内部的容器也是需要有颜色的,如果想实现内部透明的效果则需要将内部View的背景色跟背景的颜色保持一致,这是不太方便的地方。

2.使用9-patch(九宫格)的背景图片来实现边框效果。

做一个有边框的9-patch图片,作为要有边框的View的背景图即可。这样你还可以控制哪边有边框,哪边无边框,这种方法是比较好的一种方法,而且没有多余的View嵌套。另外你还可以实现圆角边框等效果。

Android下实现边框效果 方案二

Android下实现边框效果 方案二

如果你还不了解关于9-patch的内容,请移步。你需要做一个有边框的png图片,使用sdk的tools文件夹下的draw9patch.bat工具,你可以轻松生成9-patch图片。工具用起来很简单。左侧和顶部的线用于扩展重复显示的内容,右侧和底部的线用于控制内容显示的位置。在这里我要先感谢国家,我们现在已经可以自由的访问Android开发者站点

3.利用shape的stroke来实现边框效果。

当然你可以使用shape中的stroke来实现border的效果。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
  <stroke android:width="1dp" android:color="#f00" />
</shape>

然后你可以引用这个shape作为背景就可以实现边框效果。关于更多关于shape的内容请移步

最终的效果展示:

当然还有很多其他的变通方法,比如你也可以添加一个view把宽度设置为1dp,作为边框。这个就需要你在实际开发中变通使用了。

本人还是Android开发的小白级人员,如有谬误还请不吝指教。

转载请注明原文出处《Android学习笔记(1)—边框》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。

避免Android内存泄露(译)

Android的应用被限制为最多占用16m的内存,至少在T-Mobile G1上是这样的(当然现在已经有几百兆的内存可以用了——译者注)。它包括电话本身占用的和开发者可以使用的两部分。即使你没有占用全部内存的打算,你也应该尽量少的使用内存,以免别的应用在运行的时候关闭你的应用。Android能在内存中保持的应用越多,用户在切换应用的时候就越快。作为我的一项工作,我仔细研究了Android应用的内存泄露问题,大多数情况下它们是由同一个错误引起的,那就是对一个上下文(Context)保持了长时间的引用。

在Android中,上下文(Context)被用作很多操作中,但是大部分是载入和访问资源。这就是所有的widget都会在它们的构造函数中接受一个上下文(Context)参数。在一个合格的Android应用中,你通常能够用到两种上下文(Context):活动(Activity)和应用(Application)。活动(Activity)通常被传递给需要上下文(Context)参数的类或者方法:

  1. @Override
  2. protected void onCreate(Bundle state) {
  3. super.onCreate(state);
  4.  
  5. TextView label = new TextView(this);
  6. label.setText("Leaks are bad");
  7.  
  8. setContentView(label);
  9. }

这就意味着那个View有一个对整个活动(Activity)的引用并且对这个活动(Activity)中保持的所有对象有保持了引用;通常它们包括整个View的层次和它的所有资源。因此,如果你“泄露”了上下文(Context)(这里“泄露”的意思是你保持了一个引用并且组织GC收集它),你将造成大量的内存泄露。如果你不够小心的话,“泄露”一整个活动(Activity)是件非常简单的事情。

当屏幕的方向改变时系统会默认的销毁当前的活动(Activity)并且创建一个新的并且保持了它的状态。这样的结果就是Android会从资源中重新载入应用的UI。现在想象一下,你写了一个应用,有一个非常大的位图,并且你并不想在每次旋转时都重新载入。保留它并且每次旋转不重新加载的最简单的办法就是把它保存在一个静态字段上:

  1. private static Drawable sBackground;
  2.  
  3. @Override
  4. protected void onCreate(Bundle state) {
  5. super.onCreate(state);
  6.  
  7. TextView label = new TextView(this);
  8. label.setText("Leaks are bad");
  9.  
  10. if (sBackground == null) {
  11. sBackground = getDrawable(R.drawable.large_bitmap);
  12. }
  13. label.setBackgroundDrawable(sBackground);
  14.  
  15. setContentView(label);
  16. }

这段代码非常快,同时也错的够离谱。它泄露了当第一次屏幕角度改变时创建的第一个活动(Activity)。当一个Drawable被附加到一个View,这个View被设置为drawable的一个回调。在上面的代码片断中,这意味着这个Drawable对TextView有一个引用,同时这个TextView对Activity(Context对象)保持着引用,同时这个Activity对很多对象又有引用(这个多少还要看你的代码了)。

这个例子是造成Context泄露的最简单的一个原因,你可以看一下我们在主屏幕源码(查看unbindDrawables()方法)中是通过在Activity销毁时设置保存过的Drawable的回调为空来解决这个问题的。更为有趣的是,你可以创建一个context泄露的链,当然这非常的糟糕。它们可以让你飞快的用光所有的内存。

有两种简单的方法可以避免与context相关的内存泄露。最明显的一个就是避免在context的自身的范围外使用它。上面的例子展示了在类内部的一个静态的引用和它们对外部类的间接引用是非常危险的。第二个解决方案就是使用Application Context。这个context会伴随你的应用而存在,并且不依赖Activity的的生命周期。如果你计划保持一个需要context的长生命周期的对象,请记得考虑Application对象。你可以非常方便的通过调用Context.getApplicationContext() 或者 Activity.getApplication()获取它。

总之,为了避免涉及到context的内存泄露,请记住如下几点:

    o

  1. 不要对一个Activity Context保持长生命周期的引用(一个对Activity的引用应该与Activity自身的生命周期相同)
  2. o

  3. 尝试使用应用上下文(context-application)代替活动上下文(context-activity)
  4. o

  5. 如果你不能控制它们的生命周期,在活动(Activity)中避免使用不是静态的内部类,使用静态类并且使用弱引用到活动(Activity)的内部。对于这个问题的解决方法是使用静态的内部类与一个弱引用(WeakReference)的外部类。就像ViewRoot和它的W内部类那么实现的。
  6. o

  7. 垃圾回收器对于内存泄露来说并不是百分百保险的。

原文地址:Avoiding memory leaks

转载请注明原文出处《避免Android内存泄露(译)》 如无特别声明,所有文章均遵守创作共用 署名-非商业-禁止演绎 3.0协议。