Я пытаюсь рисовать на холсте, используя событие перемещения мыши.
Вы можете увидеть рабочую демонстрацию на этом молниеносный Я вызываю эту функцию при движении мыши, чтобы нарисовать прямоугольник
updateDraw(e: MouseEvent) {
this.previousCoordinates = this.currentCoordinates;
this.currentCoordinates = HelloComponent.getCoordinatesOnCanvas(this.canvas.nativeElement, e);
if (this.drawingMode) {
HelloComponent.createShape(this.shapes, this.ctx, this.startCoordinates,
this.currentCoordinates, this.previousCoordinates, true);
this.endCoordinates = this.currentCoordinates;
}
}
Проблема в том, что если я двигаю мышь слишком быстро, я получаю несколько прямоугольников (я предполагаю, что чистый прямоугольник не работает, так как движение мыши слишком быстрое), как я могу избежать этого, должен быть только 1 прямоугольник в 1 перетаскивании ?
Редактировать: Я хочу иметь возможность рисовать более 1 прямоугольника, здесь я отслеживаю и очищаю предыдущие координаты
private static createShape(shape: Shapes, context: CanvasRenderingContext2D,
start: Coordinates, end: Coordinates, prev: Coordinates,
dotted: boolean) {
context.clearRect(start.x, start.y, (prev.x - start.x), (prev.y - start.y));
@Reactgular Я отредактировал, я отслеживаю и очищаю прямоугольник в функции
this.previousCoordinates = this.currentCoordinates
это сделано вовремя? Должно быть сделано после очистки прямоугольника.
@Reactgular все равно происходит то же самое (создал новый блиц) stackblitz.com/edit/angular-epezro?file=src/app/…
просто измените вызов clearRect()
на context.clearRect(0,0, context.canvas.width, context.canvas.height);
Объяснение:
Вы правы, проблема в том, что область, в которую вы отправляете clearRect
, на самом деле не включает границу. Согласно документация (выделено мной),
The CanvasRenderingContext2D.strokeRect() method of the Canvas 2D API draws a rectangle that is stroked (outlined) according to the current strokeStyle and other context settings.
Итак, чтобы очистить границу, вам действительно нужно учитывать ширину границы, когда вы пытаетесь ее очистить.
const borderWidth = 1;
const x = Math.min(start.x, prev.x) - borderWidth;
const y = Math.min(start.y, prev.y) - borderWidth;
const width = Math.abs(start.x - prev.x) + (2 * borderWidth);
const height = Math.abs(start.y - prev.y) + (2 * borderWidth);
context.clearRect(x, y, width, height);
или просто измените вызов clearRect()
на context.clearRect(0,0, context.canvas.width, context.canvas.height);
@Randy Casburn Это хороший момент, но я хочу иметь возможность рисовать более 1 прямоугольника за раз
@Vlad274 Отлично, спасибо!
@dota2pro — Что вы обнаружите (скорее всего), так это то, что чем больше вы будете рисовать на холсте, тем чаще вы будете сталкиваться с подобными артефактами. Лучше всего использовать два элемента холста. Один из них является активным холстом для рисования, а второй — холстом постоянного отображения. Холст для рисования получает описанную здесь обработку, но готовый рисунок затем закрашивается в постоянный элемент холста. Много ресурсов, чтобы узнать об этом.
@RandyCasburn только что понял, что вы имели в виду, я думаю, что это сделает мою жизнь очень легкой, если у меня будет 2 холста.
Да, очень. Кроме того, я думаю, я мог бы упомянуть, что «рисующий» холст прозрачен и перекрывает «постоянный». Держу пари, ты это уже понял.
@RandyCasburn да
Это никак не связано со скоростью движения. Скорее всего, вы не отслеживаете текущее предыдущее значение.