HTML 5 Canvas似乎重绘了已删除的部分

我在jsfiddle上创建了以下代码。 目标是在单击canvas后从canvas中删除它。 实际发生的是网格被清除并完全重新绘制,其中包含已删除的旧框。 当所有给定对象都被删除时,网格只会显示为空…我很困惑! 我究竟做错了什么?

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( '' ).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 } ); }; }​ 

工作小提琴

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方法。 在内部,路径存储为子路径(线,弧等)的列表,它们一起形成一个形状。 每次调用此方法时,列表都会重置,我们可以开始绘制新的形状。

进一步阅读