linaCharts开发笔记:js封装和canvas填坑

来源:互联网 发布:java md5加密与解密 编辑:程序博客网 时间:2024/06/08 14:49

js的封装,是个老生常谈的问题了,不管咋个看,和其他面向对象的语言相比,总是显得怪怪。js封装的写法,也有很多种,这里就介绍最常用的一种,也是linaCharts使用的,prototype的封装,先看代码

LinaCharts = function( canvasId ){console.log("LinaCharts 1.0.0");this.ucanvas = document.getElementById(canvasId);this.renderer = new THREE.WebGLRenderer({        canvas:this.ucanvas,        antialias:true, //设置抗锯齿    });    this.scene = new THREE.Scene();    this.camera = new THREE.PerspectiveCamera(70, 6 / 6, 10, 5000);    this.controls = new THREE.OrbitControls( this.camera, this.renderer.domElement );};LinaCharts.prototype = {constructor: LinaCharts,init:function(camera_dis){                ……        }}

js中万物皆对象(也就是木有单身狗=。=),首先我们定义了linaCharts=function(){},function也是对象。接下来介绍几个关键词this,constructor,prototype :

constructor:字面意思构造器,每个function 的prototype中都有一只constructor,保存了指向这个function的一个引用,他指向了这个对象的构造函数。说得直白点,构造函数嘛,大家都懂的,就是new的时候就要先执行的函数嘛。这里constructor: LinaCharts是惯例写法,就表示了当new 一只LinaCharts的时候,就要传入一个canvasId,然后把console 啊 this.ucanvas 啊……到this.controls的代码都跑一遍……

prototype:叫做原型,逼格很高,还有个叫prototype chain(原型链)的东东,当访问对象的属性或者方法时,将按照搜索原型链prototype chain的规则进行。首先查找自身的静态属性、方法,继而查找构造上下文的可访问属性、方法,最后查找构造的原型链。说白了就是顺藤摸瓜的意思。就是A有个西瓜init:function(),然后A告诉B "我给你讲,我有个瓜超甜",B听到后给C讲:"我给你讲,我有个瓜超甜",然后C再告诉D:"我给你讲,我有个瓜超甜",这时候D说:给我尝尝呗。然后C告诉D:“我这没西瓜,B告诉我的,我给你问问”,然后B也木有,然后B问A,A说"我有,拿去吧",然后A就西瓜给D了,D吃得很开心……优点嘛,很明显,B和C捎句话就行,不需要抱着西瓜。所以prototype的好处就是,传递的是引用,不需要每次new的时候开辟新的内存空间。所以linaCharts的方法是放在prototype里的。

最后是this,this就是函数本身。与protptype的区别就是this的东东在每次new的时候,都会开辟新的空间,所以scene,camera这些每个对象都不同的东西就放在this里的。值得一提的,this对象丢失的问题,所谓对象丢失,不是指对象真的丢了,而且this指向的对象改变了,而你却不知道。举个简单的例子:

render:function(){        console.log(this);        requestAnimationFrame(this.render);        this.renderer.render(this.scene,this.camera);        this.controls.update();},

上面代码是绘制每一帧的代码,如果这样写的话,第一次绘制是ok的,但是后面就挂了,报错,不认识this.render,阿勒……那是因为第一次指向,this指的是linaCharts,所以this.render没毛病。但是执行
requestAnimationFrame后,this的指向改变了,变成了window,所以this.render当然木有了,window哪来的render方法。所以这时候,需要使用bind();把this.renderer.render(this.scene,this.camera);改成requestAnimationFrame(this.render.bind(this)); ,就ok啦。js里bind()(注意不是jq的bind方法)的作用之一:使函数不论怎么调用都有同样的this值,在这里就是让这个this永远都是linaCharts。

好的,js封装到此结束……下面谈谈canvas……

阿勒,canvas还需要谈吗?不就是画布吗,h5新加入的标签。这里就说一点,canvas的高和宽,放在标签里和放在css里是不一样的。

也就是说

<canvas id="mainCanvas" width="400" height="400">

#mainCanvas{ width:400;height:400}

<canvas id="mainCanvas" >

你看到的图像是不一样的,所以一般情况下建议使用<canvas id="mainCanvas" width="400" height="400">这种写法。

如果想知道为啥不一样,可以参考下面文章:

http://blog.csdn.net/felix__xp/article/details/51472153




原创粉丝点击