Механизм CanvasPattern в HTML5 Canvas API используется
для заполнения областей повторяющимися изображениями или фрагментами
другого canvas-буфера. В контексте Chart.js он применяется для
кастомизации заливки элементов диаграммы: столбцов, сегментов круговых
диаграмм, областей под линиями и любых других графических примитивов,
поддерживающих свойство backgroundColor.
Основная идея заключается в том, что вместо сплошного цвета или
градиента используется повторяющийся рисунок, формируемый через
CanvasRenderingContext2D.createPattern. Это позволяет
создавать визуально насыщенные графики, где каждый dataset может иметь
уникальную текстуру.
CanvasPattern создаётся через контекст канваса:
const ctx = document.getElementById('chart').getContext('2d');
const img = new Image();
img.src = 'pattern.png';
img.onl oad = () => {
const pattern = ctx.createPattern(img, 'repeat');
};
Параметр второго аргумента задаёт поведение повторения:
repeat — повтор по обеим осямrepeat-x — только горизонтальноrepeat-y — только вертикальноno-repeat — без повторенияВ Chart.js этот объект может быть напрямую использован как значение цвета.
Chart.js позволяет использовать объект CanvasPattern в
качестве значения backgroundColor:
const img = new Image();
img.src = 'stripe.png';
img.onl oad = () => {
const pattern = ctx.createPattern(img, 'repeat');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['A', 'B', 'C'],
datasets: [{
label: 'Данные',
data: [10, 20, 30],
backgroundColor: pattern
}]
}
});
};
В этом случае каждый столбец диаграммы будет заполнен повторяющимся изображением вместо однотонной заливки.
Использование изображений не является единственным способом. Часто паттерны создаются программно, что обеспечивает гибкость и отсутствие внешних зависимостей.
function createStripePattern(color = '#000') {
const canvas = document.createElement('canvas');
canvas.width = 10;
canvas.height = 10;
const ctx = canvas.getContext('2d');
ctx.strokeStyle = color;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.moveTo(0, 10);
ctx.lineTo(10, 0);
ctx.stroke();
return ctx;
}
Далее:
const pattern = ctxMain.createPattern(createStripePattern().canvas, 'repeat');
Такие паттерны называются процедурными, так как они формируются алгоритмически.
CanvasPattern особенно полезен при визуализации нескольких наборов данных, когда цветовой кодировки недостаточно.
const patterns = [
ctx.createPattern(img1, 'repeat'),
ctx.createPattern(img2, 'repeat'),
ctx.createPattern(img3, 'repeat')
];
datasets: [
{
label: 'Первый',
data: [12, 19, 3],
backgroundColor: patterns[0]
},
{
label: 'Второй',
data: [5, 8, 13],
backgroundColor: patterns[1]
}
]
Такой подход особенно полезен в печатной графике или в условиях ограниченной цветопередачи.
CanvasPattern зависит от загрузки изображения. Это означает, что создание диаграммы должно происходить только после полной загрузки ресурсов.
Типичная ошибка — попытка создать pattern до завершения загрузки:
const img = new Image();
img.src = 'texture.png';
const pattern = ctx.createPattern(img, 'repeat'); // ошибка логики
Правильная последовательность:
img.onl oad = () => {
const pattern = ctx.createPattern(img, 'repeat');
new Chart(ctx, {
type: 'line',
data: {
datasets: [{
data: [1, 2, 3],
backgroundColor: pattern
}]
}
});
};
CanvasPattern не масштабируется автоматически при изменении размеров canvas. Это приводит к важному эффекту: плотность текстуры остаётся фиксированной в пикселях.
При изменении размеров графика возможны два сценария:
Для управления этим эффектом применяется предварительное масштабирование изображения:
function scalePatternImage(img, scale) {
const canvas = document.createElement('canvas');
canvas.width = img.width * scale;
canvas.height = img.height * scale;
const ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
return canvas;
}
Chart.js позволяет изменять данные и стили без пересоздания графика. CanvasPattern можно обновлять аналогично, но важно пересоздавать объект, а не мутировать его.
dataset.backgroundColor = ctx.createPattern(newImg, 'repeat');
chart.update();
Паттерн нельзя «перепрошить» внутри существующего объекта — требуется создание нового экземпляра.
Наиболее частый сценарий. Паттерн заменяет цвет столбцов:
Паттерны применяются к сегментам:
backgroundColor: [
pattern1,
pattern2,
pattern3
]
Каждый сегмент получает индивидуальную текстуру.
Использование паттернов возможно для fill области под
линией:
datasets: [{
data: [1, 3, 2, 5],
fill: true,
backgroundColor: pattern
}]
Несмотря на гибкость, механизм имеет ряд технических ограничений:
Также важно учитывать производительность: сложные изображения в паттернах увеличивают нагрузку на рендеринг при частых обновлениях графика.
При работе с большим количеством datasets следует избегать повторного создания одинаковых паттернов. Вместо этого используется кэширование:
const patternCache = new Map();
function getPattern(ctx, img) {
if (patternCache.has(img.src)) {
return patternCache.get(img.src);
}
const pattern = ctx.createPattern(img, 'repeat');
patternCache.set(img.src, pattern);
return pattern;
}
Это уменьшает количество операций создания объектов и снижает нагрузку на GPU/CPU рендеринг.
Canvas API позволяет создавать полностью программные текстуры:
Пример точечного паттерна:
function dotPattern() {
const canvas = document.createElement('canvas');
canvas.width = 8;
canvas.height = 8;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#000';
ctx.beginPath();
ctx.arc(2, 2, 1, 0, Math.PI * 2);
ctx.fill();
return canvas;
}
Такие паттерны хорошо масштабируются логически, так как их можно пересоздавать с разной плотностью.
CanvasPattern может комбинироваться с альфа-каналом и прозрачностью через RGBA-слои или глобальные настройки canvas.
В некоторых случаях паттерн накладывается поверх полупрозрачного цвета, создавая сложные визуальные эффекты:
backgroundColor: 'rgba(0, 0, 0, 0.1)'
или сочетание:
backgroundColor: pattern
где изображение уже содержит прозрачность.
При построении систем визуализации с паттернами выделяются несколько устойчивых моделей:
1. Паттерн-фабрика Централизованное создание и кэширование всех CanvasPattern.
2. Паттерн-декоратор Наложение текстур поверх базовых цветов.
3. Паттерн-слой Отдельное управление текстурами независимо от данных графика.
Разные браузеры по-разному оптимизируют повторяющиеся изображения. На практике это выражается в:
Chart.js абстрагирует большую часть этих различий, но поведение CanvasPattern остаётся нативным для браузера.
Существуют библиотеки, генерирующие предопределённые текстуры (полосы, точки, сетки), которые возвращают уже готовые CanvasPattern-объекты. Они упрощают создание визуально согласованных диаграмм, особенно в больших аналитических панелях.
Типичный подход — генерация набора стандартных паттернов и повторное использование их во всех графиках приложения.