aboutsummaryrefslogtreecommitdiff
path: root/files/pl/web/api/canvas_api/tutorial/basic_usage/index.html
blob: ca8bc1557011ffeee21c48d9dd37ad40708992ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
---
title: Podstawowe użycie elementu canvas
slug: Web/API/Canvas_API/Tutorial/Basic_usage
tags:
  - Canvas
  - Grafika
  - HTML
  - Płótno
  - Sredniozaawansowany
  - Tutorial
translation_of: Web/API/Canvas_API/Tutorial/Basic_usage
---
<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}}</div>

<div class="summary">
<p>Zacznijmy od przyjrzenia się znacznikowi {{HTMLElement("canvas")}} należącego do zbioru elementów {{Glossary("HTML")}}. W tym rozdziale nauczysz się jak ustanowić dwuwymiarowy kontekst płótna, oraz narysujesz swój pierwszy rysunek.</p>
</div>

<h2 id="Element_&lt;canvas>">Element <code>&lt;canvas&gt;</code></h2>

<pre class="brush: html">&lt;canvas id="tutorial" width="150" height="150"&gt;&lt;/canvas&gt;
</pre>

<div class="note">
<p><strong>Uwaga:</strong> W tym tutorialu będziemy używać słowa <u>canvas</u> zamiennie ze słowem <u>płótno</u>.</p>
</div>

<p>Na pierwszy rzut oka {{HTMLElement("canvas")}} wygląda jak element {{HTMLElement("img")}}, z tą różnicą, że nie posiada on atrybutów <code>src</code> oraz <code>alt</code>. W swojej specyfice element <code>&lt;canvas&gt;</code> posiada jedynie dwa atrybuty, {{htmlattrxref("width", "canvas")}} oraz {{htmlattrxref("height", "canvas")}}. Nie są one wymagane oraz mogą być ustanowione za pomocą <a href="/en-US/docs/Web/API/HTMLCanvasElement">właściwości</a> {{Glossary("DOM")}}. Jeśli wartości atrybutów <code>width</code> oraz <code>height</code> nie zostaną określone, zostaną użyte domyślne: szerokość - <strong>300 pikseli</strong>, wysokość - <strong>150 pikseli</strong>. Za pomocą {{Glossary("CSS")}} możemy narzucić rozmiar płótna, ale podczas renderowania dokumentu, rysunek zostanie dopasowany do domyślnej wielkości: jeśli wartości określone za pomocą CSS nie będą proporcjonalne z wartościami domyślnymi, rysunek zostanie zniekształcony.</p>

<div class="note">
<p><strong>Uwaga:</strong> Jeśli rysunek wydaje się zniekształcony, spróbuj określić atrybuty <code>width</code> oraz <code>height</code> bezpośrednio wewnątrz znacznika <code>&lt;canvas&gt;</code>, a nie za pomocą CSS.</p>
</div>

<p><a href="/en-US/docs/Web/HTML/Global_attributes/id"><code>id</code></a> jest <a href="/en-US/docs/Web/HTML/Global_attributes">globalnym atrybutem HTML</a> i można go stosować z każdym elementem HTML (tak samo jak np. <code><a href="/en-US/docs/Web/HTML/Global_attributes/class">class</a></code>). Warto go używać, aby w ten sposób mieć dostęp do elementu z poziomy skryptu.</p>

<p>Element <code>&lt;canvas&gt;</code> można stylizować za pomocą CSS tak, jak każdy obraz ({{cssxref("margin")}}, {{cssxref("border")}}, {{cssxref("background")}}…). Z tym, że żadna z reguł CSS nie wpłynie na zawartość płótna. Zobaczymy to w <a href="/pl/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors">późniejszym rozdziale</a> tego tutorialu. Jeśli nie określimy inaczej, tło płótna będzie w pełni przezroczyste.</p>

<div id="section_2">
<h3 id="Treść_zastępcza">Treść zastępcza</h3>

<p>Inaczej niż w przypadku {{HTMLElement("img")}}, w elemencie <code>&lt;canvas&gt;</code> tak samo jak w {{HTMLElement("video")}}, {{HTMLElement("audio")}}, czy {{HTMLElement("picture")}} łatwo jest określić to, co będzie wyświetlane w starszych przeglądarkach albo tych, które jeszcze nie obsługują tego elementu, jak np. Internet Explorer poprzedzający wersję 9 oraz przeglądarki tekstowe.</p>

<p>Aby zapewnić treść zastępczą wystarczy zagnieździć ją wewnątrz elementu <code>&lt;canvas&gt; ... &lt;/canvas&gt;</code>. Przeglądarki nieobsługujące tego elementu, zignorują rysunek i zamiast tego wyświetlą to, co zagnieździliśmy wewnątrz tegoż elementu. Natomiast przeglądarki obsługujące element <code>&lt;canvas&gt;</code> wygenerują jego zawartość ignorując przy tym wszystko, co znajduje się wewnątrz tego elementu.</p>

<div class="note">
<p><strong>Uwaga:</strong> Gdy mówimy o tym, co znajduje się <strong>w znaczniku</strong> <code>&lt;canvas&gt;</code>, mamy na myśli jego atrybuty czyli to, co znajduje się pomiędzy znakami <code>&lt;</code> oraz <code>&gt;</code> (np. <code>&lt;canvas class="nazwa-klasy"&gt;</code>. Natomiast gdy mówimy o tym, co znajduje się <strong>wewnątrz elementu</strong> <code>&lt;canvas&gt;</code>, mamy na myśli wszystko, co znajduje się pomiędzy znacznikiem otwierającym <code>&lt;canvas&gt;</code>, a znacznikiem zamykającym <code>&lt;/canvas&gt;</code> (np. <code>&lt;canvas&gt;&lt;img src="/canvas.jpg"&gt;&lt;/canvas&gt;</code>). W tym drugim przypadku mówimy o <em>zagnieżdżaniu   </em>jednego elementu w drugim.</p>
</div>

<p>Treść zastępczą może stanowić opis, tego co znajduje się na płótnie lub statyczny obraz wygenerowanej zawartości. Oto przykład:</p>

<pre class="brush: html">&lt;canvas id="stockGraph" width="150" height="150"&gt;
  current stock price: $3.15 + 0.15
&lt;/canvas&gt;

&lt;canvas id="clock" width="150" height="150"&gt;
  &lt;img src="images/clock.png" width="150" height="150" alt=""/&gt;
&lt;/canvas&gt;
</pre>

<p>Umieszczanie tekstu w stylu: <em>Twoja przeglądarka nie obsługuje elementu canvas</em>, nie pomoże czytelnikowi w zrozumieniu treści. Zapewnienie treści zastępczej uczyni <a href="/pl/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility">element canvas bardziej dostępnym</a>.</p>

<h3 id="Wymagany_znacznik_końca_&lt;canvas>">Wymagany znacznik końca <code>&lt;/canvas&gt;</code></h3>

<p>Z uwagi na sposób w jaki tworzymy treść zastępczą, znacznikowi <code>&lt;canvas&gt;</code> <strong>musi towarzyszyć</strong> znacznik zamykający <code>&lt;/canvas&gt;</code>.  Gdybyśmy go nie wprowadzili, przeglądarka zinterpretowałaby wszystko, co znajduje się po znaczniku otwierającym <code>&lt;canvas&gt;</code> jako treść zastępczą.</p>

<p>Jeśli nie decydujemy się, aby zapewnić treść zastępczą, w dalszym ciągu <strong>musimy</strong> użyć znaczników początkowego i końcowego <code>&lt;canvas id="foo" ...&gt;&lt;/canvas&gt;</code>, z tą różnicą, że nie będziemy umieszczać niczego wewnątrz tego elementu. Jest to prawidłowy zapis dla przeglądarki, która obsługuje element <code>canvas</code>. Przeglądarki, które go nie obsługują, niczego w tym miejscu nie wyświetlą.</p>

<h2 id="Kontekst_renderingu">Kontekst renderingu</h2>

<p>Element {{HTMLElement("canvas")}} tworzy powierzchnię rysunkową o stałym rozmiarze zapewniając jeden lub więcej kontekstów renderingu, które są używane do tworzenia i manipulowania wyświetlaną zawartością. W tym tutorialu skupimy się na kontekście dwuwymiarowym (2D). Inne konteksty mogą wykorzystywać odmienne sposoby renderowania, np <a href="/pl/docs/Web/WebGL">WebGL</a> wykorzystuje kontekst trójwymiarowy (3D) bazujący na <a href="https://pl.wikipedia.org/wiki/OpenGL_ES">OpenGL ES</a>.</p>

<p>Początkowo płótno jest puste, pozbawione tła. Aby coś na nim wyświetlić, skrypt musi posiadać dostęp do kontekstu renderowania a następnie musi coś w nim narysować. Element {{HTMLElement("canvas")}} posiada metodę {{domxref("HTMLCanvasElement.getContext", "getContext()")}} niezbędną, aby uzyskać dostęp do nowego kontekstu renderowania oraz jego funcji rysujących. Metoda <code>getContext()</code> wymaga podania jednego argumentu, który określa typ kontekstu. Dla rysunków dwuwymiarowych, o których mowa w tym tutorialu, argument metody {{domxref("CanvasRenderingContext2D")}} wymaga podania wartości tekstowej "2d".</p>

<pre class="brush: js">var canvas = document.getElementById('tutorial');
var ctx = canvas.getContext('2d');
</pre>

<p>W pierwszej lini program uzyskuje dostęp do węzła DOM reprezentującego element {{HTMLElement("canvas")}} za pomocą metody {{domxref("document.getElementById()")}}. Posiadając dostęp do węzła DOM, możemy następnie uzyskać dostęp do kontekstu renderowania rysunku za pomocą metody <code>getContext()</code>.</p>

<div id="section_5">
<h2 id="Test_zgodności">Test zgodności</h2>

<p>Treść zastępcza jest wyświetlana w przeglądarce, która nie obsługuje elementu {{HTMLElement("canvas")}}. Również z poziomu skryptu możemy sprawdzić czy przeglądarka wspiera znacznik <code>canvas</code>. W tym celu posługujemy się metodą <code>getContext()</code>. Oto przykład:</p>

<pre class="brush: js">var canvas = document.getElementById('tutorial');

if (canvas.getContext) {
  var ctx = canvas.getContext('2d');
  // drawing code here
} else {
  // canvas-unsupported code here
}
</pre>

<p>Przeglądarka, która nie wspiera znacznika <code>canvas</code>, nie rozpoznaje również metody <code>getContext()</code>. W takim wypadku wyrażenie <code>canvas.getContext</code> zwróci logiczną wartość <code>false</code>.</p>
</div>
</div>

<h2 id="Szkielet_szablonu"> Szkielet szablonu</h2>

<p>Poniżej znajduje się szablon dokumentu HTML, którego będziemy używać jako podstawy w kolejnych przykładach ilustrujących <code>canvas</code>.</p>

<div class="note">
<p><strong>Uwaga:</strong> podczas produkcji stron internetowych warto umieszczać skrypty oraz arkusze stylów w osobnych plikach dla lepszej organizacji kodu. W tym tutorialu przykładowe skrypty będziemy jednak osadzać wewnątrz kodu HTML, tak aby cały przykład był zwięzły oraz w pełni funcjonalny.</p>
</div>

<pre class="brush: html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;meta charset="utf-8"/&gt;
    &lt;title&gt;Canvas tutorial&lt;/title&gt;
    &lt;script type="text/javascript"&gt;
      function draw() {
        var canvas = document.getElementById('tutorial');
        if (canvas.getContext) {
          var ctx = canvas.getContext('2d');
        }
      }
    &lt;/script&gt;
    &lt;style type="text/css"&gt;
      canvas { border: 1px solid black; }
    &lt;/style&gt;
  &lt;/head&gt;
  &lt;body onload="draw();"&gt;
    &lt;canvas id="tutorial" width="150" height="150"&gt;&lt;/canvas&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>

<p>Skrypt zawiera funckcję <code>draw()</code>, która jest wykonywana po załadowaniu strony; uczyniliśmy to za pomocą obserwatora zdarzenia {{event("load")}} dokumentu HTML. Funkcja taka może być również wywołana za pomocą metody {{domxref("WindowTimers.setTimeout", "window.setTimeout()")}}, {{domxref("WindowTimers.setInterval", "window.setInterval()")}} lub jeszcze innej, która obsługuje zdarzenia, po tym jak strona zostanie załadowana.</p>

<p>Oto jak szablon wygląda w akcji. Jak widać, początkowo jest on pusty.</p>

<p>{{EmbedLiveSample("A_skeleton_template", 160, 160)}}</p>

<h2 id="Prosty_przykład">Prosty przykład</h2>

<p>Na razie spójrzmy na poniższy przykład, zawierający rysunek dwóch przecinających się kwadratów, z których jeden jest przezroczysty. Szczegóły działania poszczególnych elementów kodu poznamy w dalszej części tego tutorialu.</p>

<pre class="brush: html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
 &lt;head&gt;
  &lt;meta charset="utf-8"/&gt;
  &lt;script type="application/javascript"&gt;
    function draw() {
      var canvas = document.getElementById('canvas');
      if (canvas.getContext) {
        var ctx = canvas.getContext('2d');

        ctx.fillStyle = 'rgb(200, 0, 0)';
        ctx.fillRect(10, 10, 50, 50);

        ctx.fillStyle = 'rgba(0, 0, 200, 0.5)';
        ctx.fillRect(30, 30, 50, 50);
      }
    }
  &lt;/script&gt;
 &lt;/head&gt;
 &lt;body onload="draw();"&gt;
   &lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;
 &lt;/body&gt;
&lt;/html&gt;
</pre>

<p>Przykład wygląda następująco:</p>

<p>{{EmbedLiveSample("A_simple_example", 160, 160, "https://mdn.mozillademos.org/files/228/canvas_ex1.png")}}</p>

<p>{{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}}</p>