1.关于 this
/*
****总结:谁调用fn, this,就指向谁*****
*
* 四种调用模式:
* 1、函数调用 == window
* 2、方法调用 == 宿主
* 3、构造器 == 实例对象
* 4、上下文(间接调用) == 自由指定
*
* 函数执行时,内部的this指向才会确定,
* 函数执行时this的指向与定义无关,与调用方式有关。
* */
function fn() {
console.log( this );
}
var obj = {
fn: fn
}
var o = {
obj : {
f: fn
}
}
fn(); // window
obj.fn(); // obj
o.obj.f(); // obj
new fn(); // fn函数的实例对象
new o.obj.f(); // f函数的实例对象
fn.call( [1, 2, 3] ); // 数组
fn.apply( { val: 100 } ); // 对象
// 传入定时器的回调函数,this指向window
setTimeout( function() {
console.log( this );
}, 500);
document.getElementById( 'div' ).addEventListener( 'click', function() {
console.log( this );
} );
2.状态的保存于回滚
var canvas = document.getElementById('demoCanvas');
var pencil = canvas.getContext('2d');
/**
* 状态的保存与回滚
* 1.状态可以保存多分
* 2.回滚可以回滚到最近的状态保存
*
* 状态的保存与回滚与路径无关
*
* 个人理解:
* var pencil = canvas.getContext('2d');//找一根画平面图的笔
* pencil.rect相当于素描的打底(先描一个矩形轮廓出来),
* pencil.save 类似栈:先进后出 将这次的画稿备份下,摞起来
* pencil.beginPath() 相当于是将笔抬起来准备画下一张图
* pencil.restore();//把摞起来的画稿第一章拿出来放到手写板上
* pencil.stroke();//准备工作完成,开始画图
* */
pencil.rect(10, 10, 50, 50);
pencil.save();
//清除路径
pencil.beginPath();
//回滚到上次一的保存状态
pencil.restore();
pencil.stroke();
3.判断点在不在路径上(碰撞区检测的最简化)
var canvas = document.getElementById('demoCanvas');
var pencil = canvas.getContext('2d');
/**
*判断点在不在路径上
* pencil.isPointInPath(要判断点的x轴坐标,y轴坐标)
* */
pencil.rect(10, 10, 50, 50);
pencil.stroke();
//点击画布, 判断点击的位置在不在路径上
canvas.addEventListener('click', function (e) {
var x = e.pageX - canvas.offsetLeft;
var y = e.pageY - canvas.offsetTop;
alert(pencil.isPointInPath(x, y));
})
4.工厂模式
var canvas = document.getElementById('demoCanvas');
var pencil = canvas.getContext('2d');
function Person( name, age) {
this.name = name;
this.age = age;
}
//工厂(工厂模式相当于省去new关键字)
function getPerson(name, age){
return new Person(name, age);
}
console.log(getPerson('giao','18'));
5.监听者模式:
var canvas = document.getElementById('demoCanvas');
var pencil = canvas.getContext('2d');
/**
* 监听者模式
* 适用于两个对象之间消息沟通。
*
* 将gamescene 改成一个监听者:
* 1.维护一个队列
* 2.当游戏有事件发生时(小鸟死亡)
* 3.告知听众
* */
//监听者
var jianTingZhe = {
listeners: { //听众列表
birdOver:[],
birdFlappy:[],
birdRotate:[]
},
//小鸟死亡触发时,告知所有监听死亡的听众
triggerBirdOver:function () {
this.listeners.birdOver.forEach(function (listen) {
listen();
})
},
//小鸟飞翔时侯,告知所有监听死亡的听众
triggerBirdFlappy:function () {
this.listeners.birdFlappy.forEach(function (listen) {
listen();
})
},
//小鸟死亡触发时,告知所有监听死亡的听众
triggerBirdRotate:function () {
this.listeners.birdRotate.forEach(function (listen) {
listen();
})
},
};
jianTingZhe.listeners.birdOver.push(function () {
console.log("小鸟死了, 1");
});
jianTingZhe.listeners.birdRotate.push(function () {
console.log("小鸟转了, 2");
});
jianTingZhe.listeners.birdFlappy.push(function () {
console.log("小鸟飞了, 3");
});
//监听到小鸟死了
jianTingZhe.triggerBirdOver();
//监听到小鸟旋转
jianTingZhe.triggerBirdRotate();
//监听到小鸟飞翔
jianTingZhe.triggerBirdFlappy();
6.请求动画帧函数
var canvas = document.getElementById('demoCanvas');
var pencil = canvas.getContext('2d');
/**
* (function fn(){
* }())
* 立即执行函数:保护内部变量的作用*/
/**
* 请求动画帧函数, 这个函数和setTimeOut方法使用类似
* setTimeout 可以自由指定回调的触发时间
* requestAnimationFrame函数回调的触发时由浏览器控制的
*
* requestAnimateFrame(callBack)
* 备注:当浏览器重绘页面时,会调用这个callback
* 这样callback的执行就会比较稳定,适合做流畅的动画
*/
// (function con() {
// console.log(1);
// setTimeout(con, 50);
// }())
(function con() {
console.log(111);
requestAnimationFrame(con);
}())