JS: Изменение размера холста + перерисовывание элементов на холсте - PullRequest
0 голосов
/ 22 сентября 2018

Мой вопрос: как лучше всего изменить размер холста со всеми нарисованными элементами?

У меня есть 2 примера, в которых я пытался это заархивировать.

Первый работает, но не хватаетфункциональность, потому что, если бы я добавил еще много элементов для рисования, это было бы очень грязно.Во втором примере я попытался поместить все в массив и перебрать его, но он больше не изменяет размер правильно, потому что он больше не пересчитывает x, y width и height.По сути, я хочу знать, как не нужно вызывать функцию, которая вычисляет элементы x, y, width и height перед рисованием.Я хочу поместить математику в массив, и когда она отрисовывается, она пересчитывается, поэтому я просто должен убедиться, что обновляется canvas.width / height, как мне это сделать?

1stпример

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>

2-й пример

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 голосов
/ 22 сентября 2018

Наблюдение 1 : " Поскольку события изменения размера могут запускаться с высокой скоростью, обработчик событий не должен выполнять вычислительно дорогостоящие операции, такие как модификации DOM. Вместо этого рекомендуется регулировать событиеusing requestAnimationFrame, setTimeout или customEvent"Это из MDN resize

Observation 2 : при изменении размера вам необходимо связать холст, в противном случае вы получите холстundefined.

Наблюдение 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...