Canvas е програмно платно за двуизмерно рисуване на графика, достъпно в уеб браузъри чрез HTML5 Canvas API и на мобилни платформи чрез native 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 не съхранява списък от обекти. Това намалява консумацията на памет, но усложнява интерактивността — разработчикът сам реализира hit-testing и прерисуване.
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 са причинени от прекомерно прерисуване и липса на кеширане на слоеве.
| Проблем | Причина | Решение |
|---|---|---|
| Дръпваща се анимация | Изчистване на цялото платно всеки кадър | Използвайте мръсни региони и 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.
Използвайте мръсни региони за частично прерисуване, кеширайте статични елементи в offscreen Canvas и намалете броя на draw извикванията. За Android включете хардуерно ускорение в манифеста. На iOS използвайте Metal вместо OpenGL.
Canvas позволява заснемане на видео чрез drawImage() от video елемент и прилагане на филтри към всеки кадър. За пълноценен монтаж се използват WebGL и WebCodecs за нисконивова работа с видео поток.
Обобщение
Ще разработим мобилно приложение под ключ
IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.
Прочетете също