html5 canvas 添加消除矩形 可移动重置缩放

HTML5-canvas  学习
~~canvas矩形框,可创建、消除、重置
最近需要完成一个小demo:初始化一个canvas,通过鼠标的down、move、up事件来画矩形框。
查了很多资料,发现都没有我想要的。只好自己尝试写一个,下面是一些参考的网址:
http://jsfiddle.net/a7mad24/aPLq5/
废话不多直接上demo:
首先是html页面:
<!DOCTYPE html>
<html>
   
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>
            demo 1
        </title>
        <script src="jquery-1.10.2.min.js">
        </script>
        <script type="text/javascript" src="shapes.js">
        </script>
    </head>
   
    <body onload="init()">
        <div id="body">
            <div>
                <button id="reset" class="reset">
                    <span>
                        Reset
                    </span>
                </button>
                <button id="create" class="create">
                    <span>
                        Create
                    </span>
                </button>
                <button id="state" class="state">
                    <span id="txt">
                        Start
                    </span>
                </button>
            </div>
            <div id="container">
                <canvas id="canvas0" width="200" height="150" style="border: 1px solid black;background-color: rgb(94, 255, 0);">
                </canvas>
            </div>
        </div>
    </body>
    <script>
        var CanvasAry;
        var edit = false;
        function init() {
            CanvasAry = new Array();
            var canvas = document.getElementById('canvas0');
            var s = new CanvasState(canvas);
            s.addShape(new Shape(0, 0, 60, 30, 'rgba(96, 96, 96, .5)', true));
            s.addShape(new Shape(30, 30, 60, 30, 'rgba(96, 96, 96, .5)', true));
            CanvasAry[0] = s;
            start();
            end();
        }
        $(document).on('click', ".reset",
        function(event) {
            edit = false;
            $("canvas").remove();
            $("#txt").html("Start");
            var container = document.getElementById('container');
            var canvas = document.createElement('canvas');
            canvas.id = 'canvas0';
            canvas.width = 200;
            canvas.height = 150;
            canvas.style.border = '1px solid black';
            canvas.style.backgroundColor = 'rgb(94, 255, 0)';
            container.appendChild(canvas);
            init();
        });
        $(document).on('click', ".state",
        function(event) {
            var txt = $("#txt")[0].innerHTML;
            if (txt == "Start") {
                start();
            } else {
                end();
            }
        });
        $(document).on('click', ".create",
        function(event) {
            var container = document.getElementById('container');
            var l = CanvasAry.length;
            var newId = 'canvas' + (l + 1);
            var canvas = document.createElement('canvas');
            canvas.id = newId;
            canvas.width = 200;
            canvas.height = 150;
            canvas.style.border = '1px solid black';
            canvas.style.backgroundColor = 'rgb(94, 255, 0)';
            container.appendChild(canvas);
            var newS = new CanvasState(canvas);
            CanvasAry[l] = newS;
            var txt = $("#txt")[0].innerHTML;
            if (txt == "End") {
                newS.start();
            }

        });
        function start() {
            var l = CanvasAry.length;
            edit = true;
            for (var i = 0; i < l; i++) {
                CanvasAry[i].start();
                redraw(CanvasAry[i]);
            }
            $("#txt").html("End");
        }
        function end() {
            var l = CanvasAry.length;
            edit = false;
            for (var i = 0; i < l; i++) {
                redraw(CanvasAry[i]);
                CanvasAry[i].end();
            }
            $("#txt").html("Start");
        }
        function redraw(myState) {
            var ctx = myState.ctx;
            var shapes = myState.shapes;
            myState.clear();
            var l = shapes.length;
            for (var i = 0; i < l; i++) {
                var shape = shapes[i];
                shapes[i].draw(ctx);
            }
        }
    </script>

</html>

然后就是主要的js:shape.js
function Shape(x, y, w, h, fill, finished) {
    this.x = x || 0;
    this.y = y || 0;
    this.w = w || 1;
    this.h = h || 1;
    this.fill = fill || 'rgba(96, 96, 96, .5)';
    this.finished = finished;
}

Shape.prototype.draw = function(ctx) {
    ctx.fillStyle = this.fill;
    ctx.fillRect(this.x, this.y, this.w, this.h);
if(edit){
    if (this.finished) {
var img=new Image();
img.src="x_20.png";
var ix=this.x + this.w - 20;
var iy=this.y;
if(this.w<0){
ix=this.x-20;
}
if(this.h<0){
iy=this.y+this.h;
}
        ctx.drawImage(img, ix, iy, 20, 20);
    }
}
}

Shape.prototype.contains = function(mx, my) {
    return (this.x <= mx) && (this.x + this.w >= mx) && (this.y <= my) && (this.y + this.h >= my);
}

Shape.prototype.needClose = function(mx, my) {
var minx=this.x + this.w - 20;
var miny=this.y;
if(this.w<0){
minx=this.x-20;
}
if(this.h<0){
miny=this.y+this.h;
}
    return (minx <= mx) && (minx+20 >= mx) && (miny <= my) && (miny + 20 >= my);
}

function CanvasState(canvas) {
    this.canvas = canvas;
    this.width = canvas.width;
    this.height = canvas.height;
    this.ctx = canvas.getContext('2d');
    var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop;
    if (document.defaultView && document.defaultView.getComputedStyle) {
        this.stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0;
        this.stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0;
        this.styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0;
        this.styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0;
    }
    var html = document.body.parentNode;
    this.htmlTop = html.offsetTop;
    this.htmlLeft = html.offsetLeft;

    this.valid = false;
    this.shapes = [];
    this.dragging = false;
    this.isDown = false;
    this.selection = null;
    this.dragoffx = 0;
    this.dragoffy = 0;
this.rect;

    var myState = this;

var funSelectStart=function(e) {
        e.preventDefault();
        return false;
    };

var funMouseDown=function(e) {
        var mouse = myState.getMouse(e);
        var mx = mouse.x;
        var my = mouse.y;
        if (!myState.isDown) {
            var shapes = myState.shapes;
            var l = shapes.length;
            for (var i = l - 1; i >= 0; i--) {
                if (shapes[i].needClose(mx, my)) {
                    var mySel = shapes[i];
                    myState.deleteShape(mySel);
myState.draw();
                    return;
                }
                if (shapes[i].contains(mx, my)) {
                    var mySel = shapes[i];
                    myState.dragoffx = mx - mySel.x;
                    myState.dragoffy = my - mySel.y;
                    myState.dragging = true;
                    myState.selection = mySel;
                    myState.valid = false;
                    return;
                }
            }
            if (myState.selection) {
                myState.selection = null;
                myState.valid = false;
            }

var newRect=new Shape(mx, my, 0, 0, 'rgba(96, 96, 96, .5)', false);
            myState.addShape(newRect);
            myState.setRect(newRect);
            myState.setIsDown(true);
        }

    };
   
var funMouseMove= function(e) {
        var mouse = myState.getMouse(e);
        if (myState.dragging) {
            myState.selection.x = mouse.x - myState.dragoffx;
            myState.selection.y = mouse.y - myState.dragoffy;
            myState.valid = false;
        }
        if (myState.isDown) {
            var shapes = myState.shapes;
var rect=myState.rect;
            var rex = rect.x;
            var rey = rect.y;
            var rew = mouse.x - rex
            var reh = mouse.y - rey;
myState.deleteShape(rect);
var newRect=new Shape(rex, rey, rew, reh, 'rgba(96, 96, 96, .5)', false);
            myState.addShape(newRect);
myState.setRect(newRect);
        }
    };

var funMouseUp=function(e) {
        myState.dragging = false;
        if (myState.isDown) {
            var shapes = myState.shapes;
var rect=myState.rect;
            var rex = rect.x;
            var rey = rect.y;
            var rew = rect.w;
            var reh = rect.h;
myState.deleteShape(myState.rect);
var ifBadW=false;
var ifBadH=false;
if(rew>=0){
if(rew <= 2){
ifBadW=true;
}
if(rew<40){
rew=40;
}
}else{
if(rew >= -2){
ifBadW=true;
}
if(rew>-40){
rew=-40;
}
}
if(reh>=0){
if(reh <= 2){
ifBadH=true;
}
if(reh<20){
reh=20;
}
}else{
if(reh >= -2){
ifBadH=true;
}
if(reh>-20){
reh=-20;
}
}
            if (!(ifBadW&&ifBadH)){
                myState.addShape(new Shape(rex, rey, rew, reh, 'rgba(96, 96, 96, .5)', true));
            }
        }
        myState.setIsDown(false);
    };
   
this.start=function(){
canvas.addEventListener('selectstart',funSelectStart,false);
canvas.addEventListener('mousedown',funMouseDown, true);
canvas.addEventListener('mousemove',funMouseMove, true);
canvas.addEventListener('mouseup',funMouseUp,true);
};
   
this.end=function(){
canvas.removeEventListener('selectstart',funSelectStart,false);
canvas.removeEventListener('mousedown',funMouseDown, true);
canvas.removeEventListener('mousemove',funMouseMove, true);
canvas.removeEventListener('mouseup',funMouseUp,true);
};

    setInterval(function() {
        myState.draw();
    },
    myState.interval);
}

CanvasState.prototype.setIsDown = function(isDown) {
    this.isDown = isDown;
}
CanvasState.prototype.setRect = function(rect) {
    this.rect = rect;
}
CanvasState.prototype.addShape = function(shape) {
    this.shapes.push(shape);
    this.valid = false;
}

CanvasState.prototype.deleteShape = function(shape) {
this.shapes.splice($.inArray(shape, this.shapes), 1);
    this.valid = false;
}

CanvasState.prototype.clear = function() {
    this.ctx.clearRect(0, 0, this.width, this.height);
}

CanvasState.prototype.draw = function() {
    if (!this.valid) {
        var ctx = this.ctx;
        var shapes = this.shapes;
        this.clear();
        var l = shapes.length;
        for (var i = 0; i < l; i++) {
            var shape = shapes[i];
            if (shape.x > this.width || shape.y > this.height || shape.x + shape.w < 0 || shape.y + shape.h < 0) continue;
            shapes[i].draw(ctx);
        }
        this.valid = true;
    }
}

CanvasState.prototype.getMouse = function(e) {
    var element = this.canvas,
    offsetX = 0,
    offsetY = 0,
    mx, my;
    if (element.offsetParent !== undefined) {
        do {
            offsetX += element.offsetLeft;
            offsetY += element.offsetTop;
        } while (( element = element . offsetParent ));
    }
    offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft;
    offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop;
    mx = e.pageX - offsetX;
    my = e.pageY - offsetY;

    return {
        x: mx,
        y: my
    };
}
需要引入jquery-1.10.2.min.js
图片:
效果如下:
1. 初始化 不可修改。
2. 点击start 可通过叉来消除,鼠标按下、移动、松开来创建,同时矩形可通过鼠标来移动。
3. 点击end 去除叉,同时去除鼠标事件。
4. 点击reset 返回初始页面。
5. 点击create
可创建多个canvas,同时可以通过按钮来控制事件。


初级版本仅供参考,后续有升级版本,添加功能按比例缩放。 

你可能感兴趣的:(html5,canvas,矩形添加修改)