Вот немного более сложный пример, но я надеюсь, что он не только соответствует вашим конкретным потребностям, но также покажет вам некоторые другие возможные пути развития вашего решения. Я представил одну вещь. Прямоугольник отвечает за управление своим состоянием на основе итераций и введенного холста (свойств). Когда вы нажимаете кнопку «Действие», прямоугольник просто посещает каждый угол холста и циклически меняет свой размер (сначала он сжимается, затем увеличивается, а затем сжимается и так далее ...). Код содержит только базовые c проверки на предмет неправильного размера прямоугольника. Наслаждайтесь.
const button = document.getElementById('btnAction');
const canvas = document.getElementById('cnv');
const ctx = canvas.getContext('2d');
const rect = {
size: 210,
delta: -10,
iteration: 0,
getState: function getState(canvas) {
this.size += this.delta;
if (this.size <= 0) {
this.size = 0;
this.delta = 10;
}
if (this.size >= canvas.width) {
this.size = canvas.width;
this.delta = -10;
}
const corner = this.iteration % 4;
switch (corner) {
case 0:
return [0, 0, this.size, this.size];
break;
case 1:
return [canvas.width - this.size, 0, this.size, this.size];
break;
case 2:
return [canvas.width - this.size, canvas.height - this.size, this.size, this.size];
break;
case 3:
return [0, canvas.height - this.size, this.size, this.size];
break;
}
}
}
ctx.fillStyle = 'red';
ctx.fillRect(...rect.getState(canvas));
button.addEventListener('click', () => {
rect.iteration++;
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillRect(...rect.getState(canvas));
});
canvas {
border: 1px solid #000000;
display: block;
margin-bottom: 10px;
}
<div>
<canvas id="cnv" width="250px" height="250px"></canvas>
<button id="btnAction">Action</button>
</div>