gpt4 book ai didi

javascript - 有没有办法从 Canvas 上清除一个元素而不消除其他元素?

转载 作者:行者123 更新时间:2023-12-03 05:54:01 25 4
gpt4 key购买 nike

我正在使用 Canvas 构建一个页面加载器,并使用 es6 类...虽然目前我无法使其正常工作..原因之一是我找不到一种方法来清除 Canvas 正在进行中。

这是我到目前为止的代码:

<小时/>
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);

清洁 Canvas ,我可以使用

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

应该清理每个矩形......因此,在我的 Snake 类中,我构建了 _clearSnake() 函数,然后在需要时将其调用到我的子类中。

我的逻辑有什么问题吗?如何改进我的代码?

最佳答案

一旦您在 Canvas 上绘制了某些内容,您就无法简单地删除该对象。

Canvas 不像 HTML 元素那样分层,因此删除对象不会显示下面的对象。

最干净的方法是重新绘制之前的状态。

关于javascript - 有没有办法从 Canvas 上清除一个元素而不消除其他元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40016705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com