现有绘图控件存在的问题
在传统的网页应用中,报表是很重要的一块呈现内容,而其中的图表控件更能够直观的反应各种数据。随着混合模式手机应用的推广,相应的图表控件也需要在手机上进行呈现,这就引起了一些在手机环境下才会产生的问题。
所以开发者如果可能掌握一种自由度更高的绘图方法,在有特殊的情况下使用它,就可以让图表在手机端更好的展示了。HTML5 中的 CANVAS 就是一个很好的应用编程接口,通过它可以在手机端完成各种复杂的需求。
CANVAS 提供的基本功能CANVAS 最早是应用在苹果系统中,用于绘制仪表盘等控件的。在 HTML5 标准中,它不但可以快速的绘制图像,还可以提供各种便利的接口,提高开发者的编码效率。它其实是在浏览器中开辟了一块独立的区域用于开发者绘制图片,在这块区域里面开发者可以通过系统提供的 API 进行诸如直线、圆弧、曲线等基本图形的绘制;也可以通过接口显示文字和图形;更高级的是可以通过操作区域中的每个像素点,设定图形的颜色和透明度等信息。从现有的情况来看,CANVAS 的功能是很强大的,几乎可以实现各种高级的绘图功能。
浏览器性能检测虽然现在流行的浏览器都支持 CANVAS 这个功能,但是为了避免错误,在使用 CANVAS 之前可以判断浏览器是否支持这个控件,只需要简单的检测可否获得画布的上下文即可。
CANVAS 和 CSS虽然在 CANVAS 绘图时,可以动态指定各种颜色和大小,但是 CANVAS 作为基本的元素还是可以指定它的边框、边距、缩进等等属性;同时,CANVAS 中一些元素的属性会默认继承 CANVAS 的 CSS 属性,比如文字的默认属性就是从 CANVAS 中继承来的。在此基础上,CSS 设定各个元素的方法在 CANVAS 中也同样适用,所以熟悉 CSS 对于在 CANVAS 中设定各个值会有很大的帮助。
描绘基本图形在 CANVAS 中描绘基本图形就像在一个指定的坐标轴内画图一样,不过这个坐标轴的方向和正常的坐标轴有所不同,图 1 是一个 CANVAS 的坐标轴系统,它的 Y 轴朝下 X 轴朝右,而普通的坐标系统 Y 轴方向是向上的。
图 1. CANVAS 坐标轴平移坐标轴在几何中,研究者可以通过平移坐标轴来简化问题,那么在使用 CANVAS 绘制图表时,开发者也可以通过类似的方式来重用一些函数。比如在应用中可能需要绘制多个柱状图,利用平移坐标轴,就可以把柱状图的左下角统一作为坐标系的零点进行考虑,这样图形只需要考虑柱状图的长宽,而不需要涉及在整张图中与零点的位置了。清单 1 中的三行代码说明了三个步骤:首先记录绘图的上下文,然后把坐标轴平移到一个位置(此时 chartX 和 chartY 就成为了新坐标轴的零点),绘制完成图像后再重置上下文,便又回到了原始系统。这个代码会在下面的实例中体现出很大的作用。
清单 1. 平移代码context.save(); context.translate(chartX, chartY); // draw code context.restore(); 使用渐变和图片
在图表中有时候会用到一些已有的图片,比如用户的头像、商品的等级,这时候就需要利用 CANVAS 读入这些图片,然后把它们展现在区域中,这会让图表显得更加生动。至于渐变在目前的应用中用到较少,主要原因是没有好的应用场景。
文字一般的图表都会用到文字,用于直观的描述一些信息。普通的文字呈现是简单的,类似在 CSS 中定义文字的大小、字体、颜色等就可以描绘出来;在高级应用中,需要让文字进行旋转,从而更好的符合整体图形的呈现。
事件监听CANVAS 和普通的元素一样也可以进行事件监听,比如点击、移动。通过进行监听不同的事件,可以进行一些高级的处理。比如监听按下、移动和释放事件,就能模拟用户拖拽的事件了。在 CANVAS 中监听事件需要注意的是用户点击时在 CANVAS 中的坐标和在整个浏览器中坐标的转换,在接下来的实例中会详细介绍。
列举了那么多 CANVAS 提供的基础功能后,本文的余下部分将通过一个实例来具体展现各个功能的在代码中的调用情况,便于读者在开发过程中利用 CANVAS 绘制高级图像。
实例解析为了更好的展现 CANVAS 的不同功能,实例中的图像较为复杂,在实际的图表中只需要涉及其中的一部分。整个例子有五部分功能,分别是:图表初始化、用户信息描绘、球队描绘、能力描绘和信息查看。
图表初始化手机的长宽区别较大,为了更好的利用手机提供的屏幕大小,应用在初始化的时候需要确认 CANVAS 的高度和宽度。清单 2 描述了完成这个功能的代码。
清单 2. 初始化 CANVASthis._width = jQuery(window).width(); this._height = jQuery(window).height(); this._canvas = document.createElement("canvas"); jQuery("body").append(this._canvas); this._canvas.width = this._width; this._canvas.height = this._height; this._context = this._canvas.getContext("2d");;
这段代码中利用了 jQuery 框架中的一些函数,这样可以方便的获得当前窗口的宽度和高度。但是演示时会发现,在页面上会有两个滚动条,这可能是浏览器在解析 CANVAS 对象时存在的一个问题,将 CANVAS 的 display 属性设置为 block 就可以解决这个问题。当窗口初始化或者调整大小后调用这个函数,就动态的实现 CANVAS 的长宽变化,从而和窗口大小相吻合。
用户信息描绘在这部分功能中,主要实现下面的三个关键点:坐标轴的平移和旋转、图片的描绘和文字的描绘。
在电脑上浏览网页时,浏览器的长度一般是大于宽度的,所以图表是横向呈现。但是在手机上长度小于宽度,如果继续横向呈现,效果就比较差。所以实例中利用了 CANVAS 提供的旋转功能将图表横向呈现,图 2 中表述了实际屏幕和虚拟屏幕的关系。
图 2. 坐标轴平移和旋转虚拟屏幕是代码中实际画出的图形,实际屏幕是最终呈现的图形,从图 2 可以看到,虚拟屏幕在向右移动了一个屏幕宽度后,再旋转九十度就是实际屏幕的位置,所以相应的代码为清单 3 所示。
清单 3. 初始化 CANVASthis._context.save(); this._context.translate(width, 0); this._context.rotate(Math.PI / 2); this._context.restore();
可以看到清单 3 和清单 1 的代码很相似,所以为了更好的使用 CANVAS 的接口,开发者需要掌握一定的数学知识,只有这样才能完成一些必须的工作,后面的代码还将涉及。