2012-06-27 1 views
1

Я создал следующий код на jsfiddle. Цель состоит в том, чтобы удалить окно с холста после его нажатия. На самом деле происходит то, что сетка очищается и полностью перерисовывается с удаленной коробкой в ​​старом месте. Сетка останется пустой, когда все данные объекты будут удалены ... Я озадачен! Что я делаю не так?HTML 5 Холст, похоже, перерисовывает удаленные части

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 }); 
    }; 
}​ 
+0

Что вы имеете в виду коробки все еще находятся в массиве? В 'createGrid()' я превращаю 'this.boxesOnGrid' в пустой массив:' [] '. // ninja edit for spelling –

+0

Предупреждение о методе 'clearGrid' никогда не появляется, что означает, что ваш оператор if в методе' clickHandler' никогда не возвращает true, даже когда вы нажимаете на поле, поэтому, пожалуйста, перепроверьте свою математику о том, как вы узнаете, коробка была нажата. – Delta

+0

Просто нажмите один из серых ящиков, он показывает, когда я это сделаю. –

ответ

4

Working Fiddle

Изменение 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(); 
    }; 

Ваш не правильно начинать/окончание пути, так что предыдущий путь Isnt очищается, когда вы перекроить таким образом, заполняя их все снова. Другой способ - просто использовать fillRect.

Первым шагом для создания пути является вызов метода beginPath. Внутренне пути сохраняются в виде списка подпутей (линий, дуг и т. Д.), Которые вместе образуют форму. Каждый раз, когда вызывается этот метод, список сбрасывается, и мы можем начинать рисовать новые фигуры.

Further Reading

+0

Большое вам спасибо! –

+1

np :) Я знаю, что такие вещи могут вызвать много разрывов волос. – Loktar

Смежные вопросы