Javascript 命令模式结合HTML5实现动画效果




<!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>
        //命令模式是一种封装方法调用的模式
        //命令模式的目的,把调用命令的调用者 和执行命令的接收者
        //要执行的一件事情:function1(命令1) function2(命令2) function3(命令3)
        //命令模式 必须实现接口(execute)
        //命令模式分类:简单命令模式、复杂命令模式(事物)、用闭包去封装命令模式(再加灵活的调用命令)
        //客户、调用者,接受者
        //客户创建命令,调用这个执行命令,接受者在命令执行时进行相应的操作

        //用命令模式实现简单的小游戏
        //页面上有4个按钮(up down left right) 目标对象(元素div。。。)还有一个关键按钮(回退按钮)
        //我现在有一个元素up 、 down left  right 4个命令,应该有一个集合去记录所有的命令
        /**
         *
         * @type {BH.Interface}
         */
        //有一个命令接口 两个方法 一个是执行命令  还有一个是回退命令
        var ReversibleCommandInterface = new BH.Interface('ReversibleCommandInterface',['execute','undo']);
        //命令对象的类  参数传递的是接受者(cursor)
        //把命令对象叫做调用者
        var MoveUp = function (cursor) {
            this.cursor = cursor;
        }
        MoveUp.prototype = {
            constructor:MoveUp,
            execute:function () {
                //真正的接收者调用自己的move方法(x轴,y轴)
                this.cursor.move(0,-10);
            },
            undo:function () {
                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);
            },
            undo:function () {
                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);
            },
            undo:function () {
                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);
            },
            undo:function () {
                this.cursor.move(-10,0);
            }
        }
        //当前接受者(也就是操作的方法的对象)
        //Cursor
        var Cursor = function (width,height,parent) {
            //宽高代表外层div(canvas画布)
            this.width = width;
            this.height = height;
            this.position = {
                x:width/2,
                y:height/2
            };
            //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.fillStyle = 'red';//填充红色
            this.move(0,0);
        }
        Cursor.prototype = {
            constructor:Cursor,
            move:function (x,y) {
                this.position.x += x;
                this.position.y +=y;
                //有一个重画的方法
                this.ctx.clearRect(0,0,this.width,this.height);//清空画布,每次重画前都要清空画布
                this.ctx.fillRect(this.position.x,this.position.y,20,20);
            }
        };

        //应该有一个命令集合【数组】:目的是为了当执行每一个命令之前  把该命令加入到集合中(push pop)
        //命令对象在执行真的操作之前  应该把该命令加入到集合中 也就是在原始命令类上加一些新的特性:特别适合  装饰者模式
        //使用装饰者模式 完成这件事情
        //当前是一个装饰类  装饰命令对象类的实例  两个参数(原始命令对象【被装饰者】,命令集合【数组】)
        var UndoDercorator = function (command,undoStack) {
            this.command = command;
            this.undoStack = undoStack;
        }

        UndoDercorator.prototype = {
            constructor:UndoDercorator,
            execute:function () {
                //执行真正命令之前  把命令加入到命令集合
                this.undoStack.push(this.command);
                this.command.execute();
            },
            undo:function () {
                this.command.undo();
            }
        }
        //完善一下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 ,undoStack) {
            this.element = document.createElement('button');
            this.element.innerHTML = label;
            parent.appendChild(this.element);
            //添加事件
            BH.EventUtil.addHandler(this.element,'click',function () {
                if(unddoStack.length===0){
                    alert('已经没有命令了,是最后一步回退操作');
                    return;
                }
               var lastCommand = undoStack.pop();
                lastCommand.undo();
            })
        };
        window.onload = function () {

            var body = document.getElementsByTagName('body')[0];
            var cursor = new Cursor(400,400,body);//接受者对象实例化出来了
            var undoStack = [];
            //客户创建命令
            var upCommand = new UndoDercorator(new MoveUp(cursor),undoStack);
            var downCommand = new UndoDercorator(new MoveDown(cursor),undoStack);
            var leftCommand = new UndoDercorator(new MoveLeft(cursor),undoStack);
            var rightCommand = new UndoDercorator(new MoveRight(cursor),undoStack);

            //创建按钮
            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 CommandButton('undo',body,undoStack);
        }
    </script>
</head>
<body>
</body>
</html>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值