Край сглаживания.
Причина, по которой вы получаете линию ~ 1px, заключается в том, что ctx.fillRect
, который вы используете для очистки холста, преобразуется тем же преобразованием, которое использовалось для рисования прямоугольника.
Когда фигура отображается, ее края имеют сглаживание , некоторые из краевых пикселей отображаются полупрозрачными, что означает, что при рисовании в этом же поле некоторые оригинальные пиксели останутся позади.
Для исправления
- Сбросьте преобразование по умолчанию до очистки холста.
ctx.setTransform(1,0,0,1,0,0);
- Используйте переменную для хранения общего поворота окна (см. Пример)
Используйте setTransform
для замены текущего преобразования, а не для поэтапного построения преобразования с использованием ctx.translate
и ctx.rotate
.
Основы преобразования , помогая понять, как setTransform
можно использовать для позиционирования, масштабирования и поворота визуализированных объектов в API 2D-холста.
Другие точки
- Используйте
requestAnimationFrame
вместо setInterval
для вызова анимации l oop, чтобы обеспечить максимально плавную анимацию. - Используйте один объект для хранения связанных данных , Например, объект
box
в примере содержит все соответствующие данные, необходимые для анимации блока. - Попробуйте express анимации осмысленным образом. В этом примере частота вращения блока
box.rotSpeed
устанавливается как число оборотов в секунду
Пример
requestAnimationFrame(mainLoop);
const ctx = canvas.getContext("2d")
canvas.height = canvas.width = 300;
canvas.style.backgroundColor = "#303030"
const box = {
color: "lime",
cx: 0.25, // x rotation center as fraction of box size
cy: 0.25, // y rotation center as fraction of box size
x: 150,
y: 150,
size: (150 * 150 / 2) ** 0.5, // makes diagonal size of box 150
rot: 0,
rotSpeed: 0.5, // in rotations per second
};
function drawBox(box) {
box.rot += box.rotSpeed * Math.PI / 30; // 2*PI/60 is one rotation per second at 60FPS
ctx.fillStyle = box.color;
const xa = Math.cos(box.rot);
const ya = Math.sin(box.rot);
ctx.setTransform(xa, ya, -ya, xa, box.x, box.y);
ctx.fillRect(-box.cx * box.size, -box.cy * box.size, box.size, box.size);
}
function mainLoop() {
ctx.setTransform(1, 0, 0, 1, 0, 0); // set default transform
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawBox(box);
requestAnimationFrame(mainLoop);
}
<canvas id="canvas">