-
201403李威学习月报
普通类 -
- 支持
- 批判
- 提问
- 解释
- 补充
- 删除
-
-
技术学习
学习了canvas的一些相关内容,在开发中也遇到了一些问题,下面就遇到的问题做一个小总结:
画布大小自适应
为了支持不同的终端,就必须要支持canvas画布大小的自适应,具体采用的实现方法是利用canvas的绘图表面大小与元素本身大小的不一致来实现的,当设置元素的width和height属性时,实际上是同时修改了该元素本身的大小与元素绘图表面的大小,然而,如果是通过CSS来设定canvas元素的大小,那么只会改变元素本身的大小而不会影响到绘图表面。
具体代码如下:
var POP = {
// 设置最初的长、宽属性
WIDTH: 900,
HEIGHT: 800,
RATIO: null,// 高和宽的比
currentWidth: null,//现实的宽度
currentHeight: null,//现实的高度
canvas: null,
ctx: null,
init: function() {
// 获得宽高比的值
POP.RATIO = POP.WIDTH / POP.HEIGHT;
// currentWith和currentHeight会随着窗口大小改变
POP.currentWidth = POP.WIDTH;
POP.currentHeight = POP.HEIGHT;
// 获得canvas元素
POP.canvas = document.getElementsByTagName('canvas')[0];
// 设置canvas元素的宽高
POP.canvas.width = POP.WIDTH;
POP.canvas.height = POP.HEIGHT;
// 获得绘图表面
POP.ctx = POP.canvas.getContext('2d');
// 进行自适应设置
POP.resize();
},
resize: function() {
POP.currentHeight = window.innerHeight;//获得窗口高度
// 根据窗口高度和宽高比值调整窗口的宽度
POP.currentWidth = POP.currentHeight * POP.RATIO;
if (POP.android || POP.ios) {
document.body.style.height = (window.innerHeight + 50) + 'px';
}
// 通过CSS设置canvas的宽度和高度
//注意:设置完以后,绘图表面的大小是没变的,只是元素本身的大小变了,而当绘图表面大小与canvas元素大小不一致时,浏览器会将绘图表面进行缩放以符合绘图表面的大小,从而实现自适应显示
POP.canvas.style.width = POP.currentWidth + 'px';
POP.canvas.style.height = POP.currentHeight + 'px';
//设置timeout是因为有些手机浏览器要等待一些时间才会开始反应
window.setTimeout(function() {
window.scrollTo(0,1);
}, 1);
}
};
POP.init();//初始化
window.addEventListener('resize', POP.resize, false);//增加resize事件的监听器
2. Canvas中添加事件的方式
- 是基于像素的,整个canvas在网页中就是一块画布,这块画布是基于较低层的像素来进行操作的,所以在这块画布中也就不再有节点之类的概念了,只能基于像素进行操作,那么如何为我们绘制的图像添加事件呢?js添加的事件只能是针对整个canvas画布的,并不能针对画布中的具体图像,所以只能添加类似于canvas.onclick = function(){}这样类型的事件。那么如何实现点击画布中个别图像的事件呢?
一般思路是为canvas整体绑定事件,在指定事件发生时判断事件发生的位置,然后判断该位置中的图像是什么,再去执行具体的事件,思路比较简单,但操作起来会比较难,判断的过程本身有可能很复杂,并且还要考虑效率的问题。具体可以参看http://bz5811.iteye.com/blog/1908172
该博客中提到在画布中已经有了很多个图形,在判断事件发生在哪个具体图形上时,一般采用重绘整幅图像,然后在绘制每一部分时使用context.isPoingInPath(点)方法来进行判断,但是重绘本身会降低图形显示的效率,因此对于位置比较固定的图表类图形时,也可以考虑直接进行判断,来提高效率。这两种方法也可以结合使用,不同情境具体判断。
Canvas和svg的适用场景
生成图像的原理是基于像素,而SVg则是基于形状,SVG通过XML语言描述图形的形状,无论放大或缩小都保持文本描述的形状,所以是矢量的,而canvas基于像素的,当把图像放大的话就会变模糊。canvas就是一个HTML元素,其中可以绘制很多图形,都是在这一个canvas中,而SVG所绘制的各个图形都是单独的一个元素,是DOM的一部分。- 无法对已绘制的图像进行操作、修改,也就是说获取不到canvas中的某一个图像,但是SVG可以,因为在SVG所渲染的图像中,单个的图像都是一个DOM元素,我们就可以通过CSS和js脚本进行修改和操作。不过,在canvas中我们可以记录其中各个对象的位置,想要的修改某一对象,我们只能是把原来的对象擦除,重新绘制。
- 中的某一图像“对象”无法像DOM中元素一样来添加事件,只能是通过判断当前事件的坐标是否落在该对象中来进行模拟事件模型;SVG就可以跟为DOM元素添加事件一样,为其中的每一个图像添加事件。当绘制的对象数目较少时,canvas和SVG的性能差不多,但是当数量增加之后,canvas的性能要远远优于SVG。
另外,因为svg中的元素都被增加到DOM中,因此可以被搜索引擎检索到,而canvas中绘制的所有内容都被包裹在画布之中,因此不能被搜索引擎检索到。
http://msdn.microsoft.com/zh-cn/library/ie/gg193983(v=vs.85).aspx#real_time_data 这篇文章介绍的很全,对于数据图表来说,
反思
这个月算是开学的第一个月吧,从放假状态重新调频到学校状态还是需要一点时间的,刚开始效率有点低,这点很不好,希望能够逐渐改掉这种毛病;另外,很多事情同时进行的时候,容易分不清主次,而且任务难度较大的时候容易习惯性拖延,这些都非常影响效率,必须要改掉。准备试试每天列一个任务清单,不知道好不好使,试试吧~
- 和svg的具体性能对比可以参看http://smus.com/canvas-vs-svg-performance/
-
-
- 标签:
- 进行
- canvas
- 事件
- 大小
- 判断
- svg
- 画布
- 201403
- 学习
- 月报
- 具体
- 元素
- 图像
- 李威
-
学习元评论 (0条)
聪明如你,不妨在这 发表你的看法与心得 ~