2016-10-13 57 views
0

我正在使用canvas創建一個頁面加載器,並使用es6類......雖然目前我無法使它正常工作..其中一個原因是我無法找到一種方法來清除帆布在進展中。有沒有辦法從畫布中清除某個元素而不消除其他元素?

這是我到目前爲止的代碼:


class Loader { 

constructor (width, height) { 
    this.width = width 
    this.height = height 
} 


_init() { 
    this._createCanvas() 
    this._bindEvents() 
} 
// create canvas 
_createCanvas() { 
    this.canvas = document.createElement("canvas") 
    document.body.appendChild(this.canvas) 
    this.canvas.id = "canvas" 
    this.canvas.width = loader.width 
    this.canvas.height = loader.height 
} 

_throttle (callback, delay) { 
    let last 
    let timer 
    return function() { 
     let context = this 
     let now = +new Date() 
     let args = arguments 
     if (last && now < last + delay) { 
      clearTimeout(timer) 
      timer = setTimeout(function() { 
       last = now 
       callback.apply(context, args) 
      }, delay) 
     } else { 
      last = now 
      callback.apply(context, args) 
     } 
    } 
} 

// resize canvas 
_resizeCanvas() { 
    // resize canvas 
    var canvasRatio = this.canvas.height/this.canvas.width; 
    var windowRatio = window.innerHeight/window.innerWidth; 
    var width; 
    var height; 

    if (windowRatio < canvasRatio) { 
     height = window.innerHeight; 
     width = height/canvasRatio; 
    } else { 
     width = window.innerWidth; 
     height = width * canvasRatio; 
    } 

    this.canvas.width = width 
    this.canvas.height = height 
} 

_bindEvents() { 
// create events listeners 
    this.resizeCanvas = this._throttle(function (event) { 
     this._resizeCanvas() 
    }.bind(this), 250) 

    window.addEventListener('resize', this.resizeCanvas, false) 
} 

_unbindEvents() { 
// remove events listeners 
    window.removeEventListener('resize', this.resizeCanvas, false) 
} 


} 



class Snake { 
    constructor(options = {}) { 
    this.options = { 
     x: options.x, 
     y: options.y, 
     height: options.height, 
     width: options.width, 
     isMoving: options.isMoving || false, 
     hasDispatched: options.hasDispatched || false, 
     nextSnakeCallback: options.nextSnakeCallback || null, 
     speed: options.speed || 4 
    } 
} 

_init() { 
    this._drawSnake() 
} 
start() { 
    this.options.isMoving = true; 
} 

reset() { 
    this.options.hasDispatched = false; 
} 

setNextSnakeCallback (callback) { 
    this.options.nextSnakeCallback = callback; 
} 

_drawSnake() { 
    this.canvas = document.getElementById("canvas") 
    this.ctx = this.canvas.getContext("2d") 
    this.ctx.beginPath() 
    this.ctx.rect(
     this.options.x, 
     this.options.y, 
     this.options.width, 
     this.options.height) 
    this.ctx.fillStyle = "#f44242" 
    this.ctx.fill() 


} 

_clearSnake() { 
    this.ctx.clearRect(this.options.x, this.options.y, this.options.width, this.options.height); 

} 

} 

class SnakeTop extends Snake { 

    constructor (options) { 
    super(options) 
    } 

_init() { 
    super._drawSnake() 
    this._moveSnakeToRight() 
    super._clearSnake() 
} 

reset() { 
    this.options.x = this.options.height; 
} 

_moveSnakeToRight() { 
    if(this.options.isMoving){ 

     this._clearSnake() 
     this._drawSnake() 

     if(this.options.x > loader.width - this.options.width && !this.options.hasDispatched){ 
      this.options.hasDispatched = true; 
      if(this.options.nextSnakeCallback) { 
       this.setNextSnakeCallback() 
      } 
     } else if(this.options.x >= loader.width){ 
      this.options.isMoving = false; 
     } 

     this.options.x += this.options.speed 


    } 

    window.requestAnimationFrame(this._moveSnakeToRight.bind(this)); 
    } 

    } 


class SnakeRight extends Snake { 

    constructor (options = {}) { 
     super(options) 
    } 

_init() { 
    super._drawSnake() 
    this._moveSnakeDown() 
    super._clearSnake() 
} 

_moveSnakeDown() { 
    if(this.options.isMoving) { 
     this._clearSnake() 
     this._drawSnake() 

     if(this.options.y > loader.height - this.options.height && !this.options.hasDispatched){ 
      this.options.hasDispatched = true; 
      if(this.options.nextSnakeCallback) { 
       this.setNextSnakeCallback() 
      } 

     } else if (this.options.y > loader.height) { 
      this.options.isMoving = false 
     } 
      this.options.y += this.options.speed 
    } 
    window.requestAnimationFrame(this._moveSnakeDown.bind(this)); 

    } 
    } 


class SnakeBottom extends Snake { 

    constructor (options = {}) { 
     super(options) 
} 
_init() { 
    super._drawSnake() 
    this._moveSnakeToLeft() 
    super._clearSnake() 
} 

_moveSnakeToLeft() { 
    if (this.options.isMoving) { 

     this._clearSnake() 
     this._drawSnake() 

     if(this.options.x < 0 && !this.options.hasDispatched){ 
      this.options.hasDispatched = true 
      if(this.options.nextSnakeCallback) { 
       this.setNextSnakeCallback() 
      } 
     } else if (this.options.x < this.options.width) { 
      this.options.isMoving = false 
     } 
     this.options.x -= this.options.speed 

    } 

     window.requestAnimationFrame(this._moveSnakeToLeft.bind(this)); 
    } 

    } 


    class SnakeLeft extends Snake { 
    constructor(options = {}) { 
     super(options) 
    } 

_init() { 
    super._drawSnake() 
    this._moveSnakeUp() 
    super._clearSnake() 
} 

_moveSnakeUp() { 
    if(this.options.isMoving) { 

     this._clearSnake() 
     this._drawSnake() 

     if(this.options.y < 0 && !this.options.hasDispatched) { 
      this.options.hasDispatched = true 
      if(this.options.nextSnakeCallback) { 
       this.setNextSnakeCallback() 
      } 

     } else if (this.options.y > - this.canvas.height) { 
      this.options.isMoving = false 
     } 
     this.options.y -= this.options.speed 
    } 
     window.requestAnimationFrame(this._moveSnakeUp.bind(this)); 
    } 
    } 




// defining the elements on the DOM 

    let loader = new Loader (600, 600) 
    loader._init() 

//CREATE SNAKES 
    let snakeT = new SnakeTop ({ 
    x: - 300, 
    y: 0, 
    height: 20, 
    width: 300 
    }) 
    snakeT._init() 


//ASSIGN NEXT SNAKE callback 
    snakeT.setNextSnakeCallback (()=>{ 
    snakeR.reset(); 
    snakeR.start(); 
    }); 

    //START FIRST SNAKE 
    snakeT.start(); 

等建設其他3個元素。

你可以從的jsfiddle看,我的功能drawSnake()保留後的其他

 https://jsfiddle.net/ombqfzjq/ 

在我的研究,我發現,清除矩形溺水的矩形,而不是使用

ctx.clearRect(0,0,canvasWidth,canvasHeight); 

,清理畫布,我可以使用

ctx.clearRect(square.x,square.y,square.w,square.h); 

應該代替清潔EA ch單個矩形... 因此,在我的班級中,我建立了_clearSnake()函數,然後在需要時將其調用到我的子類。

我的邏輯有什麼問題?我如何改進我的代碼?

回答

1

一旦你在畫布上畫了一些東西,你就不能簡單地移除該對象。

Canvas'不像HTML元素那樣分層,因此刪除對象不會顯示下面的對象。

最簡潔的方法是重新繪製狀態。

+0

謝謝..有效! –