BeginPath: примеры (JAVASCRIPT)

Функция beginPath в Canvas API: примеры применения
Раздел: Canvas, Рисование
beginPath: undefined

Основы функции beginPath в JavaScript

Метод beginPath() является частью Canvas 2D API и применяется для создания новых путей на холсте HTML5. Он не принимает аргументов и не возвращает значений. Основная задача функции — сброс текущего подпути и начало рисования новой фигуры.

При использовании контекста рисования CanvasRenderingContext2D все графические операции выполняются в рамках текущего пути. Метод beginPath() очищает список подпутей, позволяя начать построение новой фигуры. Если не вызывать эту функцию, предыдущие пути будут повторно использоваться при последующих операциях, таких как stroke() или fill().

Метод работает совместно с другими функциями для работы с путями: moveTo(), lineTo(), arc(), rect(), closePath().

Простые примеры использования

Пример рисования двух отдельных линий:

const canvas = document.getElementById('canvas1');
const ctx = canvas.getContext('2d');

// Первая линия
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineTo(100, 20);
ctx.stroke();

// Вторая линия
ctx.beginPath();
ctx.moveTo(20, 40);
ctx.lineTo(100, 40);
ctx.stroke();
На холсте появятся две отдельные линии.

Пример без использования beginPath:

const canvas = document.getElementById('canvas2');
const ctx = canvas.getContext('2d');

ctx.moveTo(20, 20);
ctx.lineTo(100, 20);
ctx.stroke();

// Новая линия без beginPath
ctx.moveTo(20, 40);
ctx.lineTo(100, 40);
ctx.stroke();
На холсте появятся обе линии, но вторая будет содержать точку из первой линии.

Похожие функции в JavaScript

closePath() — соединяет текущую точку с начальной точкой подпути, создавая замкнутую фигуру. Обычно используется после завершения построения контура.

rect() — создает прямоугольный путь. В отличие от последовательности moveTo и lineTo, эта функция сразу добавляет замкнутый прямоугольник к текущему пути.

clearRect() — очищает область холста, но не влияет на текущий путь. Используется для удаления графики, а не для сброса путей.

Метод beginPath() предпочтительнее использовать перед началом каждой новой фигуры, чтобы избежать нежелательного соединения элементов.

Аналоги в других языках программирования

Python (Pillow): При рисовании используется создание нового объекта ImageDraw для каждой операции.

from PIL import Image, ImageDraw

img = Image.new('RGB', (200, 200), 'white')
draw = ImageDraw.Draw(img)
draw.line([(20, 20), (100, 20)], fill='black')
# Новый объект для следующей линии
draw = ImageDraw.Draw(img)
draw.line([(20, 40), (100, 40)], fill='black')

C (Windows GDI): Используется BeginPath и EndPath для определения контура.

BeginPath(hdc);
MoveToEx(hdc, 20, 20, NULL);
LineTo(hdc, 100, 20);
EndPath(hdc);
StrokePath(hdc);

Java (Graphics2D): Создание нового объекта Path2D для каждого пути.

Path2D path = new Path2D.Double();
path.moveTo(20, 20);
path.lineTo(100, 20);
graphics.draw(path);

Распространенные ошибки

Ошибка 1: Отсутствие вызова beginPath при рисовании нескольких фигур.

const ctx = canvas.getContext('2d');
ctx.moveTo(0, 0);
ctx.lineTo(50, 50);
ctx.stroke();

// Забыли вызвать beginPath
ctx.moveTo(0, 30);
ctx.lineTo(50, 80);
ctx.stroke(); // Нарисует обе линии как один путь
Обе линии становятся частью одного пути.

Ошибка 2: Неправильный порядок вызова методов.

ctx.beginPath();
ctx.stroke(); // Нет определенного пути для рисования
ctx.moveTo(10, 10);
ctx.lineTo(50, 50);
Ничего не нарисуется, так как stroke() вызван до определения пути.

Ошибка 3: Использование beginPath внутри цикла без завершения предыдущего пути.

for(let i = 0; i < 5; i++) {
    ctx.beginPath();
    ctx.arc(30 + i*20, 30, 10, 0, Math.PI*2);
    // Забыли stroke() или fill()
}
Ничего не отобразится, так как пути созданы, но не нарисованы.

Изменения в последних версиях

Метод beginPath() не претерпел значительных изменений с момента введения Canvas API в HTML5. Спецификация остается стабильной. В современных браузерах метод работает одинаково без отклонений от стандарта.

Единственное развитие связано с оптимизацией производительности в движках рендеринга браузеров, но синтаксис и поведение остаются неизменными.

Расширенные примеры применения

Пример 1: Рисование составной фигуры с разными стилями.

Пример javascript
const ctx = canvas.getContext('2d');

// Первый путь с синей заливкой
ctx.beginPath();
ctx.rect(10, 10, 50, 50);
ctx.fillStyle = 'blue';
ctx.fill();

// Второй путь с красной обводкой
ctx.beginPath();
ctx.arc(100, 35, 25, 0, Math.PI*2);
ctx.strokeStyle = 'red';
ctx.lineWidth = 3;
ctx.stroke();
Появятся синий квадрат и красный круг без соединения.

Пример 2: Анимация с перерисовкой путей.

Пример javascript
let x = 0;
function animate() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    ctx.beginPath();
    ctx.arc(x, 50, 20, 0, Math.PI*2);
    ctx.fillStyle = 'green';
    ctx.fill();
    
    x += 2;
    if (x < 300) requestAnimationFrame(animate);
}
animate();
Зеленый круг движется по холсту.

Пример 3: Создание прерывистого контура.

Пример javascript
ctx.setLineDash([5, 3]);
ctx.beginPath();
ctx.moveTo(10, 10);
ctx.lineTo(200, 10);
ctx.lineTo(200, 100);
ctx.stroke();

// Сброс пунктира для следующего пути
ctx.setLineDash([]);
ctx.beginPath();
ctx.rect(50, 50, 60, 40);
ctx.stroke();
Первая ломаная линия пунктирная, прямоугольник сплошной.

Пример 4: Клиппинг области.

Пример javascript
// Создание клиппинг-области
ctx.beginPath();
ctx.arc(75, 75, 50, 0, Math.PI*2);
ctx.clip();

// Рисование внутри клипа
ctx.beginPath();
ctx.fillStyle = 'orange';
ctx.fillRect(0, 0, 150, 150);
Оранжевый квадрат виден только внутри круга.

JS beginPath function comments

En
BeginPath Starts a new path by emptying the list of sub-paths