HTML 5 canvas
12-09-2010
<canvas> елемента е част от новите свойства на HTML 5. Той представлява растерно платно, което позволява рисуването на графики, графики за игри и други визуални ефекти по време на изпълнение на скрипта. Платното е зависимо от резолюцията на монитора.
Всичко за canvas можете да намерите на този адрес.

Как реално изглежда canvas?
В общи линии никак. <canvas> няма нито фон, нито рамка. По подразбиране ако не му се зададат височина и широчина, то получава стойности 300 за широчината и 150 за височината. Т.е ако някъде в страницата си напишете <canvas></canvas> и браузърът ви е от последните версии на Opera, Chrome, Safari или Mozilla, ще видите празно пространство на мястото, което сте поставили canvas елемента.

И нека създадем първия си елемент canvas.

<!DOCTYPE html>
<html>
<head>
<title>Empty Canvas Demo</title>
<meta charset="utf-8">
</head>
<body>
<canvas>Този текст се показва в браузъри, които не поддържат canvas (thank you IE)</canvas>
</body>
</html>


ДЕМО

Резултатът от този код не би трябвало да го виждате освен ако не сте с браузър, който не поддържа canvas. Тогава ще ви се изпише текста между таговете <canvas> и </canvas>.
Въпреки, че не се вижда, платното вече е на страницата и можем да започнем да рисуваме върху него. Преди това ще му сложа рамка и размери, за да може да се различава без проблеми в страницата.

ДЕМО

След като виждаме платното вече можем да започнем истинската забава. За да можем да използваме платното в javascript ще трябва да му зададем id, за да можем лесно да го намираме като DOM елемент. В урока до края моето платно ще има id="my_canvas".

За да видим как действа всичко на практика ще напишем една малка функция. Не се безпокойте ако не разбирате всичко в нея. До края на урока ще има обяснение за всичко в тази функция.

<!DOCTYPE html>
<html>
<head>
<title>Canvas First Example Demo</title>
<meta charset="utf-8">
<style>
canvas { border: 1px dotted black; }
</style>
<script>
function init() {
var my_canvas = document.getElementById('my_canvas');
var my_context = my_canvas.getContext('2d');
my_context.fillRect(20, 40, 100, 100);
}
</script>
</head>
<body>
<canvas id="my_canvas" width="400" height="400">Този текст се показва в браузъри, които не поддържат canvas (thank you IE)</canvas>
<button onclick="init()">Стартирай кода!</button>
</body>
</html>


ДЕМО

Както забелязвате вече на canvas елемента съм задал id, за да можем да го намерим чрез javascript. Първия ред от функцията init:

var my_canvas = document.getElementById('my_canvas');


не е нищо ново и особено. Просто създаваме променлива, която съдържа canvas елемента, а него го намираме чрез getElementById.

Следващия ред заслужава повече внимание. Всеки canvas елемент има context, в който реално се извършва всичката работа. canvas елемента трябва да извика getContext метода с параметър '2d'. Функцията getContext() връща обект, който може да използва API-то за рисуване. Този обект се присвоява на променлива и се използва когато искаме да викаме някоя от функциите за рисуване.

var my_context = my_canvas.getContext('2d');


Последният ред просто рисува квадрат с размери 100 на 100 пиксела, чийто горен ляв ъгъл се намира на 20 пиксела наляво и 40 пиксела надолу от горния ляв ъгъл на платното ни. Квадратът е с черен цвят по подразбиране.

Функцията, която създадохме може да се сложи на всякакво събитие, но аз съм я направил при натискане на бутона.


След като видяхме как се намира canvas елемента и се взима context-a му за да можем да рисуваме, вече може да се запознаем и с някои функции за рисуване.

1. Правоъгълници
Има три функции за създаване на правоъгълници:


fillRect(x,y,width,height) : Рисува запълнен правоъгълник
strokeRect(x,y,width,height) : Рисува очертанията на правоъгълник
clearRect(x,y,width,height) : Изтрива избран очастък и го прави напълно прозрачен


И трите функции приемат еднакви параметри:
x - позицията от горния ляв ъгъл на canvas по хоризонтала, от която да започнем изчертаването
y - позицията от горния ляв ъгъл на canvas по вертикала, от която да започнем изчертаването
width - широчината на правоъгълника
height - височината на правоъгълника

И ето код, който демонстрира функциите:

function init() {
var my_canvas = document.getElementById('my_canvas');
var my_context = my_canvas.getContext('2d');
my_context.fillRect(20, 10, 120, 100);
my_context.strokeRect(20.5, 130.5, 120, 100);
my_context.clearRect(40, 20, 60, 50);
}


Тъй като html кода ще си остава непроменен до края на урока ще поставям само javascript кода, защото ще работим по него.

ДЕМО

Първите два реда ще ги презкоча и директно ще мина на обяснение на останалите три.

my_context.fillRect(20, 10, 120, 100);


функцията както обясних преди създава правоъгълник, като започва от координати 20,10 от горния ляв ъгъл на платното и използва 120 за широчина и 100 за височина. В примера това е големия черен правоъгълник.

my_context.strokeRect(20.5, 130.5, 120, 100);


Тази функция създава само очертанията на правоъгълника без да го запълва. Като и тук числата означават същото като при горната функция. В примера това е черната рамка под големия черен правоъглник.

my_context.clearRect(40, 20, 60, 50);


Тази функция изтрива определена област, като параметрите означават същото като в горните две функции. Започва от координати 40,20 (считани от горния ляв ъгъл на canvas) и използва 60 широчина и 50 височина. В примера това е малкото квадратче, което е изтрило част от черния квадрат.


2. Paths
Пътеките са нещо като рисуване с молив преди да се направи цялата рисунка, за да можем да видим самите линии трябва да направим няколко доъплнителни неща. Като начало трябва да определим какви линии, откъде докъде да се нарисуват и чак след това можем да ги покажем на платното като използваме едно от двете функции stroke() или fill().
Всяка пътека трябва да започва с beginPath(); и да завършва с closePath();

Функциите, които се използват за рисуване на линии са:


moveTo(x, y) : Премества началната точка на позицията, определена от x и y
lineTo(x, y) : Начертава права линия, която започва от позицията, определена от moveTo (или последното място, което е завършила изчертаването) и завършва на оказаните координати от параметрите си x и y


И с този примерен код ще видим нагледно как се работи с тези две функции:

function init() {
var my_canvas = document.getElementById('my_canvas');
var my_context = my_canvas.getContext('2d');
my_context.beginPath(); //тук започваме пътеката
my_context.moveTo(20.5, 20.5); //местим началната ни точка да е на координати 20.5, 20.5 от горния ляв ъгъл
my_context.lineTo(100, 20.5); //изрисуваме права линия, която започва от 20.5, 20.5 и завъшрва на координати 100.5, 20.5 от горния ляв ъгъл
my_context.moveTo(20.5, 30.5); //местим началната ни точка да е на координати 20.5, 30.5 от горния ляв ъгъл
my_context.lineTo(100.5, 30.5); //изрисуваме права линия, която започва от 20.5, 30.5 и завъшрва на координати 100.5, 30.5 от горния ляв ъгъл
my_context.lineTo(100.5, 70.5); //изрисуваме права линия, която започва от 100.5, 30.5 и завъшрва на координати 100.5, 70.5 от горния ляв ъгъл
my_context.stroke(); //правим видими очертанията
my_context.closePath(); //приключваме пътеката

my_context.beginPath(); //започваме нова пътека
my_context.moveTo(20.5, 100.5); //местим началната ни точка да е на координати 20.5, 100.5 от горния ляв ъгъл
my_context.lineTo(100.5, 100.5);//изрисуваме права линия, която започва от 20.5, 100.5 и завъшрва на координати 100.5, 100.5 от горния ляв ъгъл
my_context.lineTo(100.5, 150.5);//изрисуваме права линия, която започва от 100.5, 100.5 и завъшрва на координати 100.5, 150.5 от горния ляв ъгъл
my_context.fill(); //това запълва селекцията направена чрез линиите, вместо само да ги изрисува като stroke()
my_context.closePath(); //завършваме тази пътека
}


ДЕМО

И сега малко обяснение по кода:

my_context.moveTo(20.5, 20.5);
my_context.lineTo(100, 20.5);


тези два реда създават първата линия.

my_context.moveTo(20.5, 30.5);
my_context.lineTo(100.5, 30.5);
my_context.lineTo(100.5, 70.5);


тези три реда създават втората линия и треатата линия, която сочи надолу.

my_context.moveTo(20.5, 100.5);
my_context.lineTo(100.5, 100.5);
my_context.lineTo(100.5, 150.5);


тези три реда създават линиите, която чрез fill заплъват триъгълник.


3. Кръгове
Функцията за създаване на кръгове е:


arc(x, y, radius, startAngle, endAngle, antiClockWise) : изчертава кръг с зададените параметри


И сега един кратък пример на функцията:

function init() {
var my_canvas = document.getElementById('my_canvas');
var my_context = my_canvas.getContext('2d');
my_context.beginPath();
my_context.arc(20, 20, 10, 0, Math.PI*2, true);
my_context.stroke();
my_context.closePath();

my_context.beginPath();
my_context.arc(60, 20, 10, 0, Math.PI*2, true);
my_context.fill();
my_context.closePath();

my_context.beginPath();
my_context.arc(20, 60, 10, 0, Math.PI*1, true);
my_context.fill();
my_context.closePath();

my_context.beginPath();
my_context.arc(60, 60, 10, 0, Math.PI*1, false);
my_context.fill();
my_context.closePath();
}


ДЕМО

Първите 3 параметъра са ясни. Затова ще обърна малко повече внимание на Math.PI*2. Използваме го, за да изчислим ъглите. Може да си поиграете със стойности от 0 до 2, за да видите какво точно представлява.

Последния параметър приема стойност true или false. И както се вижда от примера ако е true, чертае едната част от кръга, който се описали чрез останалите параметри и ако е false чертае другата част.
true, за да започне обратно на часовниковата стрелка да чертае като започне от startAngle и завърши на endAngle, а false e по часовниковата стрелка.

Има и други функции за рисуване, но тях няма да ги обяснявам в урока. Част от тях са: quadraticCurveTo, bezierCurveTo, arcTo.


В останалата част от урока, ще се занимаем с това да променим цветовете на формите и рамките, за да не седят черни както е по подразбиране. Също така ще променим дебелината на stroke линията.
Свойствата, които ще променяме са:

fillStyle : може да приема всяка стойност за цвят. Примерно: "red", "#FF0000", "rgb(255, 0, 0)", "rgba(255, 0, 0, 5)". Също така могат да бъдат слагани и градиенти.
strokeStyle : може да приема всяка стойност за цвят. Примерно: "red", "#FF0000", "rgb(255, 0, 0)", "rgba(255, 0, 0, 5)"
lineWidth : може да приема стойност число


И с този кратък код ще илюстрирам тези 3 свойства:

function init() {
var my_canvas = document.getElementById('my_canvas');
var my_context = my_canvas.getContext('2d');
my_context.fillStyle = "red";
my_context.fillRect(20, 20, 100, 100);

my_context.fillStyle = "#0000FF";
my_context.fillRect(40, 40, 100, 100);

my_context.fillStyle = "rgb(255, 0, 255)";
my_context.fillRect(60, 60, 100, 100);

my_context.fillStyle = "rgba(0, 255, 0, 0.5)";
my_context.fillRect(80, 80, 100, 100);

my_context.strokeStyle = "red";
my_context.lineWidth = 5;
my_context.fillRect(20.5, 200.5, 100, 100);
my_context.strokeRect(20.5, 200.5, 100, 100);
}


ДЕМО

Както се вижда от кода, преди извикването на функциите за рисуване, можем да зададем стойности за цвета на фона и цвета на рамката и те ще се променят.
Като прави впечатление, че последния квадрат е с цвета на предпоследния, защото не сме му задали цвят, а викаме функцията, fillRect().

Мисля да е това в този урок. Останаха много неща не споменати тук, като направата на gradient background, използването на изображением за заплъване на някоя форма и функциите за трансформиране.

* ВАЖНО: В урока на някои места ще видите, че за начална точка не ползвам цяло число, а .5. И това си има причина. Нека си представим всеки пиксел като един квадрат (както е на картинката по-долу). Ако му зададем да започне от 1, то 1 ще е по средата на линията, а от двете страни ще стърчи с половин пиксел. И тъй като мониторът не може да изчертае половин пиксел и затова се дочертава и стават реално два пиксела.



Но ако вземем стойност 1.5, тогава 1.5 е в средата, а от двете страни линията е по 0.5 пиксела, което запълва точно един пиксел.




Ето и малко демота за вдъхновение :)

/ Трябва да сте регистриран за да напишете коментар /
От: talevtehnology
22:41 13-09-2010
Браво страхотна поредица от уроци
1