<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript" charset="utf-8" src="common.js"></script>
<script type="text/javascript" charset="utf-8" src="../jquery.js"></script>
<script>
//基于上一个demo做一个命令历史留痕的效果
/**
* N次命令:up up up left left down down
* 把这7次命令存到命令集合里面
* 【up up up left left】
* 当你点击回退按钮的时候 原命令集合.pop();
* 就是从原始位置开始执行命令集合
* 这次画的不是图形,画的是数显
* html: lineTo 划线
* fillStyle: 给一个图形填充颜色的
* strockStyle: 给一个线去填充颜色的
* 现在是有历史路径的了
* 开始路径的方法beginPath
* 确定位置:moveTo 移动的位置
* 画线的方法(描边:strock方法)
* */
//有一个命令接口 两个方法 一个是执行命令 还有一个是回退命
//接口中需要undo的方法,因为现在是重画集合的命令
var ReversibleCommandInterface = new BH.Interface('ReversibleCommandInterface',['execute']);
//命令对象的类 参数传递的是接受者(cursor)
//把命令对象叫做调用者
var MoveUp = function (cursor) {
this.cursor = cursor;
}
MoveUp.prototype = {
constructor:MoveUp,
execute:function () {
//真正的接收者调用自己的move方法(x轴,y轴)
this.cursor.move(0,-10);
},
}
var MoveDown= function (cursor) {
this.cursor = cursor;
}
MoveDown.prototype = {
constructor:MoveDown,
execute:function () {
//真正的接收者调用自己的move方法(x轴,y轴)
this.cursor.move(0,10);
},
}
var MoveLeft = function (cursor) {
this.cursor = cursor;
}
MoveLeft.prototype = {
constructor:MoveLeft,
execute:function () {
//真正的接收者调用自己的move方法(x轴,y轴)
this.cursor.move(-10,0);
},
}
var MoveRight = function (cursor) {
this.cursor = cursor;
}
MoveRight.prototype = {
constructor:MoveRight,
execute:function () {
//真正的接收者调用自己的move方法(x轴,y轴)
this.cursor.move(10,0);
},
}
//当前接受者(也就是操作的方法的对象)
//Cursor
//主要修改接受者对象
var Cursor = function (width,height,parent) {
//宽高代表外层div(canvas画布)
this.width = width;
this.height = height;
this.commandStack = [];
//HTML5新特性 canvas(画布的意义)
//创建一个画布,定义画布的宽高
this.canvas = document.createElement('canvas');
this.canvas.width = this.width;
this.canvas.height = this.height;
parent.appendChild(this.canvas);
//canvas 上下文元素(画布的核心对象)
this.ctx = this.canvas.getContext('2d');
//这个是描绘线的时候用的属性
this.ctx.strokeStyle = 'red';//填充红色
this.move(0,0);
}
Cursor.prototype = {
constructor:Cursor,
//只需要把当前的对象命令放到命令集合即可
move:function (x,y) {
var me = this;
this.commandStack.push(function () {
me.lineTo(x,y);
});
this.executeCommands();
},
lineTo:function (x,y) {
this.position.x += x;
this.position.y += y;
this.ctx.lineTo(this.position.x,this.position.y);
},
executeCommands:function () {
//确定当前的原始位置
this.position = {
x:this.width/2,
y:this.height/2
};
//清空当前的画布
this.ctx.clearRect(0,0,this.width,this.height);
//开始执行路径的方法
this.ctx.beginPath();
//确定当前画笔的位置
this.ctx.moveTo(this.position.x , this.position.y);
//循环遍历commandStack,每一个元素都是一个函数,都可以执行
for(var i=0;i<this.commandStack.length;i++){
this.commandStack[i]();//执行以前的命令
}
this.ctx.stroke();
},
undo:function () {
//移除最后一次命令函数即可
this.commandStack.pop();
this.executeCommands();
}
};
//完善一下html元素即可(四个按钮(命令按钮),回退按钮)
var CommandButton = function(label,command,parent){
BH.Interface.ensureImplements(command,ReversibleCommandInterface);
//实例化按钮 并放到父元素上
this.element = document.createElement('button');
this.element.innerHTML = label;
parent.appendChild(this.element);
//添加事件
BH.EventUtil.addHandler(this.element,'click',function () {
command.execute();
})
};
//回退按钮
var UndoButton = function (label , parent ,cursor) {
this.element = document.createElement('button');
this.element.innerHTML = label;
parent.appendChild(this.element);
//添加事件
BH.EventUtil.addHandler(this.element,'click',function () {
cursor.undo();
})
};
window.onload = function () {
var body = document.getElementsByTagName('body')[0];
var cursor = new Cursor(400,400,body);//接受者对象实例化出来了
//客户创建命令
var upCommand = new MoveUp(cursor);
var downCommand = new MoveDown(cursor);
var leftCommand = new MoveLeft(cursor);
var rightCommand = new MoveRight(cursor);
//创建按钮
var upButton = new CommandButton('up',upCommand,body);
var downButton = new CommandButton('down',downCommand,body);
var leftButton = new CommandButton('left',leftCommand,body);
var rightButton = new CommandButton('right',rightCommand,body);
var undoButton = new UndoButton('undo',body,cursor);
}
</script>
</head>
<body>
</body>
</html>