javascript留痕的命令模式模拟


<!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>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值