使用javascript限制矩形仅绘制一次

时间:2014-04-08 22:18:57

标签: javascript jquery

我想仅在单击按钮时使用鼠标按下事件绘制矩形。我已经为按钮事件添加了javascript代码,但是当它单击复选框时它开始绘图时它不起作用,但即使取消选中复选框也会继续绘图。我希望这只在选中按钮时绘制。我可以将矩形限制为仅绘制一次。

我的小提琴是:http://jsfiddle.net/G6tLn/7/

我正在使用鼠标事件修改选择句柄的simonsaris代码。

请帮忙。

    <html>
<head>
<title>Canvas Demo</title>
<style type="text/css">
hr{margin:0px; padding:0px;}
form, table {display:inline; margin:0px; padding:0px;}
.ck-button {
    margin:4px;
    background-color:#8080FF;
    border-radius:4px;
    border:1px solid #D0D0D0;
    overflow:auto;
    float:left;
}
.ck-button:hover {
    background-color:#B2B2FF;
}
.ck-button label {
    float:left;
    width:4.0em;
}
.ck-button label span {
    text-align:center;
    padding:3px 0px;
    display:block;
}
.ck-button label input {
    position:absolute;
    top:-20px;
}
.ck-button input:checked + span {
    background-color:#0000FF;
    color:white;
}
   #container2 {
        position: relative;
    }

    #canvas2 {
        border: 1px solid #000;
    }
    </style>
    </head>
<body>

<canvas id="canvas2"
  width="450"
  height="450"
  style="border:2px solid black">

Your browser does not support the HTML5 canvas tag.
</canvas>
<div class="ck-button">
    <input type="checkbox" id="btnROI" value="ROI" onclick="CallRoi()">
    <span>ROI</span>


  <input type="checkbox" id="btnMetric" value="Metric" onclick="CallMetric()">
    <span>Metric</span>
</div>

<script type="text/javascript">
    // holds all our boxes
    var boxes2 = [];

    // New, holds the 8 tiny boxes that will be our selection handles
    // the selection handles will be in this order:
    // 0  1  2
    // 3     4
    // 5  6  7
    var selectionHandles = [];

    // Hold canvas information
    var canvas;
    var ctx;
    var WIDTH;
    var HEIGHT;
    var INTERVAL = 20;  // how often, in milliseconds, we check to see if a redraw is needed

    var isDrag = false;
    var isResizeDrag = false;
    var isCreationDrag = false;
    var expectResize = -1; // New, will save the # of the selection handle if the mouse is over one.
    var mx, my, startMx, startMy; // mouse coordinates

    // when set to true, the canvas will redraw everything
    // invalidate() just sets this to false right now
    // we want to call invalidate() whenever we make a change
    var canvasValid = false;

    // The node (if any) being selected.
    // If in the future we want to select multiple objects, this will get turned into an array
    var mySel = null;

    // The selection color and width. Right now we have a red selection with a small width
    var mySelColor = '#CC0000';
    var mySelWidth = 2;
    var mySelBoxColor = 'darkred'; // New for selection boxes
    var mySelBoxSize = 6;

    // we use a fake canvas to draw individual shapes for selection testing
    var ghostcanvas;
    var gctx; // fake canvas context

    // since we can drag from anywhere in a node
    // instead of just its x/y corner, we need to save
    // the offset of the mouse when we start dragging.
    var offsetx, offsety;

    // Padding and border style widths for mouse offsets
    var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop;


    // Box object to hold data
    function Box2() {
        this.x = 0;
        this.y = 0;
        this.w = 1; // default width and height?
        this.h = 1;
        this.fill = '#444444';
    }

    // New methods on the Box class
    Box2.prototype = {
        // we used to have a solo draw function
        // but now each box is responsible for its own drawing
        // mainDraw() will call this with the normal canvas
        // myDown will call this with the ghost canvas with 'black'
        draw:function (context, optionalColor) {
            if (context === gctx) {
                context.fillStyle = 'black'; // always want black for the ghost canvas
            } else {
                context.fillStyle = this.fill;
            }

            // We can skip the drawing of elements that have moved off the screen:
            if (this.x > WIDTH || this.y > HEIGHT) return;
            if (this.x + this.w < 0 || this.y + this.h < 0) return;

            context.fillRect(this.x, this.y, this.w, this.h);

            // draw selection
            // this is a stroke along the box and also 8 new selection handles
            if (mySel === this) {
                context.strokeStyle = mySelColor;
                context.lineWidth = mySelWidth;
                context.strokeRect(this.x, this.y, this.w, this.h);

                // draw the boxes

                var half = mySelBoxSize / 2;

                // 0  1  2
                // 3     4
                // 5  6  7

                // top left, middle, right
                selectionHandles[0].x = this.x - half;
                selectionHandles[0].y = this.y - half;

                selectionHandles[1].x = this.x + this.w / 2 - half;
                selectionHandles[1].y = this.y - half;

                selectionHandles[2].x = this.x + this.w - half;
                selectionHandles[2].y = this.y - half;

                //middle left
                selectionHandles[3].x = this.x - half;
                selectionHandles[3].y = this.y + this.h / 2 - half;

                //middle right
                selectionHandles[4].x = this.x + this.w - half;
                selectionHandles[4].y = this.y + this.h / 2 - half;

                //bottom left, middle, right
                selectionHandles[6].x = this.x + this.w / 2 - half;
                selectionHandles[6].y = this.y + this.h - half;

                selectionHandles[5].x = this.x - half;
                selectionHandles[5].y = this.y + this.h - half;

                selectionHandles[7].x = this.x + this.w - half;
                selectionHandles[7].y = this.y + this.h - half;


                context.fillStyle = mySelBoxColor;
                for (var i = 0; i < 8; i++) {
                    var cur = selectionHandles[i];
                    context.fillRect(cur.x, cur.y, mySelBoxSize, mySelBoxSize);
                }
            }

        } // end draw

    }

    //Initialize a new Box, add it, and invalidate the canvas
    function addRect(x, y, w, h, fill) {
        var rect = new Box2;
        rect.x = x;
        rect.y = y;
        rect.w = w
        rect.h = h;
        rect.fill = fill;
        boxes2.push(rect);
        invalidate();
    }
function CallRoi(){

    var oROI = document.getElementById("btnROI");
    console.log(oROI.checked);

    if (oROI.checked) {
        init2();

    }
}
 function CallMetric(){

    var oMetric = document.getElementById("btnMetric");
    console.log(btnMetric.checked);

    if (oMetric.checked) {
        init1();
        console.log("hello");
    }
}    

    // initialize our canvas, add a ghost canvas, set draw loop
    // then add everything we want to intially exist on the canvas
    function init2() {
        canvas = document.getElementById('canvas2');
        HEIGHT = canvas.height;
        WIDTH = canvas.width;
        ctx = canvas.getContext('2d');
        ghostcanvas = document.createElement('canvas');
        ghostcanvas.height = HEIGHT;
        ghostcanvas.width = WIDTH;
        gctx = ghostcanvas.getContext('2d');

        //fixes a problem where double clicking causes text to get selected on the canvas
        canvas.onselectstart = function () {
            return false;
        }

        // fixes mouse co-ordinate problems when there's a border or padding
        // see getMouse for more detail
        if (document.defaultView && document.defaultView.getComputedStyle) {
            stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0;
            stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0;
            styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0;
            styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0;
        }

        // make mainDraw() fire every INTERVAL milliseconds
        setInterval(mainDraw, INTERVAL);

        // set our events. Up and down are for dragging,
        // double click is for making new boxes
        canvas.onmousedown = myDown;
        canvas.onmouseup = myUp;
         canvas.ondblclick = myDblClick;
        canvas.onmousemove = myMove;


        // set up the selection handle boxes
        for (var i = 0; i < 8; i++) {
            var rect = new Box2;
            selectionHandles.push(rect);
        }

    }

    function init1() {
  canvas = document.getElementById('canvas2');
  HEIGHT = canvas.height;
  WIDTH = canvas.width;
  ctx = canvas.getContext('2d');
  ghostcanvas = document.createElement('canvas');
  ghostcanvas.height = HEIGHT;
  ghostcanvas.width = WIDTH;
  gctx = ghostcanvas.getContext('2d');

  //fixes a problem where double clicking causes text to get selected on the canvas
  canvas.onselectstart = function () { return false; }

  // fixes mouse co-ordinate problems when there's a border or padding
  // see getMouse for more detail
  if (document.defaultView && document.defaultView.getComputedStyle) {
    stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10)     || 0;
    stylePaddingTop  = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10)      || 0;
    styleBorderLeft  = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0;
    styleBorderTop   = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10)  || 0;
  }

  // make mainDraw() fire every INTERVAL milliseconds
  setInterval(mainDraw, INTERVAL);

  // set our events. Up and down are for dragging,
  // double click is for making new boxes
  canvas.onmousedown = myDown;
  canvas.onmouseup = myUp;
  canvas.ondblclick = myDblClick;
  canvas.onmousemove = myMove;

  // set up the selection handle boxes
  for (var i = 0; i < 8; i ++) {
    var rect = new Box2;
    selectionHandles.push(rect);
  }

  // add custom initialization here:


  // add a large green rectangle
  addRect(50,180,50,50, 'green');

}


    //wipes the canvas context
    function clear(c) {
        c.clearRect(0, 0, WIDTH, HEIGHT);
    }

    // Main draw loop.
    // While draw is called as often as the INTERVAL variable demands,
    // It only ever does something if the canvas gets invalidated by our code
    function mainDraw() {
        if (canvasValid == false) {
            clear(ctx);

            // Add stuff you want drawn in the background all the time here

            // draw all boxes
            var l = boxes2.length;
            for (var i = 0; i < l; i++) {
                boxes2[i].draw(ctx); // we used to call drawshape, but now each box draws itself
            }

            // Add stuff you want drawn on top all the time here

            canvasValid = true;
        }
    }

    // Happens when the mouse is moving inside the canvas
    function myMove(e) {
        if (isDrag) {
            getMouse(e);

            mySel.x = mx - offsetx;
            mySel.y = my - offsety;

            // something is changing position so we better invalidate the canvas!
            invalidate();
        } else if (isResizeDrag) {
            // time ro resize!
            var oldx = mySel.x;
            var oldy = mySel.y;

            // 0  1  2
            // 3     4
            // 5  6  7
            switch (expectResize) {
                case 0:
                    mySel.x = mx;
                    mySel.y = my;
                    mySel.w += oldx - mx;
                    mySel.h += oldy - my;
                    break;
                case 1:
                    mySel.y = my;
                    mySel.h += oldy - my;
                    break;
                case 2:
                    mySel.y = my;
                    mySel.w = mx - oldx;
                    mySel.h += oldy - my;
                    break;
                case 3:
                    mySel.x = mx;
                    mySel.w += oldx - mx;
                    break;
                case 4:
                    mySel.w = mx - oldx;
                    break;
                case 5:
                    mySel.x = mx;
                    mySel.w += oldx - mx;
                    mySel.h = my - oldy;
                    break;
                case 6:
                    mySel.h = my - oldy;
                    break;
                case 7:
                    mySel.w = mx - oldx;
                    mySel.h = my - oldy;
                    break;
            }

            invalidate();
        }

        getMouse(e);
        // if there's a selection see if we grabbed one of the selection handles
        if (mySel !== null && !isResizeDrag) {
            for (var i = 0; i < 8; i++) {
                // 0  1  2
                // 3     4
                // 5  6  7

                var cur = selectionHandles[i];

                // we dont need to use the ghost context because
                // selection handles will always be rectangles
                if (mx >= cur.x && mx <= cur.x + mySelBoxSize &&
                        my >= cur.y && my <= cur.y + mySelBoxSize) {
                    // we found one!
                    expectResize = i;
                    invalidate();

                    switch (i) {
                        case 0:
                            this.style.cursor = 'nw-resize';
                            break;
                        case 1:
                            this.style.cursor = 'n-resize';
                            break;
                        case 2:
                            this.style.cursor = 'ne-resize';
                            break;
                        case 3:
                            this.style.cursor = 'w-resize';
                            break;
                        case 4:
                            this.style.cursor = 'e-resize';
                            break;
                        case 5:
                            this.style.cursor = 'sw-resize';
                            break;
                        case 6:
                            this.style.cursor = 's-resize';
                            break;
                        case 7:
                            this.style.cursor = 'se-resize';
                            break;
                    }
                    return;
                }

            }
            // not over a selection box, return to normal
            isResizeDrag = false;
            expectResize = -1;
            this.style.cursor = 'auto';
        }

    }

    // Happens when the mouse is clicked in the canvas
    function myDown(e) {

if (document.getElementById('btnROI').checked === false) return;
        getMouse(e);

        //we are over a selection box
        if (expectResize !== -1) {
            isResizeDrag = true;
            return;
        }

        clear(gctx);
        var l = boxes2.length;
        for (var i = l - 1; i >= 0; i--) {
            // draw shape onto ghost context
            boxes2[i].draw(gctx, 'black');

            // get image data at the mouse x,y pixel
            var imageData = gctx.getImageData(mx, my, 1, 1);
            var index = (mx + my * imageData.width) * 4;

            // if the mouse pixel exists, select and break
            if (imageData.data[3] > 0) {
                mySel = boxes2[i];
                offsetx = mx - mySel.x;
                offsety = my - mySel.y;
                mySel.x = mx - offsetx;
                mySel.y = my - offsety;
                isDrag = true;

                invalidate();
                clear(gctx);
                return;
            }

        }
        // havent returned means we have selected nothing
//        mySel = null;

        addRect(mx, my, 0, 0, 'rgba(220,205,65,0.7)');
        mySel = boxes2[boxes2.length - 1];
//        console.log("box", box);
        offsetx = mx - mySel.x;
        offsety = my - mySel.y;
        mySel.x = mx - offsetx;
        mySel.y = my - offsety;
        isResizeDrag = true;
        expectResize = 7;

//        getMouse(e);
//        startMx = mx;
//        startMy = my;
        // clear the ghost canvas for next time
        // clear(gctx);
        // invalidate because we might need the selection border to disappear
        // invalidate();
    }


    function myUp(e) {
        isDrag = false;
        isResizeDrag = false;
        expectResize = -1;
        if (isCreationDrag) {
            // alert("end creation drag");
            getMouse(e);
            isCreationDrag = false;
            addRect(startMx, startMy, mx - startMx, my - startMy, 'rgba(220,205,65,0.7)');
        }
    }

    // adds a new node
    function myDblClick(e) {
        getMouse(e);
        // for this method width and height determine the starting X and Y, too.
        // so I left them as vars in case someone wanted to make them args for something and copy this code
        var width = 50;
        var height = 50;
        addRect(mx - (width / 2), my - (height / 2), width, height, 'green');
    }


    function invalidate() {
        canvasValid = false;
    }

    // Sets mx,my to the mouse position relative to the canvas
    // unfortunately this can be tricky, we have to worry about padding and borders
    function getMouse(e) {
        var element = canvas, offsetX = 0, offsetY = 0;

        if (element.offsetParent) {
            do {
                offsetX += element.offsetLeft;
                offsetY += element.offsetTop;
            } while ((element = element.offsetParent));
        }

        // Add padding and border style widths to offset
        offsetX += stylePaddingLeft;
        offsetY += stylePaddingTop;

        offsetX += styleBorderLeft;
        offsetY += styleBorderTop;

        mx = e.pageX - offsetX;
        my = e.pageY - offsetY
    }



</script>
</body>
</html>

1 个答案:

答案 0 :(得分:1)

添加此行

if(!$("#btnROI").is(":checked") || boxes2.length > 0) return;

在myDown函数的开头(小提琴的第336行),只允许绘制一个框,并且仅在检查ROI时。

更新了小提琴:http://jsfiddle.net/G6tLn/21