1

jsfiddleで次のコードを作成しました。目標は、クリックされた後にキャンバスからボックスを削除することです。実際に起こることは、グリッドがクリアされ、古い場所にある削除されたボックスで完全に再描画されることです。グリッドは、指定されたすべてのオブジェクトが削除された場合にのみ空になります...私は困惑しています!私は何が間違っているのですか?

jQuery(function(){

    GridBox = new GridBox();

    GridBox.init();

    var canvas    = GridBox.canvas;

    canvas.on( 'click', GridBox.clickHandler );

});

function GridBox()
{

    this.target        = { x: 0, y: 0 };
    this.current       = { x: 0, y: 0 };
    this.boxHeight     = 50;
    this.boxWidth      = 50;
    this.width         = 500;
    this.height        = 500;
    this.context       = null;
    this.canvas        = null;

    var self = this,
        init = false,
        bw   = this.width,
        bh   = this.height,
        p    = 0,
        cw   = bw + ( p * 2 ) + 1,
        ch   = bh + ( p * 2 ) + 1;

    /**
     * Array of boxes that are painted on the grid.
     * Each box has its own x and y coordinates.
     */
    this.boxesOnGrid    = [
        { x: 2, y: 2 },
        { x: 9, y: 2 },
        { x: 5, y: 5 }
    ];

    /**
     * Initiate this object
     * @constructor 
     */
    this.init    = function()
    {
        if( !init ) {
            var canvas    = jQuery( '<canvas/>' ).attr({ width: cw, height: ch }).appendTo( 'body' );

            this.canvas     = canvas;
            this.context    = this.canvas.get( 0 ).getContext( '2d' );

            this.createGrid();

            init    = true;

        }
    };

    this.clearGrid        = function()
    {
        alert( 'clearing grid' );
        this.context.clearRect( 0, 0, 500, 500 );
    };

    /**
     * Create the grid 
     */
    this.createGrid        = function()
    {
        for( var x = 0; x <= bw; x += this.boxWidth ) {
            this.context.moveTo( 0.5 + x + p, p );
            this.context.lineTo( 0.5 + x + p, bh + p );
        }

        for( var x = 0; x <= bh; x += this.boxHeight ) {
            this.context.moveTo( p, 0.5 + x + p );
            this.context.lineTo( bw + p, 0.5 + x + p );
        }

        this.context.strokeStyle    = "#aaa";
        this.context.stroke();

        var boxes    = this.boxesOnGrid;

        this.boxesOnGrid    = [];

        for( key in boxes ) {
            var currentBox    = boxes[ key ];
            alert( 'i want to create box ' + currentBox.x + 'x' + currentBox.y );
            this.createBoxAt( currentBox.x, currentBox.y );
        }
    };

    /**
     * Find a suitable path between two boxes
     */
    this.findPath        = function()
    {

    };

    this.clickHandler    = function( event )
    {
        var clickOffset        = {
                x:    event.offsetX,
                y:    event.offsetY
            }, clickedBox    = {
                x:    Math.ceil( clickOffset.x / 50 ),
                y:    Math.ceil( clickOffset.y / 50 )
            };

        for( key in GridBox.boxesOnGrid ) {
            if( GridBox.boxesOnGrid[ key ].x === clickedBox.x && GridBox.boxesOnGrid[ key ].y === clickedBox.y ) {
                GridBox.clearGrid();
                GridBox.removeBox( key );
                GridBox.createGrid();
            }
        }

    };

    /**
     * Remove a box from the grid by removing it from the boxes array
     * and re-drawing the grid.
     */
    this.removeBox        = function( key )
    {
        alert( 'removing box ' + key );
        this.boxesOnGrid.splice( key, 1 );
    };

    /**
     * Create a box at a given coordinate on the grid
     * @param    {int} x
     * @param    {int} y 
     */
    this.createBoxAt    = function( x, y )
    {
        var box    = {
                x:    x * this.boxWidth - this.boxWidth,
                y:    y * this.boxHeight - this.boxHeight
            };

        this.createBox( box.x, box.y );
        this.saveBox( x, y );
    };

    this.createBox    = function( xpos, ypos )
    {
        this.context.rect( xpos, ypos, this.boxWidth, this.boxHeight );
        this.context.fillStyle    = '#444';
        this.context.fill();
    };

    this.saveBox    = function( x, y )
    {
        this.boxesOnGrid.push( { x: x, y: y } );
    };
}​
4

1 に答える 1

4

働くフィドル

以下に変更createBoxします。

  this.createBox    = function( xpos, ypos )
    {
        this.context.beginPath();
        this.context.rect( xpos, ypos, this.boxWidth, this.boxHeight );
        this.context.fillStyle    = '#444';
        this.context.fill();
        this.context.closePath();
    };

パスの開始/終了が正しくないため、再描画時に以前のパスがクリアされず、すべてが再び埋められます。それを回避する別の方法は、fillRect代わりに使用することです。

パスを作成する最初のステップは、beginPath メソッドを呼び出すことです。内部的には、パスは一緒に形状を形成するサブパス (線、円弧など) のリストとして保存されます。このメソッドが呼び出されるたびに、リストがリセットされ、新しい形状の描画を開始できます。

参考文献

于 2012-06-27T23:12:16.223 に答える