JS:调整画布大小+在画布上重绘元素

时间:2018-09-22 01:45:38

标签: javascript arrays object canvas resize

我的问题:用所有绘制的元素来调整画布大小的最佳方法是什么?

我有2个示例试图对此进行归档。

第一个有效,但缺少功能,因为如果我要添加更多要绘制的元素,它将变得非常混乱。在我的第二个示例中,我尝试将所有内容放入数组并循环遍历,但由于无法再计算x,y的宽度和高度,因此无法正确调整大小。基本上,我希望知道一种不必调用函数的方法,该函数在绘制之前再次计算元素x,y,宽度和高度。我想将数学放入数组中,并在绘制时 它会重新计算,因此我只需要确保canvas.width / height已更新,该怎么做?

第一个示例

class Canvas {
	constructor() {
		this.canvas = document.createElement('canvas');
		this.canvas.width = window.innerWidth;
		this.canvas.height = window.innerHeight;
		this.ctx = this.canvas.getContext('2d');
		document.body.appendChild(this.canvas);
		this.resize();
	}
	
	initAreas() {
		this.firstArea = { "x": 0, "y": 0, "w": this.canvas.width, "h": this.canvas.height / 2 }
		this.secondArea = { "x": 0, "y": this.firstArea.h, "w": this.canvas.width, "h": this.canvas.height / 2 }
	}
	
	resize() {
		this.canvas.width = window.innerWidth;
		this.canvas.height = window.innerHeight;
		this.initAreas();
		this.ctx.fillStyle = "green";
		this.ctx.fillRect(this.firstArea.x, this.firstArea.y, this.firstArea.w, this.firstArea.h);
		this.ctx.fillStyle = "red";
		this.ctx.fillRect(this.secondArea.x, this.secondArea.y, this.secondArea.w, this.secondArea.h);
	}

}

const canvas = new Canvas();

window.onresize = function() { canvas.resize(); }
body {
	padding: 0;
	margin: 0;
}

canvas {
	display: block;
}
<!DOCTYPE html>

<html>
<head>
	<meta charset="UTF-8">
	<link rel="stylesheet" href="style.css">
</head>
<body>
	<script src="script.js"></script>
</body>
</html>

第二个示例

class Canvas {
constructor() {
    this.canvas = document.createElement('canvas');
    this.canvas.width = window.innerWidth;
    this.canvas.height = window.innerHeight;
    this.ctx = this.canvas.getContext('2d');
    document.body.appendChild(this.canvas);
    this.areasToDraw = [];
    this.initAreas();
    this.resize();
}

initAreas() {
    this.firstArea = { "x": 0, "y": 0, "w": this.canvas.width, "h": this.canvas.height / 2, "color": "green" }
    this.areasToDraw.push(this.firstArea);
    this.secondArea = { "x": 0, "y": this.firstArea.h, "w": this.canvas.width, "h": this.canvas.height / 2, "color": "red" }
    this.areasToDraw.push(this.secondArea);
}

resize() {
    this.canvas.width = window.innerWidth;
    this.canvas.height = window.innerHeight;
    for(this.areas in this.areasToDraw) {
        this.ctx.fillStyle = this.areasToDraw[this.areas].color;
        this.ctx.fillRect(this.areasToDraw[this.areas].x, this.areasToDraw[this.areas].y, this.areasToDraw[this.areas].w, this.areasToDraw[this.areas].h);
    }
}

1 个答案:

答案 0 :(得分:1)

观察1 :“ 由于调整大小事件可以以很高的速率触发,因此事件处理程序不应执行计算量大的操作(例如DOM修改)。建议您限制使用requestAnimationFrame,setTimeout或customEvent 的事件” 来自MDN resize

观察2 :调整大小后,您需要绑定画布,否则您将获得未定义的画布。

观察3 :调整画布大小时,需要清空元素数组:this.areasToDraw,并用新元素重新填充数组。

这就是我要做的:

class Canvas {
constructor() {
    this.canvas = document.createElement('canvas');
    this.canvas.width = window.innerWidth;
    this.canvas.height = window.innerHeight;
    this.ctx = this.canvas.getContext('2d');
    document.body.appendChild(this.canvas);
    this.areasToDraw = [];
    //this.initAreas();
    //this.resize();
   
}

initAreas() {
    this.firstArea = { "x": 0, "y": 0, "w": this.canvas.width, "h": this.canvas.height / 2, "color": "green" }
    this.areasToDraw.push(this.firstArea);
    this.secondArea = { "x": 0, "y": this.firstArea.h, "w": this.canvas.width, "h": this.canvas.height / 2, "color": "red" }
    this.areasToDraw.push(this.secondArea);
}

resize() {
    this.canvas.width = window.innerWidth;
    this.canvas.height = window.innerHeight;
    // empty the array
    this.areasToDraw.length = 0;
    // repopulate the array
    this.initAreas();
    for(this.areas in this.areasToDraw) {
        this.ctx.fillStyle = this.areasToDraw[this.areas].color;
        this.ctx.fillRect(this.areasToDraw[this.areas].x, this.areasToDraw[this.areas].y, this.areasToDraw[this.areas].w, this.areasToDraw[this.areas].h);
    }
}

}

let canvas = new Canvas()

setTimeout(function() {
		canvas.resize()
		addEventListener('resize', canvas.resize.bind(canvas), false);
}, 15);
body {
	padding: 0;
	margin: 0;
}

canvas {
	display: block;
}