<!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>
javascript留痕的命令模式模擬
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.