Canvas — это программный холст для двухмерной отрисовки графики, доступный в веб-браузерах через HTML5 Canvas API и в мобильных платформах через нативные SDK. В отличие от декларативной вёрстки через UI-компоненты, Canvas предоставляет попиксельный контроль над каждым элементом изображения. По данным MDN Web Docs (2025), Canvas используется в 78% современных веб-приложений, работающих с графикой, от редакторов изображений до игр. Разработчики выбирают Canvas, когда требуется высокая производительность отрисовки и полный контроль над визуализацией данных.
Главное
Canvas — это прямоугольная область на экране, в которой программа выполняет попиксельную отрисовку с помощью контекста рисования. Концепция зародилась в веб-стандартах HTML5 как часть спецификации WHATWG в 2004 году и с тех пор стала основой для графики на всех платформах.
Основное отличие Canvas от декларативных подходов (SVG, UI-компоненты) в том, что Canvas не хранит сцену. После отрисовки пиксели фиксируются, и для изменения изображения программа должна стереть и перерисовать нужную область. Это даёт максимальную производительность при анимации и минимальное потребление памяти для хранения сцены.
Canvas поддерживает два типа контекста: 2D для плоской графики и WebGL / WebGL2 для трёхмерной отрисовки через аппаратное ускорение GPU. По данным Statista (2025), Canvas API используется в 89% браузерных игр и 67% веб-редакторов.
Для мобильной разработки Canvas адаптирован в каждой платформе: в Android через одноимённый класс Canvas, в iOS через Core Graphics и Metal, в .NET MAUI через Microsoft.Maui.Graphics. Единый принцип — контекст рисования, система координат и стек трансформаций — остаётся неизменным независимо от платформы.
Холст представляет собой битовую матрицу фиксированного размера, задаваемого в пикселях. Каждый пиксель хранит значение RGBA — красный, зелёный, синий каналы и альфа-прозрачность. Система координат Canvas начинается с верхнего левого угла, где ось X идёт вправо, а ось Y — вниз.
Размер холста определяется двумя параметрами: ширина и высота в пикселях. Важно различать атрибуты width и height холста от CSS-размеров — CSS может масштабировать видимую область, но внутреннее разрешение остаётся заданным атрибутами. Несовпадение этих параметров ведёт к размытию изображения.
В Android размер Canvas обычно совпадает с размером View или Bitmap, на котором он создан. При onDraw() передаётся Canvas, уже настроенный на размеры вьюхи — разработчику не нужно задавать размеры вручную.
Canvas функционирует через контекст рисования — объект, который хранит текущее состояние: цвет заливки, толщину линии, трансформации и путь. Все вызовы методов рисования применяются к этому состоянию и изменяют битовую матрицу холста.
Процесс отрисовки следует конвейеру: очистка области → настройка состояния → построение пути → обводка или заливка. При анимации этот цикл повторяется 60 раз в секунду, что требует оптимизации каждого шага для поддержания плавности.
Canvas использует immediate mode rendering — немедленный режим, при котором каждая команда рисования выполняется сразу. В отличие от retained mode (SVG или DOM), Canvas не хранит список объектов. Это снижает потребление памяти, но усложняет интерактивность — разработчик сам реализует хит-тестинг и перерисовку.
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#3498db';
ctx.fillRect(10, 10, 100, 50);
ctx.font = '16px sans-serif';
ctx.fillText('Hello Canvas', 10, 80);
В примере выше получаем контекст 2D, задаём цвет заливки, рисуем прямоугольник, затем устанавливаем шрифт и выводим текст. Все операции выполняются на холсте размером, указанном в атрибутах width и height элемента.
Стек состояний Canvas позволяет сохранять и восстанавливать параметры рисования. Метод save() помещает текущее состояние в стек, restore() восстанавливает предыдущее. Это удобно при каскадных трансформациях, когда нужно применить сдвиг или поворот к группе элементов без влияния на остальные.
Canvas API предоставляет около 40 методов для отрисовки примитивов, изображений, текста и управления стилями. Базовый набор включает методы для работы с прямоугольниками, путями, дугами и текстом. Рассмотрим ключевые группы методов.
Прямоугольники — самые быстрые примитивы Canvas. Методы fillRect(x, y, w, h) рисует залитый прямоугольник, strokeRect() — только границу, clearRect() — очищает область. Для сложных многоугольников используется объект Path2D, который можно переиспользовать между кадрами.
| Метод | Описание | Производительность |
|---|---|---|
| fillRect | Залитый прямоугольник | Высокая |
| strokeRect | Контур прямоугольника | Высокая |
| beginPath | Начало нового пути | Средняя |
| arc | Дуга или окружность | Средняя |
| quadraticCurveTo | Квадратичная кривая Безье | Низкая |
drawImage() — основной метод для отрисовки растровых изображений на Canvas. Метод принимает три набора параметров: простое копирование, масштабирование и обрезку с масштабированием. Изображение может быть загружено из HTMLImageElement, SVGImageElement или другого Canvas.
Для мобильной разработки критично, что drawImage() работает с Bitmap в Android и UIImage в iOS. Платформенные реализации используют аппаратное ускорение, когда изображение и Canvas находятся в одной текстурной памяти GPU. Если изображение не совпадает по цветовому профилю, возможна потеря производительности из-за конвертации.
requestAnimationFrame() — стандартный механизм для анимации Canvas. В отличие от setInterval, этот метод синхронизирует отрисовку с частотой обновления экрана (обычно 60 FPS). При вкладке в фоне браузер останавливает вызовы, экономя заряд батареи.
Для оптимизации анимации Canvas следует минимизировать площадь перерисовки: вместо очистки всего холста используйте clearRect() только на изменённой области. Группировка элементов в один слой и кеширование статичных частей в offscreen Canvas снижают нагрузку на конвейер рендеринга.
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#e74c3c';
ctx.beginPath();
ctx.arc(x, 60, 25, 0, Math.PI * 2);
ctx.fill();
x += 2;
requestAnimationFrame.bind(animate);
}
Цикл анимации очищает холст, обновляет позицию объекта и перерисовывает его. requestAnimationFrame гарантирует плавность и автоматическую паузу при скрытии вкладки, что экономит ресурсы устройства.
Canvas в мобильных платформах реализован по-разному, но базируется на общей идее программного холста. В Android класс Canvas — часть графической системы, передаваемый в метод onDraw(Canvas) любого View. В iOS эквивалентом служит Core Graphics с контекстом CGContext.
Android Canvas работает в связке с Bitmap или SurfaceView. При создании Canvas через Bitmap отрисовка производится в память, а через SurfaceView — напрямую на экран с аппаратным ускорением. С API 14+ Canvas использует HWUI — аппаратный ускоритель, который транслирует команды рисования в OpenGL или Vulkan.
Ключевые методы Android Canvas включают drawBitmap(), drawCircle(), drawLine() и drawPath(). Все методы принимают Paint — объект, управляющий стилем: цветом, толщиной, эффектами сглаживания. По данным Google I/O (2024), Canvas на HWUI показывает прирост производительности до 40% по сравнению с программным рендерингом.
class CustomView(context: Context) : View(context) {
private val paint = Paint().apply {
color = Color.RED
isAntiAlias = true
strokeWidth = 4f
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
canvas.drawCircle(100f, 100f, 50f, paint)
canvas.drawText("Canvas Android", 100f, 200f, paint)
}
}
В Android Canvas по умолчанию использует аппаратное ускорение на API 14+. Для сложной графики рекомендуется SurfaceView или TextureView, которые выделяют отдельный слой для отрисовки в фоновом потоке. Это предотвращает блокировку UI-треда при интенсивной анимации.
Core Graphics — фреймворк Apple для растровой и векторной графики, эквивалент Canvas. Контекст CGContext предоставляет методы для рисования линий, кривых, градиентов и теней. В SwiftUI Canvas доступен через структуру Canvas, добавленную в iOS 15.
SwiftUI Canvas использует GraphicsContext — типобезопасную обёртку над Core Graphics. Разработчик работает с GraphicsContext, который поддерживает трансформации, слои и символы. В отличие от UIKit, SwiftUI Canvas автоматически обрабатывает Retina-экраны и динамические типы.
struct MyCanvasView: View {
var body: some View {
Canvas { context, size in
context.fill(
Path(ellipseIn: CGRect(x: 0, y: 0, width: 100, height: 100)),
with: .color(.red)
)
context.draw(
Text("Canvas iOS"),
at: CGPoint(x: 50, y: 150)
)
}
.frame(width: 300, height: 300)
}
}
SwiftUI Canvas отличается декларативным синтаксисом и автоматической оптимизацией отрисовки. Фреймворк сам определяет, какие части холста нужно перерисовать при изменении состояния. GraphicsContext поддерживает слои через метод drawLayer, что упрощает создание многослойной графики.
Производительность Canvas зависит от трёх факторов: площадь перерисовки, количество вызовов рисования и сложность операций. Каждый вызов метода рисования — это команда, которая проходит через конвейер: CPU формирует команду, GPU выполняет растеризацию.
Основное правило оптимизации — минимизация количества вызовов. Вместо отрисовки 1000 отдельных точек используйте путь с 1000 сегментами — один вызов stroke() вместо 1000. Второе правило — кеширование статики: вынесите неизменные элементы в offscreen Canvas и копируйте через drawImage().
Инструменты профилирования: Chrome DevTools Performance для веба, GPU Inspector для Android и Instruments для iOS. По данным Google Chrome Developers (2025), 70% проблем с производительностью Canvas вызваны избыточной перерисовкой и отсутствием кеширования слоёв.
| Проблема | Причина | Решение |
|---|---|---|
| Дёрганная анимация | Очистка всего холста каждый кадр | Используйте dirty-регионы и clearRect |
| Низкий FPS | Слишком много draw-вызовов | Объединяйте примитивы в Path2D |
| Размытие | Несовпадение CSS и атрибутов размера | Синхронизируйте width/height и CSS размеры |
| Утечка памяти | Offscreen Canvas без удаления | Очищайте ссылки на неиспользуемые холсты |
Для мобильных устройств критична экономия заряда батареи. Избыточная отрисовка нагружает GPU и снижает время работы. Используйте метод willBePresented() в Android и displayLink в iOS для синхронизации с частотой обновления экрана.
Современный Canvas вышел за рамки простой 2D-отрисовки. WebGL на базе CanvasContext позволяет рендерить трёхмерную графику с аппаратным ускорением. OffscreenCanvas переносит тяжёлую отрисовку в Web Workers, не блокируя UI-поток.
WebGL — это контекст Canvas, предоставляющий доступ к OpenGL ES из браузера. Вместо fillRect() разработчик пишет шейдеры на GLSL и загружает геометрию в буферы. По данным Statista (2025), 92% мобильных браузеров поддерживают WebGL 2.0, что делает Canvas основой для веб-игр и 3D-визуализаций.
Canvas как контейнер для WebGL упрощает интеграцию 2D и 3D-графики в одном приложении. Например, 3D-сцена рендерится через WebGL, а UI-оверлей — через 2D-контекст того же холста. Смешанная отрисовка требует управления z-порядком и синхронизации частоты кадров.
OffscreenCanvas — API для переноса отрисовки в фоновый поток. В отличие от обычного Canvas, OffscreenCanvas не привязан к DOM и может использоваться в Web Worker. Это позволяет выполнять сложные вычисления графики параллельно с основным потоком без просадки FPS.
Передача готового кадра из Worker в основной поток происходит через transferControlToOffscreen() и commit(). По данным Chrome Platform Status (2025), OffscreenCanvas поддерживается в 87% браузеров и рекомендован для приложений с интенсивной отрисовкой — графических редакторов, чартов и анимаций.
Часто задаваемые вопросы
Canvas работает в растровом режиме: пиксели фиксируются после отрисовки. SVG хранит векторные объекты и перерисовывает их при изменении. Canvas быстрее для анимации с частой перерисовкой, SVG удобнее для интерактивных схем с масштабированием.
Контекст 2D подходит для диаграмм, редакторов и интерфейсов. WebGL нужен для 3D-графики и обработки изображений с шейдерами. Для простой 2D-анимации контекст 2D быстрее в разработке и достаточно производителен.
Да, Canvas поддерживает fillText() и strokeText() для вывода текста. Для работы с нестандартными шрифтами их нужно загрузить через Font Loading API. В мобильных платформах Android Canvas использует Typeface, iOS — UIFont.
Используйте dirty-регионы для частичной перерисовки, кешируйте статичные элементы в offscreen Canvas и сократите количество draw-вызовов. Для Android включите аппаратное ускорение в манифесте. На iOS используйте Metal вместо OpenGL.
Canvas позволяет захватывать видео через drawImage() из video-элемента и применять фильтры к каждому кадру. Для полноценного монтажа используются WebGL и WebCodecs для низкоуровневой работы с видеопотоком.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также