diff --git a/files/zh-tw/web/api/abortcontroller/index.md b/files/zh-tw/web/api/abortcontroller/index.md index 95215f88462f5b..cce85dce1ff109 100644 --- a/files/zh-tw/web/api/abortcontroller/index.md +++ b/files/zh-tw/web/api/abortcontroller/index.md @@ -3,42 +3,37 @@ title: AbortController slug: Web/API/AbortController translation_of: Web/API/AbortController --- -
{{APIRef("DOM")}}{{SeeCompatTable}}
+{{APIRef("DOM")}}{{SeeCompatTable}} -

AbortController 介面代表一個控制器物件,讓你可以在需要時中斷一個或多個 DOM 請求。

+**`AbortController`** 介面代表一個控制器物件,讓你可以在需要時中斷一個或多個 DOM 請求。 -

你可以使用 {{domxref("AbortController.AbortController()")}} 建立一個新的 AbortController 物件。與 DOM 請求溝通時則是使用 {{domxref("AbortSignal")}} 物件。

+你可以使用 {{domxref("AbortController.AbortController()")}} 建立一個新的 `AbortController` 物件。與 DOM 請求溝通時則是使用 {{domxref("AbortSignal")}} 物件。 -

建構子

+## 建構子 -
-
{{domxref("AbortController.AbortController()")}}
-
建立一個新的 AbortController 物件實體。
-
+- {{domxref("AbortController.AbortController()")}} + - : 建立一個新的 `AbortController` 物件實體。 -

屬性

+## 屬性 -
-
{{domxref("AbortController.signal")}} {{readonlyInline}}
-
回傳一個 {{domxref("AbortSignal")}} 物件實體,可以用來中斷一個 DOM 請求、或是與其溝通。
-
+- {{domxref("AbortController.signal")}} {{readonlyInline}} + - : 回傳一個 {{domxref("AbortSignal")}} 物件實體,可以用來中斷一個 DOM 請求、或是與其溝通。 -

方法

+## 方法 -
-
{{domxref("AbortController.abort()")}}
-
在一個 DOM 請求完成前中斷他。這可以用來中斷 fetch 請求、對任何 Response {{domxref("Body")}} 的讀取、或是資料流。
-
+- {{domxref("AbortController.abort()")}} + - : 在一個 DOM 請求完成前中斷他。這可以用來中斷 [fetch 請求](/zh-TW/docs/Web/API/fetch)、對任何 Response {{domxref("Body")}} 的讀取、或是資料流。 -

範例

+## 範例 -

在下面的程式碼片段中,我們要用 Fetch API 來下載一部影片。

+在下面的程式碼片段中,我們要用 [Fetch API](/zh-TW/docs/Web/API/Fetch_API) 來下載一部影片。 -

我們首先用 {{domxref("AbortController.AbortController","AbortController()")}} 建立一個控制器,然後透過 {{domxref("AbortController.signal")}} 屬性取得他的 {{domxref("AbortSignal")}} 物件。

+我們首先用 {{domxref("AbortController.AbortController","AbortController()")}} 建立一個控制器,然後透過 {{domxref("AbortController.signal")}} 屬性取得他的 {{domxref("AbortSignal")}} 物件。 -

在初始化 fetch 請求 的時候,我們把 AbortSignal 作為選項傳入該請求的選項物件中(參考下方的 {signal})。這樣會把剛才的中斷訊號與控制器跟 fetch 請求關聯起來,讓我們可以透過呼叫 {{domxref("AbortController.abort()")}} 來中斷該請求。請參考下方範例中第二個事件處理器。

+在初始化 [fetch 請求](/zh-TW/docs/Web/API/fetch) 的時候,我們把 `AbortSignal` 作為選項傳入該請求的選項物件中(參考下方的 `{signal}`)。這樣會把剛才的中斷訊號與控制器跟 fetch 請求關聯起來,讓我們可以透過呼叫 {{domxref("AbortController.abort()")}} 來中斷該請求。請參考下方範例中第二個事件處理器。 -
var controller = new AbortController();
+```js
+var controller = new AbortController();
 var signal = controller.signal;
 
 var downloadBtn = document.querySelector('.download');
@@ -58,27 +53,22 @@ function fetchVideo() {
   }).catch(function(e) {
     reports.textContent = '下載錯誤: ' + e.message;
   })
-}
+} +``` -
-

注意: 當 abort() 被呼叫的時候,fetch() 回傳的 Promise 會被以 AbortError 拒絕。

-
+> **備註:** 當 `abort()` 被呼叫的時候,`fetch()` 回傳的 Promise 會被以 `AbortError` 拒絕。 -

在 GitHub 有個完整的範例可供參考 — 請參見 abort-api或是也可以實際體驗看看)。

+在 GitHub 有個完整的範例可供參考 — 請參見 [abort-api](https://github.com/mdn/dom-examples/tree/master/abort-api)([或是也可以實際體驗看看](https://mdn.github.io/dom-examples/abort-api/))。 -

規格

+## 規格 {{Specifications}} -

瀏覽器相容性

+## 瀏覽器相容性 +{{Compat("api.AbortController")}} +## 參見 -

{{Compat("api.AbortController")}}

- -

參見

- - +- [Fetch API](/zh-TW/docs/Web/API/Fetch_API) +- [Abortable Fetch](https://developers.google.com/web/updates/2017/09/abortable-fetch) by Jake Archibald diff --git a/files/zh-tw/web/api/analysernode/index.md b/files/zh-tw/web/api/analysernode/index.md index 10a66640d8d5fc..ae6225066c6be2 100644 --- a/files/zh-tw/web/api/analysernode/index.md +++ b/files/zh-tw/web/api/analysernode/index.md @@ -11,94 +11,83 @@ tags: - Web Audio API translation_of: Web/API/AnalyserNode --- -

{{APIRef("Web Audio API")}}

+{{APIRef("Web Audio API")}} -

The AnalyserNode interface represents a node able to provide real-time frequency and time-domain analysis information. It is an {{domxref("AudioNode")}} that passes the audio stream unchanged from the input to the output, but allows you to take the generated data, process it, and create audio visualizations.

+The **`AnalyserNode`** interface represents a node able to provide real-time frequency and time-domain analysis information. It is an {{domxref("AudioNode")}} that passes the audio stream unchanged from the input to the output, but allows you to take the generated data, process it, and create audio visualizations. -

An AnalyzerNode has exactly one input and one output. The node works even if the output is not connected.

+An `AnalyzerNode` has exactly one input and one output. The node works even if the output is not connected. -

Without modifying the audio stream, the node allows to get the frequency and time-domain data associated to it, using a FFT.

+![Without modifying the audio stream, the node allows to get the frequency and time-domain data associated to it, using a FFT.](fttaudiodata_en.svg) - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + +
Number of inputs1
Number of outputs1 (but may be left unconnected)
Channel count mode"explicit"
Channel count1
Channel interpretation"speakers"
Number of inputs1
Number of outputs1 (but may be left unconnected)
Channel count mode"max"
Channel count2
Channel interpretation"speakers"
-

Inheritance

+## Inheritance -

This interface inherits from the following parent interfaces:

+This interface inherits from the following parent interfaces: -

{{InheritanceDiagram}}

+{{InheritanceDiagram}} -

Properties

+## Properties -

Inherits properties from its parent, {{domxref("AudioNode")}}.

+_Inherits properties from its parent,_ _{{domxref("AudioNode")}}_. -
-
{{domxref("AnalyserNode.fftSize")}}
-
Is an unsigned long value representing the size of the FFT (Fast Fourier Transform) to be used to determine the frequency domain.
-
{{domxref("AnalyserNode.frequencyBinCount")}} {{readonlyInline}}
-
Is an unsigned long value half that of the FFT size. This generally equates to the number of data values you will have to play with for the visualization.
-
{{domxref("AnalyserNode.minDecibels")}}
-
Is a double value representing the minimum power value in the scaling range for the FFT analysis data, for conversion to unsigned byte values — basically, this specifies the minimum value for the range of results when using getByteFrequencyData().
-
{{domxref("AnalyserNode.maxDecibels")}}
-
Is a double value representing the maximum power value in the scaling range for the FFT analysis data, for conversion to unsigned byte values — basically, this specifies the maximum value for the range of results when using getByteFrequencyData().
-
{{domxref("AnalyserNode.smoothingTimeConstant")}}
-
Is a double value representing the averaging constant with the last analysis frame — basically, it makes the transition between values over time smoother.
-
+- {{domxref("AnalyserNode.fftSize")}} + - : Is an unsigned long value representing the size of the FFT ([Fast Fourier Transform](http://en.wikipedia.org/wiki/Fast_Fourier_transform)) to be used to determine the frequency domain. +- {{domxref("AnalyserNode.frequencyBinCount")}} {{readonlyInline}} + - : Is an unsigned long value half that of the FFT size. This generally equates to the number of data values you will have to play with for the visualization. +- {{domxref("AnalyserNode.minDecibels")}} + - : Is a double value representing the minimum power value in the scaling range for the FFT analysis data, for conversion to unsigned byte values — basically, this specifies the minimum value for the range of results when using `getByteFrequencyData()`. +- {{domxref("AnalyserNode.maxDecibels")}} + - : Is a double value representing the maximum power value in the scaling range for the FFT analysis data, for conversion to unsigned byte values — basically, this specifies the maximum value for the range of results when using `getByteFrequencyData()`. +- {{domxref("AnalyserNode.smoothingTimeConstant")}} + - : Is a double value representing the averaging constant with the last analysis frame — basically, it makes the transition between values over time smoother. -

Methods

+## Methods -

Inherits methods from its parent, {{domxref("AudioNode")}}.

+_Inherits methods from its parent,_ _{{domxref("AudioNode")}}_. -
-
{{domxref("AnalyserNode.getFloatFrequencyData()")}}
-
Copies the current frequency data into a {{domxref("Float32Array")}} array passed into it.
-
+- {{domxref("AnalyserNode.getFloatFrequencyData()")}} + - : Copies the current frequency data into a {{domxref("Float32Array")}} array passed into it. +- {{domxref("AnalyserNode.getByteFrequencyData()")}} + - : Copies the current frequency data into a {{domxref("Uint8Array")}} (unsigned byte array) passed into it. +- {{domxref("AnalyserNode.getFloatTimeDomainData()")}} + - : Copies the current waveform, or time-domain, data into a {{domxref("Float32Array")}} array passed into it. +- {{domxref("AnalyserNode.getByteTimeDomainData()")}} + - : Copies the current waveform, or time-domain, data into a {{domxref("Uint8Array")}} (unsigned byte array) passed into it. -
-
{{domxref("AnalyserNode.getByteFrequencyData()")}}
-
Copies the current frequency data into a {{domxref("Uint8Array")}} (unsigned byte array) passed into it.
-
+## Examples -
-
{{domxref("AnalyserNode.getFloatTimeDomainData()")}}
-
Copies the current waveform, or time-domain, data into a {{domxref("Float32Array")}} array passed into it.
-
{{domxref("AnalyserNode.getByteTimeDomainData()")}}
-
Copies the current waveform, or time-domain, data into a {{domxref("Uint8Array")}} (unsigned byte array) passed into it.
-
+> **備註:** See the guide [Visualizations with Web Audio API](/zh-TW/docs/Web/API/Web_Audio_API/Visualizations_with_Web_Audio_API) for more information on creating audio visualizations. -

Examples

+### Basic usage -
-

Note: See the guide Visualizations with Web Audio API for more information on creating audio visualizations.

-
+The following example shows basic usage of an {{domxref("AudioContext")}} to create an `AnalyserNode`, then {{domxref("window.requestAnimationFrame()","requestAnimationFrame")}} and {{htmlelement("canvas")}} to collect time domain data repeatedly and draw an "oscilloscope style" output of the current audio input. For more complete applied examples/information, check out our [Voice-change-O-matic](http://mdn.github.io/voice-change-o-matic/) demo (see [app.js lines 128–205](https://github.com/mdn/voice-change-o-matic/blob/gh-pages/scripts/app.js#L128-L205) for relevant code). -

Basic usage

- -

The following example shows basic usage of an {{domxref("AudioContext")}} to create an AnalyserNode, then {{domxref("window.requestAnimationFrame()","requestAnimationFrame")}} and {{htmlelement("canvas")}} to collect time domain data repeatedly and draw an "oscilloscope style" output of the current audio input. For more complete applied examples/information, check out our Voice-change-O-matic demo (see app.js lines 128–205 for relevant code).

- -
var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
+```js
+var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
 var analyser = audioCtx.createAnalyser();
 
   ...
@@ -127,7 +116,7 @@ function draw() {
       var sliceWidth = WIDTH * 1.0 / bufferLength;
       var x = 0;
 
-      for(var i = 0; i < bufferLength; i++) {
+      for(var i = 0; i < bufferLength; i++) {
 
         var v = dataArray[i] / 128.0;
         var y = v * HEIGHT/2;
@@ -145,18 +134,17 @@ function draw() {
       canvasCtx.stroke();
     };
 
-    draw();
+ draw(); +``` -

Specifications

+## Specifications {{Specifications}} -

Browser compatibility

+## Browser compatibility {{Compat("api.AnalyserNode")}} -

See also

+## See also - +- [Using the Web Audio API](/zh-TW/docs/Web_Audio_API/Using_Web_Audio_API) diff --git a/files/zh-tw/web/api/battery_status_api/index.md b/files/zh-tw/web/api/battery_status_api/index.md index 94d4a8e3a5a1b5..b38a2e9a6c28a6 100644 --- a/files/zh-tw/web/api/battery_status_api/index.md +++ b/files/zh-tw/web/api/battery_status_api/index.md @@ -3,11 +3,16 @@ title: Battery Status API slug: Web/API/Battery_Status_API translation_of: Web/API/Battery_Status_API --- -

Battery Status API 也就是所謂的 Battery API,將提供系統電池充電容量的資訊,並在電池容量變化時送出事件,以通知使用者。此 API 可調整 Apps 的資源耗用量,在電力偏低時縮減耗電量;或可在電力耗盡之前儲存檔案,避免資料遺失。

-

Battery Status API 是以 window.navigator.battery 屬性 (為 BatteryManager 物件) 而擴充了 window.navigator,並新增數項可讓使用者接收的新事件,以隨時監控電池狀態。

-

範例

-

在此範例中,我們將分別監聽 chargingchangelevelchange 事件,而看到充電狀態 (不論是否插電進行充電) 與電池容量的變化。

-
var battery = navigator.battery || navigator.mozBattery || navigator.webkitBattery;
+**Battery Status API** 也就是所謂的 **Battery API**,將提供系統電池充電容量的資訊,並在電池容量變化時送出事件,以通知使用者。此 API 可調整 Apps 的資源耗用量,在電力偏低時縮減耗電量;或可在電力耗盡之前儲存檔案,避免資料遺失。
+
+Battery Status API 是以 [`window.navigator.battery`](/zh-TW/docs/Web/API/window.navigator.battery) 屬性 (為 [`BatteryManager`](/zh-TW/docs/Web/API/BatteryManager) 物件) 而擴充了 [`window.navigator`](/zh-TW/docs/Web/API/window.navigator),並新增數項可讓使用者接收的新事件,以隨時監控電池狀態。
+
+## 範例
+
+在此範例中,我們將分別監聽 [chargingchange](/zh-TW/docs/Web/Reference/Events/chargingchange) 與 [levelchange](/zh-TW/docs/Web/Reference/Events/levelchange) 事件,而看到充電狀態 (不論是否插電進行充電) 與電池容量的變化。
+
+```js
+var battery = navigator.battery || navigator.mozBattery || navigator.webkitBattery;
 
 function updateBatteryStatus() {
   console.log("Battery status: " + battery.level * 100 + " %");
@@ -20,19 +25,24 @@ function updateBatteryStatus() {
 battery.addEventListener("chargingchange", updateBatteryStatus);
 battery.addEventListener("levelchange", updateBatteryStatus);
 updateBatteryStatus();
-
-

另可參閱規格所提供之範例

-

規格

-

{{page("/en-US/docs/Web/API/BatteryManager","Specifications")}}

-

瀏覽器相容性

-

{{page("/en-US/docs/Web/API/BatteryManager","Browser_compatibility")}}

-

另請參閱

- +``` + +另可參閱[規格所提供之範例](http://dev.w3.org/2009/dap/system-info/battery-status.html#introduction)。 + +## 規格 + +{{page("/en-US/docs/Web/API/BatteryManager","Specifications")}} + +## 瀏覽器相容性 + +{{page("/en-US/docs/Web/API/BatteryManager","Browser_compatibility")}} + +## 另請參閱 + +- [部落格文章 - Using the Battery API](http://hacks.mozilla.org/2012/02/using-the-battery-api-part-of-webapi/) +- [David Walsh 所寫的 JavaScript Battery Api](http://davidwalsh.name/battery-api) +- [battery.js - 跨瀏覽器 wrapper](https://github.com/pstadler/battery.js) +- [`BatteryManager`](/zh-TW/docs/Web/API/BatteryManager) +- [`navigator.battery`](/zh-TW/docs/Web/API/window.navigator.battery) +- `測試你的瀏覽器是否支援 Battery Status API。可掃 QR Code:` +- [![QR Code to Battery Status API Test Page](http://x.co/qr/batstat?s=165)](http://x.co/qr/batstat?s=165) diff --git a/files/zh-tw/web/api/blob/index.md b/files/zh-tw/web/api/blob/index.md index 112ac46f8de123..2e67424c04038e 100644 --- a/files/zh-tw/web/api/blob/index.md +++ b/files/zh-tw/web/api/blob/index.md @@ -3,101 +3,92 @@ title: Blob slug: Web/API/Blob translation_of: Web/API/Blob --- -

{{APIRef("File API")}}

+{{APIRef("File API")}} -

Blob(Binary Large Object)物件代表了一個相當於檔案(原始資料)的不可變物件。Blob 中的資料並不一定是 JavaScript 原生的格式。{{domxref("File")}} 介面基於 Blob,繼承 blob 並擴充其功能以支援操作使用者系統上的檔案。

+`Blob`(Binary Large Object)物件代表了一個相當於檔案(原始資料)的不可變物件。Blob 中的資料並不一定是 JavaScript 原生的格式。{{domxref("File")}} 介面基於 `Blob,`繼承 blob 並擴充其功能以支援操作使用者系統上的檔案。 -

從其它非 Blob 物件或資料來建構 Blob 物件,可以使用 {{domxref("Blob.Blob", "Blob()")}} 建構式。要建立一個包含目前 blob 內容子集的 blob,可使用 {{domxref("Blob.slice()", "slice()")}} 方法。若要自使用者系統上的檔案取得 Blob 物件,請參考 {{domxref("File")}} 文件。

+從其它非 Blob 物件或資料來建構 `Blob` 物件,可以使用 {{domxref("Blob.Blob", "Blob()")}} 建構式。要建立一個包含目前 blob 內容子集的 blob,可使用 {{domxref("Blob.slice()", "slice()")}} 方法。若要自使用者系統上的檔案取得 `Blob` 物件,請參考 {{domxref("File")}} 文件。 -

接受 Blob 物件的 API 可以在 {{domxref("File")}} 上找到。

+接受 Blob 物件的 API 可以在 {{domxref("File")}} 上找到。 -
-

註:早期 slice() 方法擁有第二個參數 length 以指定在建立新 Blob 物件時要複製的位元組(byte)數量。假如指定的 start + length 超出了來源 Blob 的大小,則回傳的 Blob 會包含自索引 start 至結尾的完整來源內容。

-
+> **備註:** 早期 `slice()` 方法擁有第二個參數 `length` 以指定在建立新 `Blob` 物件時要複製的位元組(byte)數量。假如指定的 `start + length` 超出了來源 `Blob` 的大小,則回傳的 `Blob` 會包含自索引 `start` 至結尾的完整來源內容。 -
-

註:需注意在部分瀏覽器版本中,slice() 方法帶有前綴:Firefox 12 與之前的版本為 blob.mozSlice(),Safari 中是 blob.webkitSlice()。舊的、無前綴字版本的 slice() 方法則有不同的語意(semantics),但這是已淘汰的方法。瀏覽器對 blob.mozSlice() 的支援已在 Firefox 30 時中止。

-
+> **備註:** 需注意在部分瀏覽器版本中,`slice()` 方法帶有前綴:Firefox 12 與之前的版本為 `blob.mozSlice()`,Safari 中是 `blob.webkitSlice()`。舊的、無前綴字版本的 `slice()` 方法則有不同的語意(semantics),但這是已淘汰的方法。瀏覽器對 `blob.mozSlice()` 的支援已在 Firefox 30 時中止。 -

建構式

+## 建構式 -
-
{{domxref("Blob.Blob", "Blob(blobParts[, options])")}}
-
回傳新建立的 Blob 物件,包含了建構式參數傳入之陣列所串聯後的值。第二個參數為 BlobPropertyBag 物件,其擁有 typeendings 屬性。
-
+- {{domxref("Blob.Blob", "Blob(blobParts[, options])")}} + - : 回傳新建立的 `Blob` 物件,包含了建構式參數傳入之陣列所串聯後的值。第二個參數為 BlobPropertyBag 物件,其擁有 `type` 和 `endings` 屬性。 -

屬性

+## 屬性 -
-
{{domxref("Blob.size")}} {{readonlyinline}}
-
以 byte 為單位的 Blob 物件大小。
-
{{domxref("Blob.type")}} {{readonlyinline}}
-
Blob 物件中資料的型態,以 MIME 類型的字串表示。若型態為未知,則為空字串。
-
+- {{domxref("Blob.size")}} {{readonlyinline}} + - : 以 byte 為單位的 `Blob` 物件大小。 +- {{domxref("Blob.type")}} {{readonlyinline}} + - : `Blob` 物件中資料的型態,以 MIME 類型的字串表示。若型態為未知,則為空字串。 -

方法

+## 方法 -
-
{{domxref("Blob.slice()", "Blob.slice([start[, end[, contentType]]])")}}
-
回傳一個包含當前 Blob 物件之指定資料範圍(byte)內容的新 Blob 物件。
-
+- {{domxref("Blob.slice()", "Blob.slice([start[, end[, contentType]]])")}} + - : 回傳一個包含當前 `Blob` 物件之指定資料範圍(byte)內容的新 `Blob` 物件。 -

範例

+## 範例 -

Blob 建構函數用法範例

+### Blob 建構函數用法範例 -

{{domxref("Blob.Blob", "Blob() constructor")}} 建構式允許由其它物件建立 blob 物件。以下的範例演示了以字串來建構 blob 物件:

+{{domxref("Blob.Blob", "Blob() constructor")}} 建構式允許由其它物件建立 blob 物件。以下的範例演示了以字串來建構 blob 物件: -
var debug = {hello: "world"};
-var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'});
+```js +var debug = {hello: "world"}; +var blob = new Blob([JSON.stringify(debug, null, 2)], {type : 'application/json'}); +``` -
-

在 Blob 建構式出現之前,可以透過 {{domxref("BlobBuilder")}} 來建立 blob 物件(目前已不建議使用):

+> **警告:** 在 Blob 建構式出現之前,可以透過 {{domxref("BlobBuilder")}} 來建立 blob 物件(目前已不建議使用): +> +> ```js +> var builder = new BlobBuilder(); +> var fileParts = ['hey!']; +> builder.append(fileParts[0]); +> var myBlob = builder.getBlob('text/xml'); +> ``` -
var builder = new BlobBuilder();
-var fileParts = ['<a id="a"><b id="b">hey!</b></a>'];
-builder.append(fileParts[0]);
-var myBlob = builder.getBlob('text/xml');
-
+### 藉型別陣列建構的 blob 來建立 URL -

藉型別陣列建構的 blob 來建立 URL

+範例程式碼: -

範例程式碼:

- -
var typedArray = GetTheTypedArraySomehow();
+```js
+var typedArray = GetTheTypedArraySomehow();
 var blob = new Blob([typedArray], {type: 'application/octet-binary'}); // pass a useful mime type here
 var url = URL.createObjectURL(blob);
 // url will be something like: blob:d3958f5c-0777-0845-9dcf-2cb28783acaf
 // now you can use the url in any context that regular URLs can be used in, for example img.src, etc.
-
+``` -

從 Blob 取出資料

+### 從 Blob 取出資料 -

從 Blob 讀取資料的唯一方式就是使用 {{domxref("FileReader")}}。以下範例展示了讀取 Blob 內容作為型別陣列:

+從 Blob 讀取資料的唯一方式就是使用 {{domxref("FileReader")}}。以下範例展示了讀取 Blob 內容作為型別陣列: -
var reader = new FileReader();
+```js
+var reader = new FileReader();
 reader.addEventListener("loadend", function() {
    // reader.result contains the contents of blob as a typed array
 });
-reader.readAsArrayBuffer(blob);
+reader.readAsArrayBuffer(blob); +``` -

藉由操作 {{domxref("FileReader")}} 的其他方法,將 Blob 讀取成字串或是 data URL 是有可能的。

+藉由操作 {{domxref("FileReader")}} 的其他方法,將 Blob 讀取成字串或是 data URL 是有可能的。 -

規範

+## 規範 {{Specifications}} -

瀏覽器相容性

- - +## 瀏覽器相容性 -

{{Compat("api.Blob")}}

+{{Compat("api.Blob")}} -

參見

+## 參見 - +- {{domxref("BlobBuilder")}} +- {{domxref("File")}} +- {{domxref("URL.createObjectURL")}} +- [Components.utils.importGlobalProperties](/zh-TW/docs/Components.utils.importGlobalProperties) diff --git a/files/zh-tw/web/api/canvas_api/index.md b/files/zh-tw/web/api/canvas_api/index.md index bf6e23f90fff25..a75d0194c3b227 100644 --- a/files/zh-tw/web/api/canvas_api/index.md +++ b/files/zh-tw/web/api/canvas_api/index.md @@ -3,48 +3,49 @@ title: Canvas API slug: Web/API/Canvas_API translation_of: Web/API/Canvas_API --- -
{{CanvasSidebar}}
+{{CanvasSidebar}} -

{{HTMLElement("canvas")}}HTML5 的新元素,可透過 Script(通常是 JavaScript)繪製圖形。例如,可以用來繪圖、合成圖照片、建立動畫、甚至處理即時的影片播放。

+**{{HTMLElement("canvas")}}** 是 [HTML5](/zh-TW/docs/HTML) 的新元素,可透過 Script(通常是 [JavaScript](/zh-TW/docs/JavaScript))繪製圖形。例如,可以用來繪圖、合成圖照片、建立動畫、甚至處理即時的影片播放。 -

Mozilla 應用程式從 Gecko 1.8(也就是 Firefox 1.5)起開始支援 <canvas>。這個元素最初由蘋果 OS X Dashboard 和 Safari 引入。Internet Explorer 9 以上版本也有支援 <canvas>,但較舊的 IE 版本則須嵌入 Google Explorer Canvas 專案中的程式腳本,才能得到有效的支援。Opera 9 也支援 <canvas>

+Mozilla 應用程式從 Gecko 1.8(也就是 [Firefox 1.5](/en/Firefox_1.5_for_developers))起開始支援 ``。這個元素最初由蘋果 OS X [Dashboard](http://www.apple.com/macosx/features/dashboard/) 和 Safari 引入。Internet Explorer 9 以上版本也有支援` `,但較舊的 IE 版本則須嵌入 Google [Explorer Canvas](http://excanvas.sourceforge.net/) 專案中的程式腳本,才能得到有效的支援。Opera 9 也支援 ``。 -

<canvas> 元素通常也被 WebGL 用來在網頁上顯示使用硬體加速繪製的 3D 圖形。

+`` 元素通常也被 [WebGL](/zh-TW/docs/Web/WebGL) 用來在網頁上顯示使用硬體加速繪製的 3D 圖形。 -

範例

+## 範例 -

這則簡單的範例使用了{{domxref("CanvasRenderingContext2D.fillRect()")}}這個方法。

+這則簡單的範例使用了{{domxref("CanvasRenderingContext2D.fillRect()")}}這個方法。 -

HTML

+### HTML -
<canvas id="canvas"></canvas>
-
+```html + +``` -

JavaScript

+### JavaScript -
var canvas = document.getElementById("canvas");
+```js
+var canvas = document.getElementById("canvas");
 var ctx = canvas.getContext("2d");
 
 ctx.fillStyle = "green";
 ctx.fillRect(10, 10, 100, 100);
-
+``` -

Edit the code below and see your changes update live in the canvas:

+Edit the code below and see your changes update live in the canvas: - - -

{{ EmbedLiveSample('Playable_code', 700, 360) }}

- -

參考

- -
    -
  • {{domxref("HTMLCanvasElement")}}
  • -
  • {{domxref("CanvasRenderingContext2D")}}
  • -
  • {{domxref("CanvasGradient")}}
  • -
  • {{domxref("CanvasPattern")}}
  • -
  • {{domxref("ImageBitmap")}}
  • -
  • {{domxref("ImageData")}}
  • -
  • {{domxref("TextMetrics")}}
  • -
  • {{domxref("Path2D")}} {{experimental_inline}}
  • -
- -

這些與WebGLRenderingContext有關的標識,皆引用在WebGL

- -

教程指南

- -
-
Canvas tutorial
-
這個全部的課程包含 <canvas> 基礎的使用和高階的應用。
-
Code snippets: Canvas
-
一些延伸的開發功能,包含<canvas>
-
Demo: A basic ray-caster
-
使用<canvas>做的光線追蹤(ray-tracing )範例。
-
Drawing DOM objects into a canvas
-
如何在 DOM<canvas>之中,畫個物件。例如 HTML的元素。
-
Manipulating video using canvas
-
結合{{HTMLElement("video")}} 和 {{HTMLElement("canvas")}} 去控制影像資料的真實時間
-
- -

資源

- -

Generic

- - - -

Libraries

- -
    -
  • Fabric.js is an open-source canvas library with SVG parsing capabilities.
  • -
  • Kinetic.js is an open-source canvas library focused on interactivity for desktop and mobile applications.
  • -
  • Paper.js is an open source vector graphics scripting framework that runs on top of the HTML5 Canvas.
  • -
  • Origami.js is an open source lightweight canvas library.
  • -
  • libCanvas 是一個強大且輕量化的 canvas 框架。
  • -
  • Processing.js 是視覺化程式語言 Processing 的移植版。
  • -
  • PlayCanvas is an open source game engine.
  • -
  • Pixi.js is an open source game engine.
  • -
  • PlotKit 是一個製作圖表和圖形的函式庫。
  • -
  • Rekapi 是一個用來控制動畫影格的 Canvas API。
  • -
  • PhiloGL 是一個可應用在資料視覺化、遊戲開發的 WebGL 框架。
  • -
  • JavaScript InfoVis Toolkit 可在網頁上建立 2D 的互動式 Canvas 視覺化資料。
  • -
  • EaselJS 是一個自由 / 開放源始碼的函式庫,目的在簡化 canvas 於遊戲與美術的開發難度,類似 Flash API。
  • -
  • Scrawl-canvas is another open-source javascript library for creating and manipulating 2d canvas elements
  • -
- -

規範

+``` + +{{ EmbedLiveSample('Playable_code', 700, 360) }} + +## 參考 + +- {{domxref("HTMLCanvasElement")}} +- {{domxref("CanvasRenderingContext2D")}} +- {{domxref("CanvasGradient")}} +- {{domxref("CanvasPattern")}} +- {{domxref("ImageBitmap")}} +- {{domxref("ImageData")}} +- {{domxref("TextMetrics")}} +- {{domxref("Path2D")}} {{experimental_inline}} + +這些與`WebGLRenderingContext`有關的標識,皆引用在[WebGL](/zh-TW/docs/Web/WebGL) + +## 教程指南 + +- [Canvas tutorial](/zh-TW/docs/Web/API/Canvas_API/Tutorial) + - : 這個全部的課程包含 `` 基礎的使用和高階的應用。 +- [Code snippets: Canvas](/zh-TW/Add-ons/Code_snippets/Canvas) + - : 一些延伸的開發功能,包含``。 +- [Demo: A basic ray-caster](/zh-TW/docs/Web/API/Canvas_API/A_basic_ray-caster) + - : 使用``做的光線追蹤(ray-tracing )範例。 +- [Drawing DOM objects into a canvas](/zh-TW/docs/Web/API/Canvas_API/Drawing_DOM_objects_into_a_canvas) + - : 如何在 DOM``之中,畫個物件。例如 HTML 的元素。 +- [Manipulating video using canvas](/zh-TW/docs/Web/API/Canvas_API/Manipulating_video_using_canvas) + - : 結合{{HTMLElement("video")}} 和 {{HTMLElement("canvas")}} 去控制影像資料的真實時間 + +## 資源 + +### Generic + +- [HTML5 Canvas Deep Dive](http://joshondesign.com/p/books/canvasdeepdive/title.html) +- [Canvas Handbook](http://bucephalus.org/text/CanvasHandbook/CanvasHandbook.html) + +### Libraries + +- [Fabric.js](http://fabricjs.com) is an open-source canvas library with SVG parsing capabilities. +- [Kinetic.js](https://github.com/ericdrowell/KineticJS) is an open-source canvas library focused on interactivity for desktop and mobile applications. +- [Paper.js](http://paperjs.org/) is an open source vector graphics scripting framework that runs on top of the HTML5 Canvas. +- [Origami.js](http://origamijs.com/docs/) is an open source lightweight canvas library. +- [libCanvas](http://libcanvas.github.com/) 是一個強大且輕量化的 canvas 框架。 +- [Processing.js](http://processingjs.org) 是視覺化程式語言 Processing 的移植版。 +- [PlayCanvas](https://playcanvas.com/) is an open source game engine. +- [Pixi.js](http://www.pixijs.com/) is an open source game engine. +- [PlotKit](http://www.liquidx.net/plotkit/) 是一個製作圖表和圖形的函式庫。 +- [Rekapi](https://github.com/jeremyckahn/rekapi) 是一個用來控制動畫影格的 Canvas API。 +- [PhiloGL](http://senchalabs.github.com/philogl/) 是一個可應用在資料視覺化、遊戲開發的 WebGL 框架。 +- [JavaScript InfoVis Toolkit](http://thejit.org/) 可在網頁上建立 2D 的互動式 Canvas 視覺化資料。 +- [EaselJS](http://www.createjs.com/easeljs) 是一個自由 / 開放源始碼的函式庫,目的在簡化 canvas 於遊戲與美術的開發難度,類似 Flash API。 +- [Scrawl-canvas](http://scrawl.rikweb.org.uk/) is another open-source javascript library for creating and manipulating 2d canvas elements + +## 規範 {{Specifications("html.elements.canvas")}} -

參見

+## 參見 - +- [WebGL](/zh-TW/docs/Web/WebGL) diff --git a/files/zh-tw/web/api/canvas_api/tutorial/advanced_animations/index.md b/files/zh-tw/web/api/canvas_api/tutorial/advanced_animations/index.md index 5c78cde04a12a5..91dd0e6f44d25e 100644 --- a/files/zh-tw/web/api/canvas_api/tutorial/advanced_animations/index.md +++ b/files/zh-tw/web/api/canvas_api/tutorial/advanced_animations/index.md @@ -3,22 +3,22 @@ title: Advanced animations slug: Web/API/Canvas_API/Tutorial/Advanced_animations translation_of: Web/API/Canvas_API/Tutorial/Advanced_animations --- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}
+{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}} -
-

在上一章節,我們做了一些基礎動畫且知道它的移動方式。在這部分我們更仔細的介紹它的動畫效果且並增加一些特效,使它看起來更高級。

-
+在上一章節,我們做了一些[基礎動畫](/zh-TW/docs/Web/API/Canvas_API/Tutorial/Basic_animations)且知道它的移動方式。在這部分我們更仔細的介紹它的動畫效果且並增加一些特效,使它看起來更高級。 -

畫一顆球

+## 畫一顆球 -

在這次的動畫練習中使用球來練習。照著下面的步驟完成 canvas 設定。

+在這次的動畫練習中使用球來練習。照著下面的步驟完成 canvas 設定。 -
<canvas id="canvas" width="600" height="300"></canvas>
-
+```html + +``` -

照常理,先在canvas上需要先畫一顆球。創造一個 ball object,它包含的屬性和draw()的方法,使canvas可以在上面繪圖。

+照常理,先在 canvas 上需要先畫一顆球。創造一個 `ball` object,它包含的屬性和`draw()`的方法,使 canvas 可以在上面繪圖。 -
var canvas = document.getElementById('canvas');
+```js
+var canvas = document.getElementById('canvas');
 var ctx = canvas.getContext('2d');
 
 var ball = {
@@ -35,15 +35,17 @@ var ball = {
   }
 };
 
-ball.draw();
+ball.draw(); +``` -

這裡沒什麼特別的,透過{{domxref("CanvasRenderingContext2D.arc()", "arc()")}}的方法,球事實上只是畫下簡單的圓。

+這裡沒什麼特別的,透過{{domxref("CanvasRenderingContext2D.arc()", "arc()")}}的方法,球事實上只是畫下簡單的圓。 -

添加速度

+## 添加速度 -

現在有了一顆球,準備添加基礎的動畫像我們從上章節學到的課程。再次使用{{domxref("window.requestAnimationFrame()")}}控制動畫。添加移動的向量速度使球移動到向量點。對於每個幀(frame),我們使用{{domxref("CanvasRenderingContext2D.clearRect", "clear", "", 1)}}來清除canvas舊的移動幀(frame)。

+現在有了一顆球,準備添加基礎的動畫像我們從[上章節學到的課程](/zh-TW/docs/Web/API/Canvas_API/Tutorial/Basic_animations)。再次使用{{domxref("window.requestAnimationFrame()")}}控制動畫。添加移動的向量速度使球移動到向量點。對於每個幀(frame),我們使用{{domxref("CanvasRenderingContext2D.clearRect", "clear", "", 1)}}來清除 canvas 舊的移動幀(frame)。 -
var canvas = document.getElementById('canvas');
+```js
+var canvas = document.getElementById('canvas');
 var ctx = canvas.getContext('2d');
 var raf;
 
@@ -80,27 +82,31 @@ canvas.addEventListener('mouseout', function(e) {
 });
 
 ball.draw();
-
+``` -

邊界

+## 邊界 -

沒有任何邊界碰撞下,球很快就會跑出canvas。這時需要確認球的 x and y 是否超出 canvas 尺寸,若超出則將球的向量顛倒。所以,我們添加了確認條件在draw方法:

+沒有任何邊界碰撞下,球很快就會跑出 canvas。這時需要確認球的 `x` and `y` 是否超出 canvas 尺寸,若超出則將球的向量顛倒。所以,我們添加了確認條件在`draw`方法: -
if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
+```js
+if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
   ball.vy = -ball.vy;
 }
-if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
+if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
   ball.vx = -ball.vx;
-}
+} +``` -

第一個示範

+### 第一個示範 -

讓我們看看,看似很遠的行徑它如何行徑。移動你的滑鼠在canvas,使動畫開始。

+讓我們看看,看似很遠的行徑它如何行徑。移動你的滑鼠在 canvas,使動畫開始。 - - -

{{EmbedLiveSample("First_demo", "610", "310")}}

+ball.draw(); +``` -

加速性能

+{{EmbedLiveSample("First_demo", "610", "310")}} -

為了使移動看起來更真實,你可以照著範例改變速度:

+## 加速性能 -
ball.vy *= .99;
-ball.vy += .25;
+為了使移動看起來更真實,你可以照著範例改變速度: -

這個使每個幀(frame)的垂直向量減少,所以球將只會在地板彈跳直到結束。

+```js +ball.vy *= .99; +ball.vy += .25; +``` - - -

{{EmbedLiveSample("Second_demo", "610", "310")}}

+ball.draw(); +``` -

追蹤效果

+{{EmbedLiveSample("Second_demo", "610", "310")}} -

直到現在我們已經使用{{domxref("CanvasRenderingContext2D.clearRect", "clearRect")}}方法清除之前的幀(frames)。如果使用重置半透明{{domxref("CanvasRenderingContext2D.fillRect", "fillRect")}}這個方法,可以更淺顯的看出創造追蹤效果。

+## 追蹤效果 -
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
-ctx.fillRect(0, 0, canvas.width, canvas.height);
+直到現在我們已經使用{{domxref("CanvasRenderingContext2D.clearRect", "clearRect")}}方法清除之前的幀(frames)。如果使用重置半透明{{domxref("CanvasRenderingContext2D.fillRect", "fillRect")}}這個方法,可以更淺顯的看出創造追蹤效果。 - +ball.draw(); +``` -

{{EmbedLiveSample("Third_demo", "610", "310")}}

+{{EmbedLiveSample("Third_demo", "610", "310")}} -

增加滑鼠控制

+## 增加滑鼠控制 -

為了能控制球使它跟著滑鼠移動,在這個範例使用mousemove 效果。當 click 事件觸發了這顆球,它又會開始彈跳。

+為了能控制球使它跟著滑鼠移動,在這個範例使用[`mousemove`](/en-US/docs/Web/Reference/Events/mousemove) 效果。當 [`click`](/en-US/docs/Web/Events/click) 事件觸發了這顆球,它又會開始彈跳。 - +```html hidden + +``` -
var canvas = document.getElementById('canvas');
+```js
+var canvas = document.getElementById('canvas');
 var ctx = canvas.getContext('2d');
 var raf;
 var running = false;
@@ -324,10 +335,10 @@ function draw() {
   ball.x += ball.vx;
   ball.y += ball.vy;
 
-  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
+  if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) {
     ball.vy = -ball.vy;
   }
-  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
+  if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) {
     ball.vx = -ball.vx;
   }
 
@@ -356,21 +367,19 @@ canvas.addEventListener('mouseout', function(e) {
 });
 
 ball.draw();
-
+``` -

用你的滑鼠移動這顆球且點擊鬆放它。

+用你的滑鼠移動這顆球且點擊鬆放它。 -

{{EmbedLiveSample("Adding_mouse_control", "610", "310")}}

+{{EmbedLiveSample("Adding_mouse_control", "610", "310")}} -

突破性(遊戲)

+## 突破性(遊戲) -

這個小章節只有解釋一些創造高級動畫的技巧。這裡還有更多!如何增加槳,磚塊,到這個 到 Breakout game demo去看,有我們更多遊戲研發的文章!

+這個小章節只有解釋一些創造高級動畫的技巧。這裡還有更多!如何增加槳,磚塊,到這個 到 [Breakout](http://en.wikipedia.org/wiki/Breakout_%28video_game%29) game demo 去看,有我們更[多遊戲研發](/zh-TW/docs/Games)的文章! -

延伸閱讀

+## 延伸閱讀 - +- {{domxref("window.requestAnimationFrame()")}} +- [Efficient animation for web games](/zh-TW/docs/Games/Techniques/Efficient_animation_for_web_games) -

{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}}

+{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_animations", "Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas")}} diff --git a/files/zh-tw/web/api/canvas_api/tutorial/applying_styles_and_colors/index.md b/files/zh-tw/web/api/canvas_api/tutorial/applying_styles_and_colors/index.md index de877011602f03..169155a27cf816 100644 --- a/files/zh-tw/web/api/canvas_api/tutorial/applying_styles_and_colors/index.md +++ b/files/zh-tw/web/api/canvas_api/tutorial/applying_styles_and_colors/index.md @@ -3,76 +3,76 @@ title: 套用樣式與顏色 slug: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors --- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}}
+{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Drawing_shapes", "Web/API/Canvas_API/Tutorial/Drawing_text")}} -

繪畫圖形章節中,我們只用了預設的線條與填滿樣式,而在本章,我們將進一步看看所有可用的樣式選項,畫出更吸引人的圖。

+在[繪畫圖形](/zh-TW/docs//zh-TW/docs/Web/Guide/HTML/Canvas_tutorial/Drawing_shapes)章節中,我們只用了預設的線條與填滿樣式,而在本章,我們將進一步看看所有可用的樣式選項,畫出更吸引人的圖。 -

顏色

+## 顏色 -

U截至目前為止我們只有看到繪圖環境的方法(methods),如果我們想要設定圖形的顏色,我們有兩個屬性能用: fillStylestorkeStyle.

+U 截至目前為止我們只有看到繪圖環境的方法(methods),如果我們想要設定圖形的顏色,我們有兩個屬性能用: `fillStyle`與`storkeStyle.` -
-
fillStyle = color
-
設定填滿圖形時用的顏色.
-
strokeStyle = color
-
設定勾勒圖形時用的顏色.
-
+- `fillStyle = color` + - : 設定填滿圖形時用的顏色. +- `strokeStyle = color` + - : 設定勾勒圖形時用的顏色. -

其中color可以是CSS{{cssxref("<color>")}}表示字串、漸層色物件(gradient color)或是模式物件(pattern object),現在先看一下CSS{<color>}表示字串,稍後再看另外兩個項目.

+其中`color`可以是 CSS{{cssxref("<color>")}}表示字串、漸層色物件(gradient color)或是模式物件(pattern object),現在先看一下 CSS{\}表示字串,稍後再看另外兩個項目. -

預設上勾勒和填滿色是黑色(CSS顏色值為#000000).

+預設上勾勒和填滿色是黑色(CSS 顏色值為#000000). -
-

Note: 一旦改變了strokeStyle的顏色值,那麼之後圖形勾勒顏色都會變成新顏色,同樣狀況一樣適用於fillStyle.

-
+> **備註:** 一旦改變了 strokeStyle 的顏色值,那麼之後圖形勾勒顏色都會變成新顏色,同樣狀況一樣適用於 fillStyle. -

合格的顏色值請參照CSS3{{cssxref("<color>")}}規範,下面範例所標示的顏色都指向同一個顏色.

+合格的顏色值請參照 CSS3{{cssxref("<color>")}}規範,下面範例所標示的顏色都指向同一個顏色. -
// these all set the fillStyle to 'orange'
+```js
+// these all set the fillStyle to 'orange'
 
 ctx.fillStyle = "orange";
 ctx.fillStyle = "#FFA500";
 ctx.fillStyle = "rgb(255,165,0)";
 ctx.fillStyle = "rgba(255,165,0,1)";
-
+``` -
-

Note: 目前Gecko引擎並不支援CSS3全部的顏色值,例如hsl(100%,25%,0)和rgb(0,100%,0)就不被支援.

-
+> **備註:** 目前 Gecko 引擎並不支援 CSS3 全部的顏色值,例如 hsl(100%,25%,0)和 rgb(0,100%,0)就不被支援. -

fillStyle範例

+### `fillStyle`範例 -

這裡我們利用兩個for迴圈來畫出一個矩形陣列,而且陣列中每一個矩形的顏色都不相同。下面程式碼透過改變i和j兩個變數來分別變換RGB中的紅色值和綠色值,然後為每一個矩形產生自己專屬的顏色值。透過改變RGB的各顏色值,我們可以產生各式各樣的調色盤,像是逐步調整顏色值,你也可以做出像Photoshop內建一樣的調色盤。

+這裡我們利用兩個 for 迴圈來畫出一個矩形陣列,而且陣列中每一個矩形的顏色都不相同。下面程式碼透過改變 i 和 j 兩個變數來分別變換 RGB 中的紅色值和綠色值,然後為每一個矩形產生自己專屬的顏色值。透過改變 RGB 的各顏色值,我們可以產生各式各樣的調色盤,像是逐步調整顏色值,你也可以做出像 Photoshop 內建一樣的調色盤。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i=0;i<6;i++){
-    for (var j=0;j<6;j++){
+  for (var i=0;i<6;i++){
+    for (var j=0;j<6;j++){
       ctx.fillStyle = 'rgb(' + Math.floor(255-42.5*i) + ',' +
                        Math.floor(255-42.5*j) + ',0)';
       ctx.fillRect(j*25,i*25,25,25);
     }
   }
-}
+} +``` - +```js hidden +draw(); +``` -

結果如下:

+結果如下: -

{{EmbedLiveSample("A_fillStyle_example", 160, 160, "canvas_fillstyle.png")}}

+{{EmbedLiveSample("A_fillStyle_example", 160, 160, "canvas_fillstyle.png")}} -

strokeStyle範例

+### `strokeStyle`範例 -

本例和前例相當類似,不同的是我們改用arc()方法畫圓形而不是矩形、改設定strokeStyle變換圖形輪廓顏色。

+本例和前例相當類似,不同的是我們改用 arc()方法畫圓形而不是矩形、改設定 strokeStyle 變換圖形輪廓顏色。 -
  function draw() {
+```js
+  function draw() {
     var ctx = document.getElementById('canvas').getContext('2d');
-    for (var i=0;i<6;i++){
-      for (var j=0;j<6;j++){
+    for (var i=0;i<6;i++){
+      for (var j=0;j<6;j++){
         ctx.strokeStyle = 'rgb(0,' + Math.floor(255-42.5*i) + ',' +
                          Math.floor(255-42.5*j) + ')';
         ctx.beginPath();
@@ -81,44 +81,46 @@ ctx.fillStyle = "rgba(255,165,0,1)";
       }
     }
   }
-
+``` - +```js hidden +draw(); +``` -

結果如下:

+結果如下: -

{{EmbedLiveSample("A_strokeStyle_example", "180", "180", "canvas_strokestyle.png")}}

+{{EmbedLiveSample("A_strokeStyle_example", "180", "180", "canvas_strokestyle.png")}} -

透明度

+## 透明度 -

透過設定globalAlpha屬性或是以半透明顏色值設定strokeStyle與fillStyle屬性,除了畫不透明的圖形,我們還可以畫半透明的圖形。

+透過設定 globalAlpha 屬性或是以半透明顏色值設定 strokeStyle 與 fillStyle 屬性,除了畫不透明的圖形,我們還可以畫半透明的圖形。 -
-
globalAlpha = transparencyValue
-
允許值介於0.0(全透明)到1.0(不透明)。一旦設定後,之後畫布上畫的所有圖形的不透明度都會套用此設定值。預設值為1.0。
-
+- `globalAlpha = transparencyValue` + - : 允許值介於 0.0(全透明)到 1.0(不透明)。一旦設定後,之後畫布上畫的所有圖形的不透明度都會套用此設定值。預設值為 1.0。 -

當我們想畫一系列相同不透明度的圖,設定globalAlpha值是一個方便的作法。

+當我們想畫一系列相同不透明度的圖,設定 globalAlpha 值是一個方便的作法。 -

由CSS3顏色值能夠指定不透明度,我們也可以如下面一般,設定strokeStyle以及fillStyle來變更不透明度。

+由 CSS3 顏色值能夠指定不透明度,我們也可以如下面一般,設定 strokeStyle 以及 fillStyle 來變更不透明度。 -
// Assigning transparent colors to stroke and fill style
+```js
+// Assigning transparent colors to stroke and fill style
 
 ctx.strokeStyle = "rgba(255,0,0,0.5)";
 ctx.fillStyle = "rgba(255,0,0,0.5)";
-
+``` -

rgba()函數比rgb()函數多出一個不透明度參數,允許值介於0.0(全透明)到1.0(不透明).

+rgba()函數比 rgb()函數多出一個不透明度參數,允許值介於 0.0(全透明)到 1.0(不透明). -

globalAlpha範例

+### `globalAlpha`範例 -

下面我們將在四個方格色塊背景上畫一系列半透明圓形。對於所有圓形,我們藉由設置globalAlpha屬性值為0.2使得圓形變成半透明,然後for迴圈裡我們逐一增加圓形繪圖半徑,最終結果看起來便像是輻射狀漸層圖案,而且圓形相互疊加在彼此之上後,又加深了重疊區域的不透明度,只要我們不斷增加圓形數量,最後圖片中央將被完全遮蓋,看不到背後的背景。

+下面我們將在四個方格色塊背景上畫一系列半透明圓形。對於所有圓形,我們藉由設置 globalAlpha 屬性值為 0.2 使得圓形變成半透明,然後 for 迴圈裡我們逐一增加圓形繪圖半徑,最終結果看起來便像是輻射狀漸層圖案,而且圓形相互疊加在彼此之上後,又加深了重疊區域的不透明度,只要我們不斷增加圓形數量,最後圖片中央將被完全遮蓋,看不到背後的背景。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
   // draw background
   ctx.fillStyle = '#FD0';
@@ -135,26 +137,30 @@ ctx.fillStyle = "rgba(255,0,0,0.5)";
   ctx.globalAlpha = 0.2;
 
   // Draw semi transparent circles
-  for (i=0;i<7;i++){
+  for (i=0;i<7;i++){
     ctx.beginPath();
     ctx.arc(75,75,10+10*i,0,Math.PI*2,true);
     ctx.fill();
   }
-}
+} +``` - +```js hidden +draw(); +``` -

{{EmbedLiveSample("A_globalAlpha_example", "180", "180", "canvas_globalalpha.png")}}

+{{EmbedLiveSample("A_globalAlpha_example", "180", "180", "canvas_globalalpha.png")}} -

rgba()使用範例

+### `rgba()`使用範例 -

這個範例類似於上面的範例,但不同的是我們改畫半透明的矩形。rgba()在使用上會多一點彈性,因為我們可以分別設置勾勒和填滿圖形的不透明度。

+這個範例類似於上面的範例,但不同的是我們改畫半透明的矩形。rgba()在使用上會多一點彈性,因為我們可以分別設置勾勒和填滿圖形的不透明度。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
 
   // Draw background
@@ -168,50 +174,52 @@ ctx.fillStyle = "rgba(255,0,0,0.5)";
   ctx.fillRect(0,112.5,150,37.5);
 
   // Draw semi transparent rectangles
-  for (var i=0;i<10;i++){
+  for (var i=0;i<10;i++){
     ctx.fillStyle = 'rgba(255,255,255,'+(i+1)/10+')';
-    for (var j=0;j<4;j++){
+    for (var j=0;j<4;j++){
       ctx.fillRect(5+i*14,5+j*37.5,14,27.5)
     }
   }
-}
+} +``` - +```js hidden +draw(); +``` -

{{EmbedLiveSample("An_example_using_rgba()", "180", "180", "canvas_rgba.png")}}

+{{EmbedLiveSample("An_example_using_rgba()", "180", "180", "canvas_rgba.png")}} -

線條樣式

+## 線條樣式 -

有數種屬性可以讓我們設定線條樣式.

+有數種屬性可以讓我們設定線條樣式. -
-
lineWidth = value
-
設定線條寬度。
-
lineCap = type
-
設定線條結尾的樣式。
-
lineJoin = type
-
設定線條和線條間接合處的樣式。
-
miterLimit = value
-
限制當兩條線相交時交接處最大長度;所謂交接處長度(miter length)是指線條交接處內角頂點到外角頂點的長度。
-
+- `lineWidth = value` + - : 設定線條寬度。 +- `lineCap = type` + - : 設定線條結尾的樣式。 +- `lineJoin = type` + - : 設定線條和線條間接合處的樣式。 +- `miterLimit = value` + - : 限制當兩條線相交時交接處最大長度;所謂交接處長度(miter length)是指線條交接處內角頂點到外角頂點的長度。 -

底下我們將一一示範這些屬性的用途。

+底下我們將一一示範這些屬性的用途。 -

lineWidth範例

+### `lineWidth`範例 -

此屬性決定線條寬度,必須為正數,預設值為1.0單位。

+此屬性決定線條寬度,必須為正數,預設值為 1.0 單位。 -

線條寬度的起算點是從繪圖路徑中央開始往兩旁各延伸一半設定寬度,由於畫布座標不直接對應到像素(pixel),所以要比較小心設定好取得清晰的直線。

+線條寬度的起算點是從繪圖路徑中央開始往兩旁各延伸一半設定寬度,由於畫布座標不直接對應到像素(pixel),所以要比較小心設定好取得清晰的直線。 -

由下方例子可以明顯看到,畫布上有10條直線,由左至右,從最小的1.0單位寬開始逐漸加寬,請注意奇數寬度直線會因為繪圖路徑位置關係而比較模糊。

+由下方例子可以明顯看到,畫布上有 10 條直線,由左至右,從最小的 1.0 單位寬開始逐漸加寬,請注意奇數寬度直線會因為繪圖路徑位置關係而比較模糊。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
-  for (var i = 0; i < 10; i++){
+  for (var i = 0; i < 10; i++){
     ctx.lineWidth = 1+i;
     ctx.beginPath();
     ctx.moveTo(5+i*14,5);
@@ -219,54 +227,51 @@ ctx.fillStyle = "rgba(255,0,0,0.5)";
     ctx.stroke();
   }
 }
-
- - +```html hidden + +``` -

{{EmbedLiveSample("A_lineWidth_example", "180", "180", "canvas_linewidth.png")}}

+```js hidden +draw(); +``` -

為了畫出清晰的直線,我們需要了解繪圖路徑是如何產生;如下方圖示,網格代表畫布座標軸,網格所框出的方格則代表螢幕上的像素,第一張圖片填滿了座標(2,1)到(5,5)的紅色區域,而這個紅色區域的邊際正好符合像素間的邊際,所以會產生出清晰的影像。

+{{EmbedLiveSample("A_lineWidth_example", "180", "180", "canvas_linewidth.png")}} -

+為了畫出清晰的直線,我們需要了解繪圖路徑是如何產生;如下方圖示,網格代表畫布座標軸,網格所框出的方格則代表螢幕上的像素,第一張圖片填滿了座標(2,1)到(5,5)的紅色區域,而這個紅色區域的邊際正好符合像素間的邊際,所以會產生出清晰的影像。 -

第二張圖片中,有一條寬1.0單位的直線從座標(3,1)到(3,5)被畫在畫布上,不過由於線條寬度的起算點是從繪圖路徑中央開始往兩旁各延伸一半設定寬度,所以當勾勒線條時,繪圖路徑兩旁的像素格只有一半會被填滿暗藍色,至於另外一半則會經由計算填入近似色(淡藍色),結果就是整格像素並非全部填入相同的暗藍色,進而產生出邊緣較為模糊的線條,上面程式碼範例中的奇數寬度直線就是因此而產生不清晰的線條。

+![](canvas-grid.png) -

為了避免劃出邊緣模糊直線,我們必須精準設定繪圖路徑位置,就本範例而言,如果我們的直線繪圖路徑是從座標(3.5, 1)到(3.5, 5)的話(如第三張圖),那麼1.0單位寬的直線將剛好填滿像素格,所以我們將可以畫出清晰的直線。

+第二張圖片中,有一條寬 1.0 單位的直線從座標(3,1)到(3,5)被畫在畫布上,不過由於線條寬度的起算點是從繪圖路徑中央開始往兩旁各延伸一半設定寬度,所以當勾勒線條時,繪圖路徑兩旁的像素格只有一半會被填滿暗藍色,至於另外一半則會經由計算填入近似色(淡藍色),結果就是整格像素並非全部填入相同的暗藍色,進而產生出邊緣較為模糊的線條,上面程式碼範例中的奇數寬度直線就是因此而產生不清晰的線條。 -
-

Note: 請注意本範例的Y軸座標都是整數點,若非如此,一樣會導致線條端點的像素格無法剛好被填滿的現象,而且同時最後產生的結果也會被lineCap給影響;倘若lineCap值為預設butt時,我們會需要為奇數寬度直線計算一下非整數的座標點,倘若lineCap樣式為square,那麼線段端點的像素格將自動被完整填滿。

+為了避免劃出邊緣模糊直線,我們必須精準設定繪圖路徑位置,就本範例而言,如果我們的直線繪圖路徑是從座標(3.5, 1)到(3.5, 5)的話(如第三張圖),那麼 1.0 單位寬的直線將剛好填滿像素格,所以我們將可以畫出清晰的直線。 -

還有一點需要注意,只要繪圖路徑被closePath()函數閉合起來,這樣便沒有了線條端點,所有的線條端點都會依據lineJoin樣式全部前後互相連接起來,這會自動延伸端點邊緣到線段接合處,如果此時接合端點是水平或垂直的話,位於中央的像素格將會被完整填滿。後面的說明會介紹lineCap和lineJoin樣式。

-
+> **備註:** 請注意本範例的 Y 軸座標都是整數點,若非如此,一樣會導致線條端點的像素格無法剛好被填滿的現象,而且同時最後產生的結果也會被 lineCap 給影響;倘若 lineCap 值為預設 butt 時,我們會需要為奇數寬度直線計算一下非整數的座標點,倘若 lineCap 樣式為 square,那麼線段端點的像素格將自動被完整填滿。還有一點需要注意,只要繪圖路徑被 closePath()函數閉合起來,這樣便沒有了線條端點,所有的線條端點都會依據 lineJoin 樣式全部前後互相連接起來,這會自動延伸端點邊緣到線段接合處,如果此時接合端點是水平或垂直的話,位於中央的像素格將會被完整填滿。後面的說明會介紹 lineCap 和 lineJoin 樣式。 -

至於本例中偶數寬度的直線,為了避免模糊,繪圖路徑最好是落在整數座標點上。

+至於本例中偶數寬度的直線,為了避免模糊,繪圖路徑最好是落在整數座標點上。 -

雖然處裡2D繪圖縮放有些麻煩,但只要仔細計算像素格和繪圖路徑位置,縱使進行圖像縮放或變形,圖像輸出還是可以保持正確。一條寬1.0單位的直線,只要位置計算正確,放大兩倍後會變成一條2個像素寬的清晰直線,而且還是會保持正確位置。

+雖然處裡 2D 繪圖縮放有些麻煩,但只要仔細計算像素格和繪圖路徑位置,縱使進行圖像縮放或變形,圖像輸出還是可以保持正確。一條寬 1.0 單位的直線,只要位置計算正確,放大兩倍後會變成一條 2 個像素寬的清晰直線,而且還是會保持正確位置。 -

lineCap範例

+### `lineCap`範例 -

這個屬性決定線條端點的樣式,總共有三種樣式可選:

+這個屬性決定線條端點的樣式,總共有三種樣式可選: -

+![](canvas_linecap.png) -
-
butt
-
線條端點樣式為方形
-
round
-
線條端點樣式為圓形
-
square
-
增加寬同線條寬度、高線條寬度一半的的方塊於線條端點
-
+- `butt` + - : 線條端點樣式為方形 +- `round` + - : 線條端點樣式為圓形 +- `square` + - : 增加寬同線條寬度、高線條寬度一半的的方塊於線條端點 -

下面程式碼會畫出三條線,每條線的lineCap值皆不同。然後為了看清差異點,我們加上了兩條淡藍色的輔助線,線條的繪圖起始點和終點都剛好落在輔助線上。

+下面程式碼會畫出三條線,每條線的 lineCap 值皆不同。然後為了看清差異點,我們加上了兩條淡藍色的輔助線,線條的繪圖起始點和終點都剛好落在輔助線上。 -

最左邊的線條其lineCap為butt,不難看出它完全介於輔助線之間;第二條線其lineCap為round,端點樣式為半徑等於線條寬度一半的半圓;最右邊的線條其lineCap為square,端點樣式為寬同線條寬度、高線條寬度一半的的方塊。

+最左邊的線條其 lineCap 為 butt,不難看出它完全介於輔助線之間;第二條線其 lineCap 為 round,端點樣式為半徑等於線條寬度一半的半圓;最右邊的線條其 lineCap 為 square,端點樣式為寬同線條寬度、高線條寬度一半的的方塊。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
   var lineCap = ['butt','round','square'];
 
@@ -281,7 +286,7 @@ ctx.fillStyle = "rgba(255,0,0,0.5)";
 
   // Draw lines
   ctx.strokeStyle = 'black';
-  for (var i=0;i<lineCap.length;i++){
+  for (var i=0;i
+```
 
-
+```js hidden
+draw();
+```
 
-

{{EmbedLiveSample("A_lineCap_example", "180", "180", "canvas_linecap.png")}}

+{{EmbedLiveSample("A_lineCap_example", "180", "180", "canvas_linecap.png")}} -

lineJoin範例

+### `lineJoin`範例 -

lineJoin屬性決定兩個連接區端(如線條、弧形或曲線)如何連接(對於長度為零,亦即終點和控制點為同一點的圖形無效)。

+lineJoin 屬性決定兩個連接區端(如線條、弧形或曲線)如何連接(對於長度為零,亦即終點和控制點為同一點的圖形無效)。 -

lineJoin屬性共有三個屬性值如下,其中miter為預設值,請注意一點若是兩個連接區段的繪圖方向一致,那代表不會有連接處,所以測定是無效的。

+lineJoin 屬性共有三個屬性值如下,其中 miter 為預設值,請注意一點若是兩個連接區段的繪圖方向一致,那代表不會有連接處,所以測定是無效的。 -

+![](canvas_linejoin.png) -
-
round
-
代表圓弧型連接樣式。
-
bevel
-
代表斜面型連接樣式。在連接區段的共同終點處填滿一個三角形區域,將原本的外接角處形成一個切面。
-
miter
-
代表斜交型連接樣式。向外延伸連結區段外緣直到相交於一點,然後形成菱形區域,而miterLimit屬性會影響miter屬性。
-
+- `round` + - : 代表圓弧型連接樣式。 +- `bevel` + - : 代表斜面型連接樣式。在連接區段的共同終點處填滿一個三角形區域,將原本的外接角處形成一個切面。 +- `miter` + - : 代表斜交型連接樣式。向外延伸連結區段外緣直到相交於一點,然後形成菱形區域,而 miterLimit 屬性會影響 miter 屬性。 -

下方程式碼和圖形輸出展示了lineJoin在不同屬性值下呈現的不同結果

+下方程式碼和圖形輸出展示了 lineJoin 在不同屬性值下呈現的不同結果 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
   var lineJoin = ['round','bevel','miter'];
   ctx.lineWidth = 10;
-  for (var i=0;i<lineJoin.length;i++){
+  for (var i=0;i
+```
 
-
+```js hidden
+draw();
+```
 
-

{{EmbedLiveSample("A_lineJoin_example", "180", "180", "canvas_linejoin.png")}}

+{{EmbedLiveSample("A_lineJoin_example", "180", "180", "canvas_linejoin.png")}} -

miterLimit屬性

+### `miterLimit`屬性 -

前面範例顯示出,當lineJoin值為miter時,兩條線的外緣會延伸相交,所以,當這兩條相交線的相交角度越小的話,他們的延伸交會點就會越遠離內緣連接點,而且隨著角度變小,距離呈指數型增長。

+前面範例顯示出,當 lineJoin 值為 miter 時,兩條線的外緣會延伸相交,所以,當這兩條相交線的相交角度越小的話,他們的延伸交會點就會越遠離內緣連接點,而且隨著角度變小,距離呈指數型增長。 -

miterLimit會限制延伸交會點最遠可以離內緣連接點到多遠,當延伸交會點的落點超出這個範圍,那麼便以斜面(bevel)作為交接樣式。請注意,最大miter長度為線寬乘於miterLimit值,所以miterLimit可以獨立於目前顯示縮放尺寸或其他變形設定。

+miterLimit 會限制延伸交會點最遠可以離內緣連接點到多遠,當延伸交會點的落點超出這個範圍,那麼便以斜面(bevel)作為交接樣式。請注意,最大 miter 長度為線寬乘於 miterLimit 值,所以 miterLimit 可以獨立於目前顯示縮放尺寸或其他變形設定。 -

miterLimit預設值為10.0。

+miterLimit 預設值為 10.0。 -

更精確來說,miter限制是指延伸長度(在HTML畫布上,這個長度是外緣相交角到連接區段的共同繪圖路經終點)相對於一半線寬的最大允許比率;也等同於,外緣距內緣相交點之距離相對於線寬的的最大允許比率;相當於,連接區最小內緣角的一半角度的餘割(cosecant)值, 小於此值則便以斜面(bevel)作為交接樣式:

+更精確來說,miter 限制是指延伸長度(在 HTML 畫布上,這個長度是外緣相交角到連接區段的共同繪圖路經終點)相對於一半線寬的最大允許比率;也等同於,外緣距內緣相交點之距離相對於線寬的的最大允許比率;相當於,連接區最小內緣角的一半角度的餘割(cosecant)值, 小於此值則便以斜面(bevel)作為交接樣式: -
    -
  • miterLimit = max miterLength / lineWidth = 1 / sin ( min θ / 2 )
  • -
  • 10.0的預設miterLimit值會移除任何角度小於11度的相接線段的miter交接。
  • -
  • miter限制值如果等於根號2(約1.4142136)會移除銳角的miter交接,只有直角或鈍角的不會被移除。
  • -
  • miter限制值如果等於1.0會移除所有的miter交接。
  • -
  • 小於1.0不是合法的限制值。
  • -
+- `miterLimit` = **max** `miterLength` / `lineWidth` = 1 / **sin** ( **min** _θ_ / 2 ) +- 10.0 的預設 miterLimit 值會移除任何角度小於 11 度的相接線段的 miter 交接。 +- miter 限制值如果等於根號 2(約 1.4142136)會移除銳角的 miter 交接,只有直角或鈍角的不會被移除。 +- miter 限制值如果等於 1.0 會移除所有的 miter 交接。 +- 小於 1.0 不是合法的限制值。 -

下面是一個範例,其中藍線標示出各個線條繪圖路徑的起始點與終點。

+下面是一個範例,其中藍線標示出各個線條繪圖路徑的起始點與終點。 -

倘若設定範例程式碼中的miterLimit低於4.2,所有的miter交接都會被移除,取而代之的是出現在藍線附近的bevel交接;倘若設定miterLimit大於10,那麼大部分的miter交接都會出現,而且你會發現,由左到右,miter長度逐漸縮短,這是由於線條相交角度逐漸加大之故;倘若設定中間值,那麼左邊會出現bevel交接,右邊會出現miter交接。

+倘若設定範例程式碼中的 miterLimit 低於 4.2,所有的 miter 交接都會被移除,取而代之的是出現在藍線附近的 bevel 交接;倘若設定 miterLimit 大於 10,那麼大部分的 miter 交接都會出現,而且你會發現,由左到右,miter 長度逐漸縮短,這是由於線條相交角度逐漸加大之故;倘若設定中間值,那麼左邊會出現 bevel 交接,右邊會出現 miter 交接。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
 
   // Clear canvas
@@ -391,71 +398,72 @@ ctx.fillStyle = "rgba(255,0,0,0.5)";
   // Draw lines
   ctx.beginPath();
   ctx.moveTo(0,100);
-  for (i=0;i<24;i++){
+  for (i=0;i<24;i++){
     var dy = i%2==0 ? 25 : -25 ;
     ctx.lineTo(Math.pow(i,1.5)*2,75+dy);
   }
   ctx.stroke();
   return false;
 }
-
- - - -

{{EmbedLiveSample("A_demo_of_the_miterLimit_property", "400", "180", "canvas_miterlimit.png")}}

- -

漸層

- -

如同其他繪圖軟體可以畫出線性和放射狀的漸層圖案,透過設定fillStyle和strokeStyle屬性為canvasGradient漸層物件,我們也可以在canvas上做到一樣的效果。要創造漸層物件,可以使用下面的方法:

- -
-
createLinearGradient(x1, y1, x2, y2)
-
產生一個線性漸層物件,其漸層起始點為(x1, y1)、終點為(x2, y2)。
-
createRadialGradient(x1, y1, r1, x2, y2, r2)
-
產生一個放射狀漸層物件,第一個圓之圓心落在(x1, y1)、半徑為r1,第一個圓之圓心落在(x2, y2)、半徑為r2。
-
- -

例如:

- -
var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
+```
+
+```html hidden
+
+  
+    
+    
+  
+
Change the miterLimit by entering a new value below and clicking the redraw button.

+
+ + + +
+
+``` + +```js hidden +document.getElementById('miterLimit').value = document.getElementById('canvas').getContext('2d').miterLimit; +draw(); +``` + +{{EmbedLiveSample("A_demo_of_the_miterLimit_property", "400", "180", "canvas_miterlimit.png")}} + +## 漸層 + +如同其他繪圖軟體可以畫出線性和放射狀的漸層圖案,透過設定 fillStyle 和 strokeStyle 屬性為 canvasGradient 漸層物件,我們也可以在 canvas 上做到一樣的效果。要創造漸層物件,可以使用下面的方法: + +- `createLinearGradient(x1, y1, x2, y2)` + - : 產生一個線性漸層物件,其漸層起始點為(x1, y1)、終點為(x2, y2)。 +- `createRadialGradient(x1, y1, r1, x2, y2, r2)` + - : 產生一個放射狀漸層物件,第一個圓之圓心落在(x1, y1)、半徑為 r1,第一個圓之圓心落在(x2, y2)、半徑為 r2。 + +例如: + +```js +var lineargradient = ctx.createLinearGradient(0, 0, 150, 150); var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100); -
+``` -

一旦產生了canvasGradient漸層物件,我們用addColorStop()方法可以添加顏色上去。

+一旦產生了 canvasGradient 漸層物件,我們用 addColorStop()方法可以添加顏色上去。 -
-
gradient.addColorStop(position, color)
-
於gradient漸層物件建立一個顏色點,其中color是CSS{{cssxref("<color>")}}的字串表示,而position介於0.0到1.0之間,定義了該顏色在漸層中的相對位置。呼叫這個方法會指定當進行到設定的位置時,漸層需要完全轉變成設定的顏色。
-
+- `gradient.addColorStop(position, color)` + - : 於 gradient 漸層物件建立一個顏色點,其中 color 是 CSS{{cssxref("<color>")}}的字串表示,而 position 介於 0.0 到 1.0 之間,定義了該顏色在漸層中的相對位置。呼叫這個方法會指定當進行到設定的位置時,漸層需要完全轉變成設定的顏色。 -

我們可以按照需要設定無數個顏色點,下面是一個簡單的由白到黑的簡單漸層範例程式碼。

+我們可以按照需要設定無數個顏色點,下面是一個簡單的由白到黑的簡單漸層範例程式碼。 -
var lineargradient = ctx.createLinearGradient(0,0,150,150);
+```js
+var lineargradient = ctx.createLinearGradient(0,0,150,150);
 lineargradient.addColorStop(0, 'white');
 lineargradient.addColorStop(1, 'black');
-
+``` -

createLinearGradient範例

+### `createLinearGradient`範例 -

本範例中,我們將建立兩種漸層,如範例所示,strokeStyle和fillSyle屬性都可以接受canvasGradient物件作為屬性值。

+本範例中,我們將建立兩種漸層,如範例所示,strokeStyle 和 fillSyle 屬性都可以接受 canvasGradient 物件作為屬性值。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
 
   // Create gradients
@@ -478,25 +486,28 @@ lineargradient.addColorStop(1, 'black');
   ctx.strokeRect(50,50,50,50);
 
 }
-
+``` - +```js hidden +draw(); +``` -

第一個漸層為背景漸層,範例中我們在一個位置上指定了兩種顏色(白色到綠色),這樣做會產生非常突然的顏色轉換,一般來說,不管如何設定顏色點順序都沒關係,然而就這個例子而言,這種作法太過強烈了,但是如果這是你想要的顏色漸層順序,那其實也是可以。

+第一個漸層為背景漸層,範例中我們在一個位置上指定了兩種顏色(白色到綠色),這樣做會產生非常突然的顏色轉換,一般來說,不管如何設定顏色點順序都沒關係,然而就這個例子而言,這種作法太過強烈了,但是如果這是你想要的顏色漸層順序,那其實也是可以。 -

第二個漸層起始位置(position 0.0)的顏色並沒有被指定,所以下一個漸層顏色會自動被設為起始位置顏色,因此即使我們沒有指定漸層起始位置顏色也沒有關係,就像本範例自動會設定起始位置的顏色等於位置0.5的黑色。

+第二個漸層起始位置(position 0.0)的顏色並沒有被指定,所以下一個漸層顏色會自動被設為起始位置顏色,因此即使我們沒有指定漸層起始位置顏色也沒有關係,就像本範例自動會設定起始位置的顏色等於位置 0.5 的黑色。 -

{{EmbedLiveSample("A_createLinearGradient_example", "180", "180", "canvas_lineargradient.png")}}

+{{EmbedLiveSample("A_createLinearGradient_example", "180", "180", "canvas_lineargradient.png")}} -

createRadialGradient範例

+### `createRadialGradient`範例 -

這邊我們定義了四種放射狀漸層,相較於一般在Photoshop看到的”經典”放射狀漸層圖案(漸層從一個圖案中心點向外呈圓心狀延伸),因為我們可以控制漸層起始和終止點,我們可以做到更好的效果。

+這邊我們定義了四種放射狀漸層,相較於一般在 Photoshop 看到的”經典”放射狀漸層圖案(漸層從一個圖案中心點向外呈圓心狀延伸),因為我們可以控制漸層起始和終止點,我們可以做到更好的效果。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
 
   // Create gradients
@@ -530,65 +541,61 @@ lineargradient.addColorStop(1, 'black');
   ctx.fillStyle = radgrad;
   ctx.fillRect(0,0,150,150);
 }
-
+``` - +```js hidden +draw(); +``` -

程式碼範例中,為了營造出3D效果,我們讓起始點和終止點位於不同位置,請注意,最好不要讓內外圈相重疊,以避免難以預測的奇怪效果。

+程式碼範例中,為了營造出 3D 效果,我們讓起始點和終止點位於不同位置,請注意,最好不要讓內外圈相重疊,以避免難以預測的奇怪效果。 -

每一個漸層圖案最後一個漸層色都是全透明的,如果希望倒數第二個漸層色能夠平順地轉換到這個最後一個漸層色,那麼兩者應該設定一樣的顏色值,像是程式碼範例中的漸層色 #019F62 其實就等於 rgba(1,159,98,1)。

+每一個漸層圖案最後一個漸層色都是全透明的,如果希望倒數第二個漸層色能夠平順地轉換到這個最後一個漸層色,那麼兩者應該設定一樣的顏色值,像是程式碼範例中的漸層色 #019F62 其實就等於 rgba(1,159,98,1)。 -

{{EmbedLiveSample("A_createRadialGradient_example", "180", "180", "canvas_radialgradient.png")}}

+{{EmbedLiveSample("A_createRadialGradient_example", "180", "180", "canvas_radialgradient.png")}} -

樣式(Patterns)

+## 樣式(Patterns) -

先前的範例中,我們都是藉由迴圈來重複產生影像樣式,不過其實有一條更簡單的方法,那就是呼叫createPattern方法。

+先前的範例中,我們都是藉由迴圈來重複產生影像樣式,不過其實有一條更簡單的方法,那就是呼叫 createPattern 方法。 -
-
createPattern(image, type)
-
呼叫createPattern()會產一個畫布樣式物件,然後回傳出來。
- 其中image是CanvasImageSource類別物件(像是{{domxref("HTMLImageElement")}},、<canvas>元素、{{HTMLElement("video")}} 元素等)
-
+- `createPattern(image, type)` + - : 呼叫 createPattern()會產一個畫布樣式物件,然後回傳出來。 + 其中 image 是[CanvasImageSource](http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#image-sources-for-2d-rendering-contexts)類別物件(像是{{domxref("HTMLImageElement")}},、\元素、{{HTMLElement("video")}} 元素等) -

Type是一串字串,定義了如何產生樣式,允許的值有:

+Type 是一串字串,定義了如何產生樣式,允許的值有: -
-
repeat
-
沿垂直與水平方向重複排列影像
-
repeat-x
-
只沿水平方向重複排列影像
-
repeat-y
-
只沿垂直方向重複排列影像
-
no-repeat
-
不重複排列影像,只使用一次
-
+- `repeat` + - : 沿垂直與水平方向重複排列影像 +- `repeat-x` + - : 只沿水平方向重複排列影像 +- `repeat-y` + - : 只沿垂直方向重複排列影像 +- `no-repeat` + - : 不重複排列影像,只使用一次 -
-

Note: Firefox現在只支援repeat,所以其他值都是無效的

-
+> **備註:** Firefox 現在只支援 repeat,所以其他值都是無效的 -
Note: 傳入尺寸為0x0像素的畫布會引起錯誤
+> **備註:** 傳入尺寸為 0x0 像素的畫布會引起錯誤 -

利用createPattern()的方法和前面利用漸層的方法十分類似,我們呼叫createPattern()產生{{domxref("CanvasPattern")}}物件,然後將{CanvasPattern}物件設成fillStyle或strokeStyle的屬性值,例如:

+利用 createPattern()的方法和前面利用漸層的方法十分類似,我們呼叫 createPattern()產生{{domxref("CanvasPattern")}}物件,然後將{CanvasPattern}物件設成 fillStyle 或 strokeStyle 的屬性值,例如: -
var img = new Image();
+```js
+var img = new Image();
 img.src = 'someimage.png';
 var ptrn = ctx.createPattern(img,'repeat');
-
+``` -
-

Note: 不像drawImage()方法,呼叫createPattern()方法前影像必須要先載入完成,否則可能圖像的程生會有問題。

-
+> **備註:** 不像 drawImage()方法,呼叫 createPattern()方法前影像必須要先載入完成,否則可能圖像的程生會有問題。 -

createPattern範例

+### `createPattern`範例 -

這個範例中我們把fillStyle屬性值存為樣式物件,比較值得注意的是影像onload事件處理器,這是為了確保影像載入完成後再進行。

+這個範例中我們把 fillStyle 屬性值存為樣式物件,比較值得注意的是影像 onload 事件處理器,這是為了確保影像載入完成後再進行。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
 
   // create new image object to use as pattern
@@ -603,42 +610,43 @@ var ptrn = ctx.createPattern(img,'repeat');
 
   }
 }
-
+``` - +```html hidden + +``` - +```js hidden +draw(); +``` -

結果如下 :

+結果如下 : -

{{EmbedLiveSample("A_createPattern_example", "180", "180", "canvas_createpattern.png")}}

+{{EmbedLiveSample("A_createPattern_example", "180", "180", "canvas_createpattern.png")}} -

陰影

+## 陰影 -

要產生陰影只需要四個屬性:

+要產生陰影只需要四個屬性: -
-
shadowOffsetX = float
-
代表陰影從物件延伸出來的水平距離,預設為0,不受變形矩陣影響。
-
shadowOffsetY = float
-
代表陰影從物件延伸出來的垂直距離,預設為0,不受變形矩陣影響。
-
shadowBlur = float
-
代表陰影模糊大小範圍,預設為0,不受變形矩陣影響,不等同於像素值。
-
shadowColor = {{cssxref("<color>")}}
-
CSS顏色值,代表陰影顏色,預設為全透明。
-
+- `shadowOffsetX = float` + - : 代表陰影從物件延伸出來的水平距離,預設為 0,不受變形矩陣影響。 +- `shadowOffsetY = float` + - : 代表陰影從物件延伸出來的垂直距離,預設為 0,不受變形矩陣影響。 +- `shadowBlur = float` + - : 代表陰影模糊大小範圍,預設為 0,不受變形矩陣影響,不等同於像素值。 +- `shadowColor = {{cssxref("<color>")}}` + - : CSS 顏色值,代表陰影顏色,預設為全透明。 -

shadowOffsetX和shadowOffsetY會決定陰影延伸大小,若是為正值,則陰影會往右(沿X軸)和往下(沿Y軸)延伸,若是為負值,則會往正值相反方向延伸。

+`shadowOffsetX和shadowOffsetY會決定陰影延伸大小,若是為正值,則陰影會往右(沿X軸)和往下(沿Y軸)延伸,若是為負值,則會往正值相反方向延伸。` -
-

基於HTML5提議規格變更,從 開始,陰影只會在source-over的構圖排列下產生

-
+> **備註:** 基於 HTML5 提議規格變更,從 開始,陰影只會在 source-over 的[構圖排列](/zh-TW/docs/Web/Guide/HTML/Canvas_tutorial/Compositing)下產生 -

文字陰影範例

+### 文字陰影範例 -

本程式碼範例會產生一串帶有陰影的文字。

+本程式碼範例會產生一串帶有陰影的文字。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
 
   ctx.shadowOffsetX = 2;
@@ -650,12 +658,16 @@ var ptrn = ctx.createPattern(img,'repeat');
   ctx.fillStyle = "Black";
   ctx.fillText("Sample String", 5, 30);
 }
-
+``` - +```html hidden + +``` - +```js hidden +draw(); +``` -

{{EmbedLiveSample("A_shadowed_text_example", "180", "100", "shadowed-string.png")}}

+{{EmbedLiveSample("A_shadowed_text_example", "180", "100", "shadowed-string.png")}} -

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Using_images", "Web/Guide/HTML/Canvas_tutorial/Transformations")}}

+{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Using_images", "Web/Guide/HTML/Canvas_tutorial/Transformations")}} diff --git a/files/zh-tw/web/api/canvas_api/tutorial/basic_animations/index.md b/files/zh-tw/web/api/canvas_api/tutorial/basic_animations/index.md index 113a6d3690de14..b7d41498f576f0 100644 --- a/files/zh-tw/web/api/canvas_api/tutorial/basic_animations/index.md +++ b/files/zh-tw/web/api/canvas_api/tutorial/basic_animations/index.md @@ -3,73 +3,70 @@ title: 基礎動畫 slug: Web/API/Canvas_API/Tutorial/Basic_animations translation_of: Web/API/Canvas_API/Tutorial/Basic_animations --- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}
+{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}} -

控制{{HTMLElement("canvas")}}元素來產生互動式動畫不是一件難事,當然,如果產生的動畫越複雜越需要多費一些力氣,未來如果有機會我們將說明這一塊。

+控制{{HTMLElement("canvas")}}元素來產生互動式動畫不是一件難事,當然,如果產生的動畫越複雜越需要多費一些力氣,未來如果有機會我們將說明這一塊。 -

由於圖形一但產生後便靜止不動,所以我們必須重新繪圖好移動圖案,產生動畫效果,所以如果繪圖越複雜,繪圖運算也需要消耗越多運算資源和時間,換句話說,電腦效能的好壞將大大影響動畫順暢度,或許這也是畫布動畫最大的限制。

+由於圖形一但產生後便靜止不動,所以我們必須重新繪圖好移動圖案,產生動畫效果,所以如果繪圖越複雜,繪圖運算也需要消耗越多運算資源和時間,換句話說,電腦效能的好壞將大大影響動畫順暢度,或許這也是畫布動畫最大的限制。 -

動畫基本步驟

+## 動畫基本步驟 -

產生一個畫面基本上需要以下步驟 :

+產生一個畫面基本上需要以下步驟 : -
    -
  1. 清除畫布
    - 除了不變的背景畫面,所有先前畫的圖案都要先清除,這個步驟可以透過clearRect()方法達成。
  2. -
  3. 儲存畫布狀態
    - 若是想要每一次重新繪圖時畫布起始狀態都是原始狀態,那麼就需要先行儲存畫布原始狀態。
  4. -
  5. 畫出畫面
    - 畫出需要畫面。
  6. -
  7. 復原畫布狀態
    - 復原畫布狀態以備下次繪圖使用。
  8. -
+1. **清除畫布** + 除了不變的背景畫面,所有先前畫的圖案都要先清除,這個步驟可以透過 clearRect()方法達成。 +2. **儲存畫布狀態** + 若是想要每一次重新繪圖時畫布起始狀態都是原始狀態,那麼就需要先行儲存畫布原始狀態。 +3. **畫出畫面** + 畫出需要畫面。 +4. **復原畫布狀態** + 復原畫布狀態以備下次繪圖使用。 -

控制動畫

+## 控制動畫 -

一般來說當程式碼執行完畢後我們才會看到繪圖結果,所以說我們無法靠執行for迴圈來產生動畫,我們得靠每隔一段時間繪圖來產生動畫,下面將介紹兩種作法。

+一般來說當程式碼執行完畢後我們才會看到繪圖結果,所以說我們無法靠執行 for 迴圈來產生動畫,我們得靠每隔一段時間繪圖來產生動畫,下面將介紹兩種作法。 -

排程更新

+### 排程更新 -

第一種作法是利用{{domxref("window.setInterval()")}}與{{domxref("window.setTimeout()")}}方法。

+第一種作法是利用{{domxref("window.setInterval()")}}與{{domxref("window.setTimeout()")}}方法。 -
-

Note: 針對新版瀏覽器建議採用{{domxref("window.requestAnimationFrame()")}}方法。

-
+> **備註:** 針對新版瀏覽器建議採用{{domxref("window.requestAnimationFrame()")}}方法。 -
-
setInterval(function, delay)
-
每隔delay毫秒,執行輸入function(函數)
-
setTimeout(function, delay)
-
過delay毫秒後,執行輸入function(函數)
-
requestAnimationFrame(callback)
-
告訴瀏覽器你希望執行動畫的時候,要求瀏覽器在重繪下一張畫面之前,呼叫callback函數來更新動畫
-
+- `setInterval(function, delay)` + - : 每隔 delay 毫秒,執行輸入 function(函數) +- `setTimeout(function, delay)` + - : 過 delay 毫秒後,執行輸入 function(函數) +- requestAnimationFrame(callback) + - : 告訴瀏覽器你希望執行動畫的時候,要求瀏覽器在重繪下一張畫面之前,呼叫 callback 函數來更新動畫 -

如果希望不要有任何的使用者互動影響,請使用setInterval(),因為它會確實地每隔一段時間就執行程式碼。如果你想製作遊戲 , 我們能夠使用keyboard 或是 mouse event來控制動畫,並使用setTimeout()函數一起。藉由設定EventListeners,我們能夠捕捉任何使用者的動作,並執行我們的動畫函數。

+如果希望不要有任何的使用者互動影響,請使用 setInterval(),因為它會確實地每隔一段時間就執行程式碼。如果你想製作遊戲 , 我們能夠使用 keyboard 或是 mouse event 來控制動畫,並使用 setTimeout()函數一起。藉由設定 EventListeners,我們能夠捕捉任何使用者的動作,並執行我們的動畫函數。 -
-

在下面的範例,我們將使用window.requestAnimationFrame()方法來控制動畫,window.requestAnimationFrame()方法為動畫提供更順暢更有效率的方式來執行,當系統準備好繪製畫面時,藉由呼叫動畫andmation frame()的callback函數 。callback通常每秒鐘執行60次,當執行background tab時,執行次數會更低,想知道更多關於動畫迴圈(animation loop)的資訊,尤其是遊戲的應用,請查看我們在 Game development zone 的主題 Anatomy of a video game

-
+> **備註:** 在下面的範例,我們將使用**window\.requestAnimationFrame()**方法來控制動畫,**window\.requestAnimationFrame()**方法為動畫提供更順暢更有效率的方式來執行,當系統準備好繪製畫面時,藉由呼叫動畫 andmation frame()的 callback 函數 。callback 通常每秒鐘執行 60 次,當執行 background tab 時,執行次數會更低,想知道更多關於動畫迴圈(animation loop)的資訊,尤其是遊戲的應用,請查看我們在 [Game development zone](/zh-TW/docs/Games) 的主題 [Anatomy of a video game](/zh-TW/docs/Games/Anatomy) 。 -

從使用者輸入操作控制動畫

+### 從使用者輸入操作控制動畫 -

我們也可以從使用者輸入操作控制動畫,就像是電玩遊戲一般;像是在鍵盤上設置事件處理器{{domxref("EventListener")}}捕捉使用者輸入並執行對應動畫。

+我們也可以從使用者輸入操作控制動畫,就像是電玩遊戲一般;像是在鍵盤上設置事件處理器{{domxref("EventListener")}}捕捉使用者輸入並執行對應動畫。 -

你可以利用我們的次要版主要版動畫框架

+你可以利用我們的[次要版](/zh-TW/docs/DOM/window.setInterval#A_little_framework)或[主要版動畫框架](/zh-TW/docs/JavaScript/Timers/Daemons)。 -
var myAnimation = new MiniDaemon(null, animateShape, 500, Infinity);
+```plain +var myAnimation = new MiniDaemon(null, animateShape, 500, Infinity); +``` -

+或 -
var myAnimation = new Daemon(null, animateShape, 500, Infinity);
+```plain +var myAnimation = new Daemon(null, animateShape, 500, Infinity); +``` -

在後面的範例我們主要將使用window.setInterval()方法控制動畫,然後於本頁底部是一些使用widnow.setTimeout()的範例連結。

+在後面的範例我們主要將使用 window\.setInterval()方法控制動畫,然後於本頁底部是一些使用 widnow\.setTimeout()的範例連結。 -

太陽系動畫

+#### 太陽系動畫 -

本例會產生一個小型太陽系運行動畫。

+本例會產生一個小型太陽系運行動畫。 -
var sun = new Image();
+```js
+var sun = new Image();
 var moon = new Image();
 var earth = new Image();
 function init(){
@@ -112,21 +109,24 @@ function draw() {
 
   ctx.drawImage(sun,0,0,300,300);
 }
-
+``` - +```js hidden +init(); +``` -

{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}

+{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}} -

時鐘動畫

+#### 時鐘動畫 -

本例會產生一個時鐘指向現在時間。

+本例會產生一個時鐘指向現在時間。 -
function init(){
+```js
+function init(){
   clock();
   setInterval(clock,1000);
 }
@@ -146,7 +146,7 @@ function clock(){
 
   // Hour marks
   ctx.save();
-  for (var i=0;i<12;i++){
+  for (var i=0;i<12;i++){
     ctx.beginPath();
     ctx.rotate(Math.PI/6);
     ctx.moveTo(100,0);
@@ -158,7 +158,7 @@ function clock(){
   // Minute marks
   ctx.save();
   ctx.lineWidth = 5;
-  for (i=0;i<60;i++){
+  for (i=0;i<60;i++){
     if (i%5!=0) {
       ctx.beginPath();
       ctx.moveTo(117,0);
@@ -172,7 +172,7 @@ function clock(){
   var sec = now.getSeconds();
   var min = now.getMinutes();
   var hr  = now.getHours();
-  hr = hr>=12 ? hr-12 : hr;
+  hr = hr>=12 ? hr-12 : hr;
 
   ctx.fillStyle = "black";
 
@@ -224,21 +224,25 @@ function clock(){
   ctx.stroke();
 
   ctx.restore();
-}
+} +``` - +```js hidden +init(); +``` -

{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}

+{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}} -

循環景色

+#### 循環景色 -

本例會產一個由左到右循環捲動美國優勝美地國家公園景色,你也可以自行替換其他比畫布還大的圖片。

+本例會產一個由左到右循環捲動[美國優勝美地國家公園](http://commons.wikimedia.org/wiki/File:Capitan_Meadows,_Yosemite_National_Park.jpg)景色,你也可以自行替換其他比畫布還大的圖片。 -
var img = new Image();
+```js
+var img = new Image();
 
 // User Variables - customize these to change the image being scrolled, its
 // direction, and the speed.
@@ -263,10 +267,10 @@ var ctx;
 img.onload = function() {
     imgW = img.width*scale;
     imgH = img.height*scale;
-    if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
-    if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
+    if (imgW > CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
+    if (imgW > CanvasXSize) { clearX = imgW; } // image larger than canvas
     else { clearX = CanvasXSize; }
-    if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
+    if (imgH > CanvasYSize) { clearY = imgH; } // image larger than canvas
     else { clearY = CanvasYSize; }
     //Get Canvas Element
     ctx = document.getElementById('canvas').getContext('2d');
@@ -277,71 +281,59 @@ img.onload = function() {
 function draw() {
     //Clear Canvas
     ctx.clearRect(0,0,clearX,clearY);
-    //If image is <= Canvas Size
-    if (imgW <= CanvasXSize) {
+    //If image is <= Canvas Size
+    if (imgW <= CanvasXSize) {
         //reset, start from beginning
-        if (x > (CanvasXSize)) { x = 0; }
+        if (x > (CanvasXSize)) { x = 0; }
         //draw aditional image
-        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
+        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
     }
-    //If image is > Canvas Size
+    //If image is > Canvas Size
     else {
         //reset, start from beginning
-        if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
+        if (x > (CanvasXSize)) { x = CanvasXSize-imgW; }
         //draw aditional image
-        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
+        if (x > (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
     }
     //draw image
     ctx.drawImage(img,x,y,imgW,imgH);
     //amount to move
     x += dx;
 }
-
- -

循環景色就是在下方的{{HTMLElement("canvas")}}中捲動,請注意其中的width和height和程式碼中的CanvasXZSize與CanvasYSize一樣。

- -
<canvas id="canvas" width="800" height="200"></canvas>
- -

Live sample

- -

{{EmbedLiveSample("A_looping_panorama", "830", "230")}}

- -

其他範例

- -
-
Gartic
-
-

多人繪圖遊戲

-
-
Canvascape
-
-

第一人稱3D冒險遊戲

-
-
A basic ray-caster
-
透過鍵盤控制動畫範例
-
canvas adventure
-
-

另一個透過鍵盤控制動畫範例

-
-
An interactive Blob
-
和Blob遊戲
-
Flying through a starfield
-
-

飛越星河

-
-
iGrapher
-
-

股票市場圖

-
-
- -

See also

- - - -

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Compositing", "Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas")}}

+``` + +循環景色就是在下方的{{HTMLElement("canvas")}}中捲動,請注意其中的 width 和 height 和程式碼中的 CanvasXZSize 與 CanvasYSize 一樣。 + +```html + +``` + +**Live sample** + +{{EmbedLiveSample("A_looping_panorama", "830", "230")}} + +## 其他範例 + +- [Gartic](http://www.gartic.net/) + - : 多人繪圖遊戲 +- [Canvascape](http://www.abrahamjoffe.com.au/ben/canvascape/) + - : 第一人稱 3D 冒險遊戲 +- [A basic ray-caster](/zh-TW/docs/Web/Guide/HTML/A_basic_ray-caster) + - : 透過鍵盤控制動畫範例 +- [canvas adventure](http://andrewwooldridge.com/canvas/canvasgame001/canvasgame002.html) + - : 另一個透過鍵盤控制動畫範例 +- [An interactive Blob](http://www.blobsallad.se/) + - : 和 Blob 遊戲 +- [Flying through a starfield](http://arapehlivanian.com/wp-content/uploads/2007/02/canvas.html) + - : 飛越星河 +- [iGrapher](http://igrapher.com/) + - : 股票市場圖 + +## See also + +- [JavaScript timers](/zh-TW/docs/JavaScript/Timers) +- [`setInterval` – A little framework](/zh-TW/docs/DOM/window.setInterval#A_little_framework) +- [JavaScript Daemons Management](/zh-TW/docs/JavaScript/Timers/Daemons) +- [HTMLCanvasElement](/zh-TW/docs/DOM/HTMLCanvasElement) + +{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Compositing", "Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas")}} diff --git a/files/zh-tw/web/api/canvas_api/tutorial/basic_usage/index.md b/files/zh-tw/web/api/canvas_api/tutorial/basic_usage/index.md index d2e4d6d9816aa7..23d56e33d84534 100644 --- a/files/zh-tw/web/api/canvas_api/tutorial/basic_usage/index.md +++ b/files/zh-tw/web/api/canvas_api/tutorial/basic_usage/index.md @@ -3,71 +3,69 @@ title: Canvas 基本用途 slug: Web/API/Canvas_API/Tutorial/Basic_usage translation_of: Web/API/Canvas_API/Tutorial/Basic_usage --- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}}
+{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial", "Web/API/Canvas_API/Tutorial/Drawing_shapes")}} -
-

Let's start this tutorial by looking at the {{HTMLElement("canvas")}} {{Glossary("HTML")}} element itself. At the end of this page, you will know how to set up a canvas 2D context and have drawn a first example in your browser.

-
+Let's start this tutorial by looking at the {{HTMLElement("canvas")}} {{Glossary("HTML")}} element itself. At the end of this page, you will know how to set up a canvas 2D context and have drawn a first example in your browser. -

<canvas> 元素

+## `` 元素 -
<canvas id="tutorial" width="150" height="150"></canvas>
-
+```html + +``` -

首先,先來看看 {{HTMLElement("canvas")}},它看起來有點像 {{HTMLElement("img")}} 元素,其中的差異點在於 <canvas> 沒有 srcalt 屬性,<canvas> 只有 {{htmlattrxref("width", "canvas")}} 與 {{htmlattrxref("height", "canvas")}} 這兩個屬性,這兩個屬性皆為非必須、能透過 DOM屬性設定;若是沒有設定 widthheight 屬性,畫布寬預設值為 300 pixels、高預設值為 150 pixels,我們可以用 CSS 強制設定元素尺寸,但當渲染時,影像會縮放以符合元素的尺寸。

+首先,先來看看 {{HTMLElement("canvas")}},它看起來有點像 {{HTMLElement("img")}} 元素,其中的差異點在於 `` 沒有 `src` 和 `alt` 屬性,`` 只有 {{htmlattrxref("width", "canvas")}} 與 {{htmlattrxref("height", "canvas")}} 這兩個屬性,這兩個屬性皆為非必須、能透過[ DOM](/zh-TW/docs/DOM)屬性設定;若是沒有設定 `width` 和 `height` 屬性,畫布寬預設值為 **300 pixels**、高預設值為 **150 pixels**,我們可以用 [CSS ](/zh-TW/docs/Web/CSS)強制設定元素尺寸,但當渲染時,影像會縮放以符合元素的尺寸。 -
-

Note:如果繪圖結果看起來有些扭曲,可以改試著用<canvas>自身的width和height屬性而不要用CSS來設定寬高。

-
+> **備註:** 如果繪圖結果看起來有些扭曲,可以改試著用\自身的 width 和 height 屬性而不要用 CSS 來設定寬高。 -

幾乎所有HTML元素都有id屬性,<canvas>也不例外,為了方便於程式碼腳本找到需要的<canvas>,每次都設定id是一項不錯的作法。

+幾乎所有 HTML 元素都有 id 屬性,\也不例外,為了方便於程式碼腳本找到需要的\,每次都設定 id 是一項不錯的作法。 -

如同一般的影像可以設定如邊界(margin)、邊框(border)、背景(background)等等,<canvas>元素一樣可以設定這些樣式,然而,這些樣式規則不會影響canvas實際繪圖,稍後我們會看到相關範例。當沒有套用樣式規定時,<canvas>會被初始成全透明。

+如同一般的影像可以設定如邊界(margin)、邊框(border)、背景(background)等等,\元素一樣可以設定這些樣式,然而,這些樣式規則不會影響 canvas 實際繪圖,稍後我們會看到相關範例。當沒有套用樣式規定時,\會被初始成全透明。 -

錯誤替代內容(Fallback content)

+### 錯誤替代內容(Fallback content) -

因為舊版瀏覽器(特別是IE9之前的IE)不支援{<canvas>}元素,我們應該為這些瀏覽器準備錯誤替代內容。

+因為舊版瀏覽器(特別是 IE9 之前的 IE)不支援{\}元素,我們應該為這些瀏覽器準備錯誤替代內容。 -

當不支援<canvas>的瀏覽器看到不認識的<canvas>時會忽略<canvas>,而此時在<canvas>下瀏覽器認識的替代內容則會被瀏覽器解析顯示,至於支援<canvas>的瀏覽器則是會正常解析<canvas>,忽略替代內容。

+當不支援\的瀏覽器看到不認識的\時會忽略\,而此時在\下瀏覽器認識的替代內容則會被瀏覽器解析顯示,至於支援\的瀏覽器則是會正常解析\,忽略替代內容。 -

例如,我們可以準備一段canvas內容的說明文字或canvas繪圖完成後的靜態圖片,如下所示:

+例如,我們可以準備一段 canvas 內容的說明文字或 canvas 繪圖完成後的靜態圖片,如下所示: -
<canvas id="stockGraph" width="150" height="150">
+```html
+
   current stock price: $3.15 +0.15
-</canvas>
+
 
-<canvas id="clock" width="150" height="150">
-  <img src="images/clock.png" width="150" height="150" alt=""/>
-</canvas>
-
+ + + +``` -

需要</canvas>標籤

+## 需要\
標籤 -

不像{{HTMLElement("img")}}元素,{{HTMLElement("canvas")}}元素必須要有</canvas>結束標籤。

+不像{{HTMLElement("img")}}元素,{{HTMLElement("canvas")}}元素必須要有\
結束標籤。 -
-

縱使早期Apple的Safari瀏覽器不需要結束標籤,但是基於規範,這是必須的,所以,為了相容性考量,應該要有結束標籤。Safari 2.0以前的版本會同時解析canvas以及替代內容,除非我們用CSS去遮蓋內容,不過幸運的是,現在已經沒有甚麼人在用這些舊版Safari。

-
+> **備註:** 縱使早期 Apple 的 Safari 瀏覽器不需要結束標籤,但是基於規範,這是必須的,所以,為了相容性考量,應該要有結束標籤。Safari 2.0 以前的版本會同時解析 canvas 以及替代內容,除非我們用 CSS 去遮蓋內容,不過幸運的是,現在已經沒有甚麼人在用這些舊版 Safari。 -

如果不需要錯誤替代內容,簡單的<canvas id="foo" ...></canvas>便可以完全相容於所有支援的瀏覽器。

+如果不需要錯誤替代內容,簡單的\\便可以完全相容於所有支援的瀏覽器。 -

渲染環境(rendering context)

+## 渲染環境(rendering context) -

{{HTMLElement("canvas")}}產生一個固定大小的繪圖畫布,這個畫布上有一或多個渲染環境(rendering context),我們可以用渲染環境來產生或操作顯示內容的渲染環境(rendering context)。不同環境(context)可能會提供不同型態的渲染方式,好比說WebGL使用OpenGL ES的3D環境(context),而這裡我們主要將討論2D渲染環境(rendering context)。

+{{HTMLElement("canvas")}}產生一個固定大小的繪圖畫布,這個畫布上有一或多個渲染環境(rendering context),我們可以用渲染環境來產生或操作顯示內容的渲染環境(rendering context)。不同環境(context)可能會提供不同型態的渲染方式,好比說[WebGL](/zh-TW/docs/Web/WebGL)使用[OpenGL ES](http://www.khronos.org/opengles/)的 3D 環境(context),而這裡我們主要將討論 2D 渲染環境(rendering context)。 -

一開始canvas為空白,程式碼腳本需要先存取渲染環境,在上面繪圖,然後才會顯現影像。{{HTMLElement("canvas")}} 素有一個方法(method)叫getContext(),透過此方法可以取得渲染環境及其繪圖函數(function);getContext()輸入參數只有渲染環境類型一項,像本教學所討論的2D繪圖,就是輸入”2d”。

+一開始 canvas 為空白,程式碼腳本需要先存取渲染環境,在上面繪圖,然後才會顯現影像。{{HTMLElement("canvas")}} 素有一個方法([method](/zh-TW/docs/Web/API/HTMLCanvasElement#Methods))叫 getContext(),透過此方法可以取得渲染環境及其繪圖函數(function);getContext()輸入參數只有渲染環境類型一項,像本教學所討論的 2D 繪圖,就是輸入”2d”。 -
var canvas = document.getElementById('tutorial');
+```js
+var canvas = document.getElementById('tutorial');
 var ctx = canvas.getContext('2d');
-
+``` -

上面第一行先呼叫{{domxref("document.getElementById()")}}來取得{{HTMLElement("canvas")}}元素,一旦取得元素後,便可以用其getContext()取得渲染環境。

+上面第一行先呼叫{{domxref("document.getElementById()")}}來取得{{HTMLElement("canvas")}}元素,一旦取得元素後,便可以用其 getContext()取得渲染環境。 -

支援性檢查

+## 支援性檢查 -

替代內容會被不支援{{HTMLElement("canvas")}}.的瀏覽器所顯示。程式碼腳本也可以利用檢查getContext()方法是否存在來檢查是否支援<canvas>,我們可以修改上面例子成如下:

+替代內容會被不支援{{HTMLElement("canvas")}}.的瀏覽器所顯示。程式碼腳本也可以利用檢查 getContext()方法是否存在來檢查是否支援\,我們可以修改上面例子成如下: -
var canvas = document.getElementById('tutorial');
+```js
+var canvas = document.getElementById('tutorial');
 
 if (canvas.getContext){
   var ctx = canvas.getContext('2d');
@@ -75,46 +73,48 @@ if (canvas.getContext){
 } else {
   // canvas-unsupported code here
 }
-
+``` -

一個範本

+## 一個範本 -

這裡是一個最簡單的範本,之後就是我們範例的起始點。

+這裡是一個最簡單的範本,之後就是我們範例的起始點。 -
<html>
-  <head>
-    <title>Canvas tutorial</title>
-    <script type="text/javascript">
+```html
+
+  
+    Canvas tutorial
+    
+    
+  
+  
+    
+  
+
+```
 
-

一旦網頁載入完成後,程式碼會呼叫draw()函數(這是利用document上的load事件完成),這類draw()函數也可以透過{{domxref("window.setTimeout()")}}, {{domxref("window.setInterval()")}}或其他事件處理函數來呼叫,只要呼叫的時間點是在網頁載入完後。

+一旦網頁載入完成後,程式碼會呼叫 draw()函數(這是利用 document 上的 load 事件完成),這類 draw()函數也可以透過{{domxref("window.setTimeout()")}}, {{domxref("window.setInterval()")}}或其他事件處理函數來呼叫,只要呼叫的時間點是在網頁載入完後。 -

這是我們的範本實際看起來的樣子:

+這是我們的範本實際看起來的樣子: -

{{EmbedLiveSample("A_skeleton_template", 160, 160)}}

+{{EmbedLiveSample("A_skeleton_template", 160, 160)}} -

一個簡單的範例

+## 一個簡單的範例 -

首先,讓我們先來畫兩個相交的正方形,其中一個正方形有alpha透明值,之後我們會說明這是如何達成的。

+首先,讓我們先來畫兩個相交的正方形,其中一個正方形有 alpha 透明值,之後我們會說明這是如何達成的。 -
<html>
- <head>
-  <script type="application/javascript">
+```html
+
+ 
+  
+ 
+ 
+   
+ 
+
+```
 
-

本範例的結果如下:

+本範例的結果如下: -

{{EmbedLiveSample("A_simple_example", 160, 160, "canvas_ex1.png")}}

+{{EmbedLiveSample("A_simple_example", 160, 160, "canvas_ex1.png")}} -

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial", "Web/Guide/HTML/Canvas_tutorial/Drawing_shapes")}}

+{{PreviousNext("Web/Guide/HTML/Canvas_tutorial", "Web/Guide/HTML/Canvas_tutorial/Drawing_shapes")}} diff --git a/files/zh-tw/web/api/canvas_api/tutorial/compositing/index.md b/files/zh-tw/web/api/canvas_api/tutorial/compositing/index.md index 3f8fe99a76cf20..c96172468894b8 100644 --- a/files/zh-tw/web/api/canvas_api/tutorial/compositing/index.md +++ b/files/zh-tw/web/api/canvas_api/tutorial/compositing/index.md @@ -3,45 +3,42 @@ title: 合成效果 slug: Web/API/Canvas_API/Tutorial/Compositing translation_of: Web/API/Canvas_API/Tutorial/Compositing --- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}
+{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}} -

在前述的範例中,新繪製的圖形總會覆蓋在之前的圖形上,對大多數情況來說這相當正常,不過它也限制了圖形繪製的順序。其實我們可以透過 globalCompositeOperation 屬性來改變這項預設行為。

+在前述的範例中,新繪製的圖形總會覆蓋在之前的圖形上,對大多數情況來說這相當正常,不過它也限制了圖形繪製的順序。其實我們可以透過 globalCompositeOperation 屬性來改變這項預設行為。 -

globalCompositeOperation

+## `globalCompositeOperation` -

利用 globalCompositeOperation,我們可以將新圖形繪製在舊圖形之下、遮蓋部分區域、清除畫布部分區域 (不同於 clearRect() 函式只能清除矩形區域)。

+利用 globalCompositeOperation,我們可以將新圖形繪製在舊圖形之下、遮蓋部分區域、清除畫布部分區域 (不同於 clearRect() 函式只能清除矩形區域)。 -
-
globalCompositeOperation = type
-
type 字串可指定為以下 12 種合成設定之一,每一種合成設定均將套用到新繪製的圖形上。
-
+- `globalCompositeOperation = type` + - : type 字串可指定為以下 12 種合成設定之一,每一種合成設定均將套用到新繪製的圖形上。 -

See compositing examples for the code of the following examples.

+See [compositing examples](/zh-TW/docs/Web/API/Canvas_API/Tutorial/Compositing/Example) for the code of the following examples. -

{{EmbedLiveSample("Compositing_example", 750, 6750, "" ,"Web/API/Canvas_API/Tutorial/Compositing/Example")}}

+{{EmbedLiveSample("Compositing_example", 750, 6750, "" ,"Web/API/Canvas_API/Tutorial/Compositing/Example")}} -

裁剪路徑

+## 裁剪路徑 -

裁剪路徑就像是一般畫布圖形繪圖,但就如同遮罩一樣,會蓋掉不需要的部分,如右圖所示。紅邊星星是我們的裁剪路徑,在路徑區域以外部分都不會出現在畫布上。

+![](canvas_clipping_path.png)裁剪路徑就像是一般畫布圖形繪圖,但就如同遮罩一樣,會蓋掉不需要的部分,如右圖所示。紅邊星星是我們的裁剪路徑,在路徑區域以外部分都不會出現在畫布上。 -

和上述 globalCompositeOperation 相比,可以發現 source-in 和 source-atop 這兩種構圖組合所達到的效果,和裁剪路徑類似,而其中最大差異在於裁剪路徑不需加入新圖形,消失的部分也不會出現在畫布上,所以,如果想要限定繪圖區域,裁剪路徑會是更理想的作法。

+和上述 globalCompositeOperation 相比,可以發現 source-in 和 source-atop 這兩種構圖組合所達到的效果,和裁剪路徑類似,而其中最大差異在於裁剪路徑不需加入新圖形,消失的部分也不會出現在畫布上,所以,如果想要限定繪圖區域,裁剪路徑會是更理想的作法。 -

繪畫圖形一章中,我們只提到 stroke() 和 fill() 函式,但其實還有第三個函式,那就是 clip() 函式。

+在[繪畫圖形](/zh-TW/docs/Web/Guide/HTML/Canvas_tutorial/Drawing_shapes#Drawing_paths)一章中,我們只提到 stroke() 和 fill() 函式,但其實還有第三個函式,那就是 clip() 函式。 -
-
clip()
-
轉換目前繪圖路徑為裁剪路徑。
-
+- `clip()` + - : 轉換目前繪圖路徑為裁剪路徑。 -

呼叫 clip() 除了會替代 closePath() 來關閉路徑之外,還會轉換目前填滿或勾勒繪圖路徑為裁剪路徑。

+呼叫 clip() 除了會替代 closePath() 來關閉路徑之外,還會轉換目前填滿或勾勒繪圖路徑為裁剪路徑。 -

{{HTMLElement("canvas")}} 畫布預設有一個等同於本身大小的裁剪路徑,等同於無裁剪效果。

+{{HTMLElement("canvas")}} 畫布預設有一個等同於本身大小的裁剪路徑,等同於無裁剪效果。 -

clip 範例

+### `clip` 範例 -

本範例使用了圓形的裁剪路徑,來限定畫星星時的繪圖區域。

+本範例使用了圓形的裁剪路徑,來限定畫星星時的繪圖區域。 -
function draw() {
+```js
+function draw() {
   var ctx = document.getElementById('canvas').getContext('2d');
   ctx.fillRect(0,0,150,150);
   ctx.translate(75,75);
@@ -60,7 +57,7 @@ translation_of: Web/API/Canvas_API/Tutorial/Compositing
   ctx.fillRect(-75,-75,150,150);
 
   // draw stars
-  for (var j=1;j<50;j++){
+  for (var j=1;j<50;j++){
     ctx.save();
     ctx.fillStyle = '#fff';
     ctx.translate(75-Math.floor(Math.random()*150),
@@ -75,7 +72,7 @@ function drawStar(ctx,r){
   ctx.save();
   ctx.beginPath()
   ctx.moveTo(r,0);
-  for (var i=0;i<9;i++){
+  for (var i=0;i<9;i++){
     ctx.rotate(Math.PI/5);
     if(i%2 == 0) {
       ctx.lineTo((r/0.525731)*0.200811,0);
@@ -87,18 +84,20 @@ function drawStar(ctx,r){
   ctx.fill();
   ctx.restore();
 }
-
+``` - +```js hidden +draw(); +``` -

一開始我們先畫了一個黑色矩形作為畫布背景,然後移動畫布原點到中央,接著我們繪製弧線並呼叫 clip(),藉以建立圓形的裁剪路徑。畫布儲存狀態亦可儲存裁剪路徑。若要保留原本的裁剪路徑,則可於繪製新的裁剪路徑之前,先行儲存畫布狀態。

+一開始我們先畫了一個黑色矩形作為畫布背景,然後移動畫布原點到中央,接著我們繪製弧線並呼叫 clip(),藉以建立圓形的裁剪路徑。畫布儲存狀態亦可儲存裁剪路徑。若要保留原本的裁剪路徑,則可於繪製新的裁剪路徑之前,先行儲存畫布狀態。 -

繪製裁剪路徑之後,所產生的所有圖形都只會出現在路徑以內,從後來繪製的漸層背景中可看出此特性。我們用自訂的 drawStar() 函數產生 50 個隨機散佈、大小不一的星星。這些星星同樣只會出現在裁剪路徑的範圍之內。

+繪製裁剪路徑之後,所產生的所有圖形都只會出現在路徑以內,從後來繪製的漸層背景中可看出此特性。我們用自訂的 drawStar() 函數產生 50 個隨機散佈、大小不一的星星。這些星星同樣只會出現在裁剪路徑的範圍之內。 -

{{EmbedLiveSample("A_clip_example", "180", "180", "canvas_clip.png")}}

+{{EmbedLiveSample("A_clip_example", "180", "180", "canvas_clip.png")}} -

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Transformations", "Web/Guide/HTML/Canvas_tutorial/Basic_animations")}}

+{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Transformations", "Web/Guide/HTML/Canvas_tutorial/Basic_animations")}} diff --git a/files/zh-tw/web/api/canvas_api/tutorial/drawing_shapes/index.md b/files/zh-tw/web/api/canvas_api/tutorial/drawing_shapes/index.md index a825e9c5e63808..f3234db6ff1b10 100644 --- a/files/zh-tw/web/api/canvas_api/tutorial/drawing_shapes/index.md +++ b/files/zh-tw/web/api/canvas_api/tutorial/drawing_shapes/index.md @@ -3,42 +3,39 @@ title: 繪製圖形 slug: Web/API/Canvas_API/Tutorial/Drawing_shapes translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes --- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
+{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}} -

網格(Grid)

+網格(Grid) -

在開始繪圖前,我們必須先了解畫布 (canvas) 網格,或著是說座標空間。在前一頁教學中的 HTML 範本有一個寬150 pixels (像素)、高150 pixels 的畫布。如右圖,你在畫布預設網格上繪圖,網格上 1 單位相當於畫布上 1 pixel,網格的原點 (座標 (0, 0) ) 坐落於左上角,所有元素定位皆相對於此左上角原點,所以藍色方塊的位置為從左往右推 x pixels、從上往下推 y pixels (亦即座標 (x, y) )。現在我們先專注在預設設定上,之後我們會看到如何轉換原點位置、旋轉網格以及縮放網格。

+![](canvas_default_grid.png)在開始繪圖前,我們必須先了解畫布 (canvas) 網格,或著是說座標空間。在前一頁教學中的 HTML 範本有一個寬 150 pixels (像素)、高 150 pixels 的畫布。如右圖,你在畫布預設網格上繪圖,網格上 1 單位相當於畫布上 1 pixel,網格的原點 (座標 (0, 0) ) 坐落於左上角,所有元素定位皆相對於此左上角原點,所以藍色方塊的位置為從左往右推 x pixels、從上往下推 y pixels (亦即座標 (x, y) )。現在我們先專注在預設設定上,之後我們會看到如何轉換原點位置、旋轉網格以及縮放網格。 -

畫矩形

+## 畫矩形 -

不同於SVG,{{HTMLElement("canvas")}}只支援一種原始圖形,矩形。所有的圖形都必須由一或多個繪圖路徑構成,而我們正好有一些繪圖路徑函數可以讓我們畫出複雜的圖形。

+不同於[SVG](/zh-TW/docs/SVG),{{HTMLElement("canvas")}}只支援一種原始圖形,矩形。所有的圖形都必須由一或多個繪圖路徑構成,而我們正好有一些繪圖路徑函數可以讓我們畫出複雜的圖形。 -
-

首先來看看矩形,共有三個矩形繪圖函數:

+首先來看看矩形,共有三個矩形繪圖函數: -
-
fillRect(x, y, width, height)
-
畫出一個填滿的矩形。
-
strokeRect(x, y, width, height)
-
畫出一個矩形的邊框
-
clearRect(x, y, width, height)
-
清除指定矩形區域內的內容,使其變為全透明。
-
+- `fillRect(x, y, width, height)` + - : 畫出一個填滿的矩形。 +- `strokeRect(x, y, width, height)` + - : 畫出一個矩形的邊框 +- `clearRect(x, y, width, height)` + - : 清除指定矩形區域內的內容,使其變為全透明。 -

這三個函數都接受一樣的參數: x, y代表從原點出發的座標位置,width, height代表矩形的寬高。

+這三個函數都接受一樣的參數: x, y 代表從原點出發的座標位置,width, height 代表矩形的寬高。 -

矩形範例

+### 矩形範例 - +```html hidden + + + + + +``` -
function draw() {
+```js
+function draw() {
   var canvas = document.getElementById('canvas');
   if (canvas.getContext) {
     var ctx = canvas.getContext('2d');
@@ -47,62 +44,58 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
     ctx.clearRect(45,45,60,60);
     ctx.strokeRect(50,50,50,50);
   }
-}
- -

本例結果如下:

+} +``` -

{{EmbedLiveSample("Rectangular_shape_example", 160, 160, "canvas_rect.png")}}

+本例結果如下: -

fillRect()函數畫出一個寬高都100 pixels的矩形,clearRect()函數清除中央60 x 60 pixels大的正方形區域,接著strokeRect()在被清除區域內畫上一個50 x 50 pixels的矩形邊框。

+{{EmbedLiveSample("Rectangular_shape_example", 160, 160, "canvas_rect.png")}} -

之後我們會看到另外兩種代替clearRect()的方法,還有如何改變圖形顏色與筆畫樣式。

+fillRect()函數畫出一個寬高都 100 pixels 的矩形,clearRect()函數清除中央 60 x 60 pixels 大的正方形區域,接著 strokeRect()在被清除區域內畫上一個 50 x 50 pixels 的矩形邊框。 -

不像之後會看到的路徑繪圖函數,這三個函數會立即在畫布上畫出矩形。

+之後我們會看到另外兩種代替 clearRect()的方法,還有如何改變圖形顏色與筆畫樣式。 -

路徑繪製

+不像之後會看到的路徑繪圖函數,這三個函數會立即在畫布上畫出矩形。 -

使用路徑 (path) 來畫圖形需要多一點步驟,一開始先產生路徑,然後用繪圖指令畫出路徑,然後再結束路徑,一旦路徑產生後便可以用畫筆或填滿方式來渲染生成,這裡是一些可用函數:

+## 路徑繪製 -
-
{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}
-
產生一個新路徑,產生後再使用繪圖指令來設定路徑。
-
{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}
-
閉合路徑好讓新的繪圖指令來設定路徑。
-
路徑 API
-
路徑 API,這些 API 便是繪圖指令
-
+使用路徑 (path) 來畫圖形需要多一點步驟,一開始先產生路徑,然後用繪圖指令畫出路徑,然後再結束路徑,一旦路徑產生後便可以用畫筆或填滿方式來渲染生成,這裡是一些可用函數: -
-
{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}
-
畫出圖形的邊框。
-
{{domxref("CanvasRenderingContext2D.fill", "fill()")}}
-
填滿路徑內容區域來產生圖形。
-
+- {{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}} + - : 產生一個新路徑,產生後再使用繪圖指令來設定路徑。 +- {{domxref("CanvasRenderingContext2D.closePath", "closePath()")}} + - : 閉合路徑好讓新的繪圖指令來設定路徑。 +- [路徑 API](/zh-TW/docs/Web/API/CanvasRenderingContext2D#Paths) + - : 路徑 API,這些 API 便是繪圖指令 +- {{domxref("CanvasRenderingContext2D.stroke", "stroke()")}} + - : 畫出圖形的邊框。 +- {{domxref("CanvasRenderingContext2D.fill", "fill()")}} + - : 填滿路徑內容區域來產生圖形。 -

第一步呼叫 beginPath() 產生一個路徑,表面下,路徑會被存在一個次路徑 (sub-path) 清單中,例如直線、曲線等,這些次路徑集合起來就形成一塊圖形。每一次呼叫這個方法,次路徑清單就會被重設,然後我們便能夠畫另一個新圖形。

+第一步呼叫 beginPath() 產生一個路徑,表面下,路徑會被存在一個次路徑 (sub-path) 清單中,例如直線、曲線等,這些次路徑集合起來就形成一塊圖形。每一次呼叫這個方法,次路徑清單就會被重設,然後我們便能夠畫另一個新圖形。 -
Note: 當目前路徑為空(例如接著呼叫beginPath()完後)或是在一個新畫布上,不論為何,第一個路徑繪圖指令總是moveTo();因為每當重設路徑後,你幾乎都會需要設定繪圖起始點。
+> **備註:** 當目前路徑為空(例如接著呼叫 beginPath()完後)或是在一個新畫布上,不論為何,第一個路徑繪圖指令總是 moveTo();因為每當重設路徑後,你幾乎都會需要設定繪圖起始點。 -

第二步是呼叫各式方法來實際設定繪圖路徑,稍後我們將會介紹這部分。

+第二步是呼叫各式方法來實際設定繪圖路徑,稍後我們將會介紹這部分。 -

第三步,也是非必要的一步,就是呼叫closePath()。這個方法會在現在所在點到起始點間畫一條直線以閉合圖形,如果圖形已經閉合或是只含一個點,這個方法不會有任何效果。

+第三步,也是非必要的一步,就是呼叫 closePath()。這個方法會在現在所在點到起始點間畫一條直線以閉合圖形,如果圖形已經閉合或是只含一個點,這個方法不會有任何效果。 -
Note: 當呼叫fill(),任何開放的圖形都會自動閉合,所以不需要再呼叫closePath(),但是stroke()並非如此。
+> **備註:** 當呼叫 fill(),任何開放的圖形都會自動閉合,所以不需要再呼叫 closePath(),但是 stroke()並非如此。 -

畫一個三角形

+### 畫一個三角形 -

這是一個畫出三角形的程式碼範例。

+這是一個畫出三角形的程式碼範例。 - +```html hidden + + + + + +``` -
function draw() {
+```js
+function draw() {
   var canvas = document.getElementById('canvas');
   if (canvas.getContext){
     var ctx = canvas.getContext('2d');
@@ -114,35 +107,33 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
     ctx.fill();
   }
 }
-
+``` -

結果如下:

+結果如下: -

{{EmbedLiveSample("Drawing_a_triangle", 110, 110, "triangle.png")}}

+{{EmbedLiveSample("Drawing_a_triangle", 110, 110, "triangle.png")}} -

移動畫筆

+### 移動畫筆 -

moveTo()是一個很有用的函數,moveTo()不會畫任何圖形,但卻是上述路徑清單的一部分,這大概有點像是把筆從紙上一點提起來,然後放到另一個點。

+moveTo()是一個很有用的函數,moveTo()不會畫任何圖形,但卻是上述路徑清單的一部分,這大概有點像是把筆從紙上一點提起來,然後放到另一個點。 -
-
{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}
-
移動畫筆到指定的(x, y)座標點
-
+- {{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}} + - : 移動畫筆到指定的(x, y)座標點 -

當初始化畫布或是呼叫beginPath(),通常會想要使用moveTo()來指定起始點,我們可以用moveTo()畫不連結的路徑,看一下笑臉圖範例,圖中紅線即為使用到moveTo()的位置。

+當初始化畫布或是呼叫 beginPath(),通常會想要使用 moveTo()來指定起始點,我們可以用 moveTo()畫不連結的路徑,看一下笑臉圖範例,圖中紅線即為使用到 moveTo()的位置。 -

你可以拿下面的程式碼,放進先前的draw()函數,自己試試看效果。

+你可以拿下面的程式碼,放進先前的 draw()函數,自己試試看效果。 - +```html hidden + + + + + +``` -
function draw() {
+```js
+function draw() {
   var canvas = document.getElementById('canvas');
   if (canvas.getContext){
     var ctx = canvas.getContext('2d');
@@ -158,41 +149,37 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
     ctx.stroke();
   }
 }
-
+``` -

結果如下:

+結果如下: -

{{EmbedLiveSample("Moving_the_pen", 160, 160, "canvas_smiley.png")}}

+{{EmbedLiveSample("Moving_the_pen", 160, 160, "canvas_smiley.png")}} -

移除moveTo()便可以看到線條連結起來。

+移除 moveTo()便可以看到線條連結起來。 -
-

Note: 有關arc(),請參照下方弧形

-
+> **備註:** 有關 arc(),請參照下方[弧形](#弧形)。 -

線條

+### 線條 -

用lineTo()方法畫直線。

+用 lineTo()方法畫直線。 -
-
{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}
-
從目前繪圖點畫一條直線到指定的(x, y)座標點。
-
+- {{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}} + - : 從目前繪圖點畫一條直線到指定的(x, y)座標點。 -

本方法接受x, y參數作為線條結束點的座標位置,至於起始點則視前一個繪圖路徑,由前一個繪圖路徑的結束點作為起始點,當然,起始點也可以用moveTo()方法來變更。

+本方法接受 x, y 參數作為線條結束點的座標位置,至於起始點則視前一個繪圖路徑,由前一個繪圖路徑的結束點作為起始點,當然,起始點也可以用 moveTo()方法來變更。 -

下面畫兩個三角形,一個填滿,一個空心。

+下面畫兩個三角形,一個填滿,一個空心。 - +```html hidden + + + + + +``` -
function draw() {
+```js
+function draw() {
   var canvas = document.getElementById('canvas');
   if (canvas.getContext){
     var ctx = canvas.getContext('2d');
@@ -213,53 +200,49 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
     ctx.stroke();
   }
 }
-
+``` -

從呼叫beginPath()起始一個新圖形路徑,然後用moveTo()移到我們想要的起始點,然後再畫兩條線形成三角形的兩邊。

+從呼叫 beginPath()起始一個新圖形路徑,然後用 moveTo()移到我們想要的起始點,然後再畫兩條線形成三角形的兩邊。 -

{{EmbedLiveSample("Lines", 160, 160, "canvas_lineTo.png")}}

+{{EmbedLiveSample("Lines", 160, 160, "canvas_lineTo.png")}} -

我們可以看到填滿(fill)三角形和勾勒(stroke)三角形的區別;當填滿時,圖形會自動閉合,不過勾勒則不會,所以如果沒有呼叫closePaht()的話,只會畫出兩條線而非三角形。

+我們可以看到填滿(fill)三角形和勾勒(stroke)三角形的區別;當填滿時,圖形會自動閉合,不過勾勒則不會,所以如果沒有呼叫 closePaht()的話,只會畫出兩條線而非三角形。 -

弧形

+### 弧形 -

用arc()方法來畫弧形或圓形。雖然也可以用arcTo(),但這個方法比較不可靠,所以這裡我們不討論arcTo()。

+用 arc()方法來畫弧形或圓形。雖然也可以用 arcTo(),但這個方法比較不可靠,所以這裡我們不討論 arcTo()。 -
-
{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}}
-
畫一個弧形
-
+- {{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}} + - : 畫一個弧形 -

本方法接受五個參數: x, y代表圓心座標點,radius代表半徑,startAngle, endAngle分別代表沿著弧形曲線上的起始點與結束點的弧度,弧度測量是相對於x軸,anticlockwise為true代表逆時針作圖、false代表順時針作圖。

+本方法接受五個參數: x, y 代表圓心座標點,radius 代表半徑,startAngle, endAngle 分別代表沿著弧形曲線上的起始點與結束點的弧度,弧度測量是相對於 x 軸,anticlockwise 為 true 代表逆時針作圖、false 代表順時針作圖。 -
-

Note: arc()方法用的是弧度(radians)而非角度(degrees),如果要在弧度與角度間換算,可以利用以下javascript程式碼: radians = (Math.PI/180) * degrees.

-
+> **備註:** arc()方法用的是弧度(radians)而非角度(degrees),如果要在弧度與角度間換算,可以利用以下 javascript 程式碼: radians = (Math.PI/180) \* degrees. -

以下例子比較複雜,它會畫出12個不同的弧形。

+以下例子比較複雜,它會畫出 12 個不同的弧形。 -

兩個for迴圈走一遍弧形圖列的列跟行,每一個弧形由呼叫beginPath()開始新的繪圖路徑,為了清楚,我們在程式範例中用變數儲存參數,你不一定要這麼做。

+兩個 for 迴圈走一遍弧形圖列的列跟行,每一個弧形由呼叫 beginPath()開始新的繪圖路徑,為了清楚,我們在程式範例中用變數儲存參數,你不一定要這麼做。 -

x, y座標點的部分應該相當淺顯,radius和startAngle是定值,endAngle從180度(半圓)開始,然後每一行增加90度,最後一行便會形成一個完整的圓。

+x, y 座標點的部分應該相當淺顯,radius 和 startAngle 是定值,endAngle 從 180 度(半圓)開始,然後每一行增加 90 度,最後一行便會形成一個完整的圓。 -

第1, 3列的anticlockwise 為false,所以會順時針作圖,2, 4列的anticlockwise 為true,所以會逆時針作圖。最後的if決定下半部是用填滿圖形,上半部是勾勒圖形。

+第 1, 3 列的 anticlockwise 為 false,所以會順時針作圖,2, 4 列的 anticlockwise 為 true,所以會逆時針作圖。最後的 if 決定下半部是用填滿圖形,上半部是勾勒圖形。 - +```html hidden + + + + + +``` -
function draw() {
+```js
+function draw() {
   var canvas = document.getElementById('canvas');
   if (canvas.getContext){
     var ctx = canvas.getContext('2d');
 
-    for(var i=0;i<4;i++){
-      for(var j=0;j<3;j++){
+    for(var i=0;i<4;i++){
+      for(var j=0;j<3;j++){
         ctx.beginPath();
         var x              = 25+j*50;               // x coordinate
         var y              = 25+i*50;               // y coordinate
@@ -270,7 +253,7 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
 
         ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
 
-        if (i>1){
+        if (i>1){
           ctx.fill();
         } else {
           ctx.stroke();
@@ -279,40 +262,39 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
     }
   }
 }
-
+``` + {{EmbedLiveSample("Arcs", 160, 210, "canvas_arc.png")}} -

貝茲曲線(Bezier curve)與二次曲線(quadratic curve)

+### 貝茲曲線(Bezier curve)與二次曲線(quadratic curve) -

二次與三次貝茲曲線(Bézier curves)是另一種可用來構成複雜有機圖形的路徑。

+二次與三次[貝茲曲線(Bézier curves)](http://en.wikipedia.org/wiki/B%C3%A9zier_curve)是另一種可用來構成複雜有機圖形的路徑。 -
-
{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}
-
從目前起始點畫一條二次貝茲曲線到x, y指定的終點,控制點由cp1x, cp1y指定。
-
{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}
-
從目前起始點畫一條三次貝茲曲線到x, y指定的終點,控制點由(cp1x, cp1y)和(cp2x, cp2y)指定。
-
+- {{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}} + - : 從目前起始點畫一條二次貝茲曲線到 x, y 指定的終點,控制點由 cp1x, cp1y 指定。 +- {{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}} + - : 從目前起始點畫一條三次貝茲曲線到 x, y 指定的終點,控制點由(cp1x, cp1y)和(cp2x, cp2y)指定。 -

二次和三次的差別可以從右圖看出;貝茲曲線的起始和終點以藍點標示,其中二次貝茲曲線只有一個控制點(如紅點標示)而三次貝茲曲線有兩個控制點。

+![](canvas_curves.png)二次和三次的差別可以從右圖看出;貝茲曲線的起始和終點以藍點標示,其中二次貝茲曲線只有一個控制點(如紅點標示)而三次貝茲曲線有兩個控制點。 -

二次和三次貝茲曲線都用x, y參數定義終點座標,然後用cp1x, xp1y定義第一個控制點座標、cp2x, xp2y定義第二個控制點座標。

+二次和三次貝茲曲線都用 x, y 參數定義終點座標,然後用 cp1x, xp1y 定義第一個控制點座標、cp2x, xp2y 定義第二個控制點座標。 -

用二次和三次貝茲曲線作圖相當具有挑戰性,因為不像使用 Adobe illustrator 的向量繪圖軟體,我們在繪圖時無法即時看到繪圖狀況,所以畫複雜的圖形十分困難。下面的範例我們畫了一些圖形,如果你有時間與耐心,可以畫出更複雜的圖形。

+用二次和三次貝茲曲線作圖相當具有挑戰性,因為不像使用 Adobe illustrator 的向量繪圖軟體,我們在繪圖時無法即時看到繪圖狀況,所以畫複雜的圖形十分困難。下面的範例我們畫了一些圖形,如果你有時間與耐心,可以畫出更複雜的圖形。 -

二次貝茲曲線

+#### 二次貝茲曲線 -

本例用了數個二次貝茲曲線畫了一個會話框。

+本例用了數個二次貝茲曲線畫了一個會話框。 - +```html hidden + + + + + +``` -
function draw() {
+```js
+function draw() {
   var canvas = document.getElementById('canvas');
   if (canvas.getContext) {
     var ctx = canvas.getContext('2d');
@@ -329,24 +311,24 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
     ctx.stroke();
   }
 }
-
+``` -

{{EmbedLiveSample("Quadratic_Bezier_curves", 160, 160, "canvas_quadratic.png")}}

+{{EmbedLiveSample("Quadratic_Bezier_curves", 160, 160, "canvas_quadratic.png")}} -

三次貝茲曲線

+#### 三次貝茲曲線 -

這個範例畫了一個愛心。

+這個範例畫了一個愛心。 - +```html hidden + + + + + +``` -
function draw() {
+```js
+function draw() {
   var canvas = document.getElementById('canvas');
   if (canvas.getContext){
     var ctx = canvas.getContext('2d');
@@ -363,35 +345,33 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
     ctx.fill();
   }
 }
-
+``` -

{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "canvas_bezier.png")}}

+{{EmbedLiveSample("Cubic_Bezier_curves", 160, 160, "canvas_bezier.png")}} -

矩形

+### 矩形 -

除了在{畫矩形}段落中提到的三個方法,還有rect()方法能夠在畫布上畫矩形;rect()方法會在目前路徑下加入一個矩形繪圖路徑。

+除了在{畫矩形}段落中提到的三個方法,還有 rect()方法能夠在畫布上畫矩形;rect()方法會在目前路徑下加入一個矩形繪圖路徑。 -
-
{{domxref("CanvasRenderingContext2D.bezierCurveTo", "rect(x, y, width, height)")}}
-
畫一個左上角位於(x, y)、寬width、高height的矩形。
-
+- {{domxref("CanvasRenderingContext2D.bezierCurveTo", "rect(x, y, width, height)")}} + - : 畫一個左上角位於(x, y)、寬 width、高 height 的矩形。 -

呼叫這個方法,moveTo()方法會以(0, 0)參數被自動呼叫,所以目前的下筆點跟者自動被設為預設座標。

+呼叫這個方法,moveTo()方法會以(0, 0)參數被自動呼叫,所以目前的下筆點跟者自動被設為預設座標。 -

多樣組合

+### 多樣組合 -

截至目前為止,我們都只用一種路徑函數在各個範例裡作圖,不過,其實繪圖時並沒有任何使用數量或種類上的路徑函數限制,所以最後我們來試著組合各樣路徑繪圖函數來畫一些十分有名的遊戲角色。

+截至目前為止,我們都只用一種路徑函數在各個範例裡作圖,不過,其實繪圖時並沒有任何使用數量或種類上的路徑函數限制,所以最後我們來試著組合各樣路徑繪圖函數來畫一些十分有名的遊戲角色。 - +```html hidden + + + + + +``` -
function draw() {
+```js
+function draw() {
   var canvas = document.getElementById('canvas');
   if (canvas.getContext){
     var ctx = canvas.getContext('2d');
@@ -408,15 +388,15 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes
     ctx.lineTo(31,37);
     ctx.fill();
 
-    for(var i=0;i<8;i++){
+    for(var i=0;i<8;i++){
       ctx.fillRect(51+i*16,35,4,4);
     }
 
-    for(i=0;i<6;i++){
+    for(i=0;i<6;i++){
       ctx.fillRect(115,51+i*16,4,4);
     }
 
-    for(i=0;i<8;i++){
+    for(i=0;i<8;i++){
       ctx.fillRect(51+i*16,99,4,4);
     }
 
@@ -474,46 +454,46 @@ function roundedRect(ctx,x,y,width,height,radius){
   ctx.quadraticCurveTo(x,y,x,y+radius);
   ctx.stroke();
 }
-
+``` -
-

結果如下:

+結果如下: -

{{EmbedLiveSample("Making_combinations", 160, 160)}}

+{{EmbedLiveSample("Making_combinations", 160, 160)}} -

畫出這樣的圖其實沒有想像中的困難,所以我們就不再描述細節了,其中比較需要注意的是,我們在繪圖環境上用了fillStyle屬性以及一個自定義的效用函數(roundedRect()),利用效用函數來執行時常重複的繪圖工作可以幫忙減少程式碼數量與複雜度。

+畫出這樣的圖其實沒有想像中的困難,所以我們就不再描述細節了,其中比較需要注意的是,我們在繪圖環境上用了 fillStyle 屬性以及一個自定義的效用函數(roundedRect()),利用效用函數來執行時常重複的繪圖工作可以幫忙減少程式碼數量與複雜度。 -

稍後我們會更進一步介紹fillStyle屬性,這個範例我們所做是的透過fillStyle屬性來改變路徑填滿色為白色,然後再改回預設黑色,來變換填滿顏色,。

+稍後我們會更進一步介紹 fillStyle 屬性,這個範例我們所做是的透過 fillStyle 屬性來改變路徑填滿色為白色,然後再改回預設黑色,來變換填滿顏色,。 -

{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Basic_usage", "Web/Guide/HTML/Canvas_tutorial/Using_images")}}

-
-
+{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Basic_usage", "Web/Guide/HTML/Canvas_tutorial/Using_images")}} -

Path2D objects

+## Path2D objects -

如同前面的範例,canvas 上常常會畫上一連串的繪圖路徑,為了簡化程式碼還有改善效能,我們可以利用 {{domxref("Path2D")}} 物件 (目前在較先進的瀏覽器上已經有提供了)。Path2D 讓我們可以快取和記錄繪圖指令,方便快速重複地繪圖,底下我就來看看如何使用 Path2D :

+如同前面的範例,canvas 上常常會畫上一連串的繪圖路徑,為了簡化程式碼還有改善效能,我們可以利用 {{domxref("Path2D")}} 物件 (目前在較先進的瀏覽器上已經有提供了)。Path2D 讓我們可以快取和記錄繪圖指令,方便快速重複地繪圖,底下我就來看看如何使用 Path2D : -

{{domxref("Path2D.Path2D", "Path2D()")}}

+{{domxref("Path2D.Path2D", "Path2D()")}} -

Path2D 的建構子,可接受的參數有無參數、另一個 Path2D 物件、 字元表式的 SVG path:

+Path2D 的建構子,可接受的參數有無參數、另一個 Path2D 物件、 字元表式的 [SVG path](/zh-TW/docs/Web/SVG/Tutorial/Paths): -
new Path2D();     // 不傳入參數會回傳一個空的 Path2D 物件
+```js
+new Path2D();     // 不傳入參數會回傳一個空的 Path2D 物件
 new Path2D(path); // 複製傳入的 Path2D 物件,然後以之建立 Path2D 物件
-new Path2D(d);    // 以傳入的 SVG 路徑建立 Path2D 物件
+new Path2D(d); // 以傳入的 SVG 路徑建立 Path2D 物件 +``` -

所有已知的 路徑 API,如 rect, arc 等等,都可以在 Path2D 上找到。

+所有已知的 [路徑 API](/zh-TW/docs/Web/API/CanvasRenderingContext2D#Paths),如 rect, arc 等等,都可以在 Path2D 上找到。 -

Path2D 物件還可以加入其他 Path2D 物件,這讓我們可以很方便的組合多個物件使用。

+Path2D 物件還可以加入其他 Path2D 物件,這讓我們可以很方便的組合多個物件使用。 -

{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}}

+{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}} -

addPath 增加一個 Path2D 物件,其中的非必要參數是變形矩陣。

+addPath 增加一個 Path2D 物件,其中的非必要參數是變形矩陣。 -

Path2D example

+### Path2D example -

這個例子用 Path2D 物件將矩形和圓形的繪圖路徑存起來,以供之後使用。而配合新的 Path2D API,有一些繪圖方法更接受傳入 Path2D 作為繪圖路徑使用,例如下方本例所用到的 stroke 和 fill。

+這個例子用 Path2D 物件將矩形和圓形的繪圖路徑存起來,以供之後使用。而配合新的 Path2D API,有一些繪圖方法更接受傳入 Path2D 作為繪圖路徑使用,例如下方本例所用到的 stroke 和 fill。 -
function draw() {
+```js
+function draw() {
   var canvas = document.getElementById('canvas');
   if (canvas.getContext){
     var ctx = canvas.getContext('2d');
@@ -528,18 +508,19 @@ new Path2D(d);    // 以傳入的 SVG 路徑建立 Path2D 物件
ctx.stroke(rectangle); ctx.fill(circle); } -}
- -

{{EmbedLiveSample("Path2D_example", 130, 110, "path2d.png")}}

+} +``` -

使用向量路徑 (SVG paths)

+{{EmbedLiveSample("Path2D_example", 130, 110, "path2d.png")}} -

另一個強而有力的特色是在 SVG 和 Canvas 中我們都可以使用 SVG path。

+### 使用向量路徑 (SVG paths) -

下面的路徑會移到座標點 (10, 10) (M10, 10),然後水平右移 80 點 (h 80),垂至下移 80 點 (v 80) 水平左移 80 點 (h -80) 最後回到起始點 (z),請到Path2D 建構子頁面看繪圖範例結果。

+另一個強而有力的特色是在 SVG 和 Canvas 中我們都可以使用 SVG path。 -
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
+下面的路徑會移到座標點 (10, 10) (M10, 10),然後水平右移 80 點 (h 80),垂至下移 80 點 (v 80) 水平左移 80 點 (h -80) 最後回到起始點 (z),請到[`Path2D` 建構子頁面](/zh-TW/docs/Web/API/Path2D.Path2D#Using_SVG_paths)看繪圖範例結果。 -
{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}
+```js +var p = new Path2D("M10 10 h 80 v 80 h -80 Z"); +``` -

+{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}} diff --git a/files/zh-tw/web/api/canvas_api/tutorial/drawing_text/index.md b/files/zh-tw/web/api/canvas_api/tutorial/drawing_text/index.md index 7650a9e3edfd17..7adf7ac20c149b 100644 --- a/files/zh-tw/web/api/canvas_api/tutorial/drawing_text/index.md +++ b/files/zh-tw/web/api/canvas_api/tutorial/drawing_text/index.md @@ -3,15 +3,15 @@ title: 使用canvas繪製文字 slug: Web/API/Canvas_API/Tutorial/Drawing_text translation_of: Web/API/Canvas_API/Tutorial/Drawing_text --- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}}
+{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Applying_styles_and_colors", "Web/API/Canvas_API/Tutorial/Using_images")}} -

canvas元素支援在標準 HTML 5 特色以及少許實驗性的Mozilla方法和功能上繪製文字。

+[`canvas`](/en/HTML/Canvas)元素支援在[標準 HTML 5 特色](http://www.whatwg.org/specs/web-apps/current-work/#text-0)以及少許實驗性的 Mozilla 方法和功能上繪製文字。 -

文字可以包括任何Unicode字元,即使用那些超出“基本多文種平面”的字元也可以。

+文字可以包括任何 Unicode 字元,即使用那些超出“基本多文種平面”的字元也可以。 -

{{ fx_minversion_note("3.5", '在Firefox 3.5或之後的版本,當繪圖時,任何對於 shadow effects(陰影效果)的處理可以使用在文字上。') }}

+{{ fx_minversion_note("3.5", '在Firefox 3.5或之後的版本,當繪圖時,任何對於 shadow effects(陰影效果)的處理可以使用在文字上。') }} -

方法概述

+## 方法概述 @@ -39,295 +39,309 @@ translation_of: Web/API/Canvas_API/Tutorial/Drawing_text
-

屬性

+## 屬性 - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + +
屬性型別描述
fontDOMString -

當前的文字樣式被用在繪製文字。該字串使用和 CSS font(樣式表字型)相同的語法。要改變繪製文字的樣式,只要簡單的改變它的屬性值即可,就像下面展示的,預設的字型是10px(像素) sans-serif(字型名稱)

- -

例如:

- -
-ctx.font = "20pt Arial";
-
mozTextStyle {{ deprecated_inline() }}DOMString -

由上面的Html5字型 屬性取代

-
textAlignDOMString -

當前繪製文字所使用的文字對齊方式。 可使用的值:

- -
-
left
-
文字靠左對齊。
-
right
-
文字靠右對齊。
-
center
-
文字置中對齊。
-
start
-
文字依照行首對齊 (書寫習慣由左到右的地區就靠左對齊,書寫習慣由右到左的就靠右對齊。).
-
end
-
文字依照行尾對齊(書寫習慣由左到右的地區就靠右對齊,書寫習責由右到左的地區就靠左對齊。)
-
- -

預設的值是 start.

-
textBaselineDOMString -

當前繪製文字的基線位置 可使用的值:

- -
-
top
-
基線在字元區塊的頂部(圖中top of the squre位置)。
-
hanging(懸掛)
-
文字基線在拼音文字頂部的位置(圖中hanging baseline) 當前仍未支援;會顯示 alphabetic代替。
-
middle
-
文字基線在字元區塊的中間。
-
alphabetic(拼音文字)
-
這是一般拼音文字底線的位置。
-
ideographic(表意文字)
-
文字在表意文字(如漢字)底部的位置 當前仍未支援;會顯示alphabetic代替。
-
bottom
-
基線在拼音文字下伸部的位置 這與ideographic的基線位置不同,因為表意文字沒有下伸部
-
- -

預設使用 alphabetic.

-
屬性型別描述
font + DOMString + +

+ 當前的文字樣式被用在繪製文字。該字串使用和 + CSS font(樣式表字型)相同的語法。要改變繪製文字的樣式,只要簡單的改變它的屬性值即可,就像下面展示的,預設的字型是10px(像素) + sans-serif(字型名稱) +

+

例如:

+
ctx.font = "20pt Arial";
+
mozTextStyle {{ deprecated_inline() }} + DOMString + +

由上面的Html5字型 屬性取代

+
textAlign + DOMString + +

當前繪製文字所使用的文字對齊方式。 可使用的值:

+
+
left
+
文字靠左對齊。
+
right
+
文字靠右對齊。
+
center
+
文字置中對齊。
+
start
+
+ 文字依照行首對齊 + (書寫習慣由左到右的地區就靠左對齊,書寫習慣由右到左的就靠右對齊。). +
+
end
+
+ 文字依照行尾對齊(書寫習慣由左到右的地區就靠右對齊,書寫習責由右到左的地區就靠左對齊。) +
+
+

預設的值是 start.

+
textBaseline + DOMString + +

當前繪製文字的基線位置 可使用的值:

+
+
top
+
基線在字元區塊的頂部(圖中top of the squre位置)。
+
hanging(懸掛)
+
+ 文字基線在拼音文字頂部的位置(圖中hanging baseline) + 當前仍未支援;會顯示 alphabetic代替。 +
+
middle
+
文字基線在字元區塊的中間。
+
alphabetic(拼音文字)
+
這是一般拼音文字底線的位置。
+
ideographic(表意文字)
+
+ 文字在表意文字(如漢字)底部的位置 + 當前仍未支援;會顯示alphabetic代替。 +
+
bottom
+
+ 基線在拼音文字下伸部的位置 + 這與ideographic的基線位置不同,因為表意文字沒有下伸部 +
+
+

預設使用 alphabetic.

+
-

下圖展示了textBaseline屬性所支援的各種基線,感謝 WHATWG.

+下圖展示了 textBaseline 屬性所支援的各種基線,感謝 [WHATWG](http://www.whatwg.org/). -

top of em squre(字元區塊頂部)大致在字型中所有字母的最頂部位置,hanging basline(懸掛基線)則是在一些特殊(較小的,像是“आ”)字母頂部,middle則是在top of em squre(字元區塊頂部和bottom of em squre(字元區塊底部)的中間,alphabetic(拼音文字)的基線位置則是在一般拼音字母如Á,ÿ,f,Ω的底線位置。ideographic(表意文字)的基線在字元的底部位置,bottom of em squre(字元區塊底部)則大致是字型中所有字母的最底部位置。而top and bottom of the bounding box(上下的區域範圍線)則比這些基線都來得更遠,基於字母的高度可能超過字元區塊頂部和底部的範圍。

+![top of em squre(字元區塊頂部)大致在字型中所有字母的最頂部位置,hanging basline(懸掛基線)則是在一些特殊(較小的,像是“आ”)字母頂部,middle則是在top of em squre(字元區塊頂部和bottom of em squre(字元區塊底部)的中間,alphabetic(拼音文字)的基線位置則是在一般拼音字母如Á,ÿ,f,Ω的底線位置。ideographic(表意文字)的基線在字元的底部位置,bottom of em squre(字元區塊底部)則大致是字型中所有字母的最底部位置。而top and bottom of the bounding box(上下的區域範圍線)則比這些基線都來得更遠,基於字母的高度可能超過字元區塊頂部和底部的範圍。](http://www.whatwg.org/specs/web-apps/current-work/images/baselines.png) -

方法

+## 方法 -

fillText()

+### fillText() -

繪製文字使用font屬性指定的文字樣式,對齊則使用textAlign屬性,而指定基線則使用textBaseline. 填充文字當前使用fillStyle,而strokeStyle則被忽略

+繪製文字使用`font`屬性指定的文字樣式,對齊則使用`textAlign`屬性,而指定基線則使用`textBaseline`. 填充文字當前使用`fillStyle`,而`strokeStyle`則被忽略 -
這個方法在 Gecko 1.9.1 (Firefox 3.5)時引進,且是HTML 5標準的一部分.
+> **備註:** 這個方法在 Gecko 1.9.1 (Firefox 3.5)時引進,且是 HTML 5 標準的一部分. -
void fillText(
+```plain
+void fillText(
    in DOMString textToDraw,
    in float x,
    in float y,
    [optional] in float maxWidth
 );
-
+``` -
參數
+##### 參數 -
-
textToDraw
-
將文字繪製到文本中。
-
x
-
繪製位置的x座標。
-
y
-
繪製位置的y座標。
-
maxWidth
-
最大寬度,可選用的;繪製字串最大長度 如果指定此參數,當字串被計算出比這個值更寬,它會自動選擇水平方向更窄的字型(如果有可用的字型或是有可讀的字型可以嵌入當前字型之中),或者縮小字型。
-
+- `textToDraw` + - : 將文字繪製到文本中。 +- `x` + - : 繪製位置的 x 座標。 +- `y` + - : 繪製位置的 y 座標。 +- `maxWidth` + - : 最大寬度,可選用的;繪製字串最大長度 如果指定此參數,當字串被計算出比這個值更寬,它會自動選擇水平方向更窄的字型(如果有可用的字型或是有可讀的字型可以嵌入當前字型之中),或者縮小字型。 -
範例
+##### 範例 -
ctx.fillText("Sample String", 10, 50);
-
+```js +ctx.fillText("Sample String", 10, 50); +``` -

measureText()

+### measureText() -

測量文字。返回一個物件包含了寬度,像素值,所指定的文字會以當前的文字樣式繪製。

+測量文字。返回一個物件包含了寬度,像素值,所指定的文字會以當前的文字樣式繪製。 -
這個方法在 Gecko 1.9.1 (Firefox 3.5) 引進,且是HTML 5標準的一部分。
+> **備註:** 這個方法在 Gecko 1.9.1 (Firefox 3.5) 引進,且是 HTML 5 標準的一部分。 -
nsIDOMTextMetrics measureText(
+```plain
+nsIDOMTextMetrics measureText(
   in DOMString textToMeasure
 );
-
+``` -

參數

+#### 參數 -
-
textToMeasure
-
該字串的像素值。
-
+- `textToMeasure` + - : 該字串的像素值。 -

返回值

+#### 返回值 -

nsIDOMTextMetrics物件的width屬性在繪製時會將數字設定給CSS 的像素值寬度。

+[`nsIDOMTextMetrics`](/nsIDOMTextMetrics)物件的`width`屬性在繪製時會將數字設定給 CSS 的像素值寬度。 -

mozDrawText()

+### mozDrawText() -

{{ deprecated_header() }}

+{{ deprecated_header() }} -

繪製文字使用由mozTextStyle屬性的文字樣式。文本當前的填充顏色被用來當做文字顏色。

+繪製文字使用由`mozTextStyle`屬性的文字樣式。文本當前的填充顏色被用來當做文字顏色。 -
注意:這個方法已經不被建議使用,請使用正式的HTML 5方法 fillText() and strokeText().
+> **備註:** 這個方法已經不被建議使用,請使用正式的 HTML 5 方法 `fillText()` and `strokeText()`. -
void mozDrawText(
+```plain
+void mozDrawText(
    in DOMString textToDraw
 );
-
+``` -

參數

+#### 參數 -
-
textToDraw
-
將文字繪製到文本。
-
+- `textToDraw` + - : 將文字繪製到文本。 -

範例

+#### 範例 -
ctx.translate(10, 50);
+```js
+ctx.translate(10, 50);
 ctx.fillStyle = "Red";
 ctx.mozDrawText("Sample String");
-
+``` -

這個範例將文字“Sample String”繪製到畫布(canvas)上。

+這個範例將文字“Sample String”繪製到畫布(canvas)上。 -

mozMeasureText()

+### mozMeasureText() -

{{ deprecated_header() }}

+{{ deprecated_header() }} -

返回寬度,像素值,指定文字

+返回寬度,像素值,指定文字 -
注意:這個方法已經已宣告棄用,請使用正式的HTML 5方法measureText().
+> **備註:** 這個方法已經已宣告棄用,請使用正式的 HTML 5 方法`measureText()`. -
float mozMeasureText(
+```plain
+float mozMeasureText(
   in DOMString textToMeasure
 );
-
+``` -

參數

+#### 參數 -
-
textToMeasure
-
字串的寬度像素值
-
+- `textToMeasure` + - : 字串的寬度像素值 -

返回值

+#### 返回值 -

文字的寬度像素值

+文字的寬度像素值 -

範例

+#### 範例 -
var text = "Sample String";
+```js
+var text = "Sample String";
 var width = ctx.canvas.width;
 var len = ctx.mozMeasureText(text);
 ctx.translate((width - len)/2, 0);
 ctx.mozDrawText(text);
-
+``` -

這個範例測量了字串的寬度,接著使用這個資訊將它畫在畫布(canvas)的水平中心。

+這個範例測量了字串的寬度,接著使用這個資訊將它畫在畫布(canvas)的水平中心。 -

mozPathText()

+### mozPathText() -

給文字路徑加上外框線,如果你想要的話,它允許你替文字加上框線代替填充它。

+給文字路徑加上外框線,如果你想要的話,它允許你替文字加上框線代替填充它。 -
void mozPathText(
+```plain
+void mozPathText(
   in DOMString textToPath
 );
-
+``` -

參數

+#### 參數 -
-
textToPath
-
為當前的文字路徑加上框線
-
+- `textToPath` + - : 為當前的文字路徑加上框線 -

Example

+#### Example -
ctx.fillStyle = "green";
+```js
+ctx.fillStyle = "green";
 ctx.strokeStyle = "black";
 ctx.mozPathText("Sample String");
 ctx.fill()
 ctx.stroke()
-
+``` -

這個範例繪出文字“Sample String”,填充顏色是綠色,外框顏色是黑色。

+這個範例繪出文字“Sample String”,填充顏色是綠色,外框顏色是黑色。 -

mozTextAlongPath()

+### mozTextAlongPath() -

Adds (or draws) the specified text along the current path.

+Adds (or draws) the specified text along the current path. -
void mozTextAlongPath(
+```plain
+void mozTextAlongPath(
   in DOMString textToDraw,
   in boolean stroke
 );
-
+``` -

參數

+#### 參數 -
-
textToDraw
-
沿著指定路徑繪出文字
-
stroke
-
如果參數是 true(真值),文字會沿著指定路徑繪製。如果 false(假值),這個文字則會加入到路徑之中,再沿著當前路徑繪製。
-
+- `textToDraw` + - : 沿著指定路徑繪出文字 +- `stroke` + - : 如果參數是 `true`(真值),文字會沿著指定路徑繪製。如果 `false`(假值),這個文字則會加入到路徑之中,再沿著當前路徑繪製。 -

備註

+#### 備註 -

字體不會沿著路徑曲線縮放或變形,反而在彎曲路徑下,字體每次計算都會當成是直線在處理。這可以用來建立一些特殊的效果。

+字體不會沿著路徑曲線縮放或變形,反而在彎曲路徑下,字體每次計算都會當成是直線在處理。這可以用來建立一些特殊的效果。 -

strokeText()

+### strokeText() -

繪製文字使用font屬性指定的文字樣式,對齊則使用textAlign屬性,而指定基線則使用textBaseline. 當前使用strokeStyle來建立文字外框。

+繪製文字使用`font`屬性指定的文字樣式,對齊則使用`textAlign`屬性,而指定基線則使用`textBaseline`. 當前使用`strokeStyle`來建立文字外框。 -
注意: 這個方法在 Gecko 1.9.1 (Firefox 3.5)時引進,且是HTML 5標準的一部分。
+> **備註:** 這個方法在 Gecko 1.9.1 (Firefox 3.5)時引進,且是 HTML 5 標準的一部分。 -
void strokeText(
+```plain
+void strokeText(
    in DOMString textToDraw,
    in float x,
    in float y,
    [optional] in float maxWidth
 );
-
- -
參數
- -
-
textToDraw
-
將文字繪製到文本中。
-
x
-
繪製位置的x座標。
-
y
-
繪製位置的y座標
-
maxWidth
-
最大寬度,可選用的;繪製字串最大長度 如果指定此參數,當字串被計算出比這個值更寬,它會自動選擇水平方向更窄的字型(如果有可用的字型或是有可讀的字型可以嵌入當前字型之中),或者縮小字型。
-
+``` -
範例
+##### 參數 -
ctx.strokeText("Sample String", 10, 50);
-
+- `textToDraw` + - : 將文字繪製到文本中。 +- `x` + - : 繪製位置的 x 座標。 +- `y` + - : 繪製位置的 y 座標 +- `maxWidth` + - : 最大寬度,可選用的;繪製字串最大長度 如果指定此參數,當字串被計算出比這個值更寬,它會自動選擇水平方向更窄的字型(如果有可用的字型或是有可讀的字型可以嵌入當前字型之中),或者縮小字型。 -

備註

+##### 範例 -
    -
  • 請見 WHATWG specification 關於HTML 5 canvas text的說明。
  • -
  • 你不需要特別的文本來使用這些功能;2D的文本就可以執行得很好。
  • -
  • 所有的繪圖都使用即時變化來完成。
  • -
+```js +ctx.strokeText("Sample String", 10, 50); +``` +## 備註 +- 請見 [WHATWG specification](http://www.whatwg.org/specs/web-apps/current-work/#text) 關於 HTML 5 canvas text 的說明。 +- 你不需要特別的文本來使用這些功能;2D 的文本就可以執行得很好。 +- 所有的繪圖都使用即時變化來完成。 diff --git a/files/zh-tw/web/api/canvas_api/tutorial/pixel_manipulation_with_canvas/index.md b/files/zh-tw/web/api/canvas_api/tutorial/pixel_manipulation_with_canvas/index.md index dbb407088c7b8b..a0a94723c12f61 100644 --- a/files/zh-tw/web/api/canvas_api/tutorial/pixel_manipulation_with_canvas/index.md +++ b/files/zh-tw/web/api/canvas_api/tutorial/pixel_manipulation_with_canvas/index.md @@ -3,81 +3,84 @@ title: Pixel manipulation with canvas slug: Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas translation_of: Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas --- -
{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}}
+{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}} -
-

直到目前為止,我們還沒真正了解 pixels 在 canvas上的運用。使用ImageData物件,可直接對pixel 裡的陣列資料讀(read)寫(write)。在接下的內容中,也可了解到如何使影像平滑化(反鋸齒)及如何將影像保存在canvas之中。

-
+直到目前為止,我們還沒真正了解 pixels 在 canvas 上的運用。使用`ImageData`物件,可直接對 pixel 裡的陣列資料**讀(read)**和**寫(write)**。在接下的內容中,也可了解到如何使影像平滑化(反鋸齒)及如何將影像保存在 canvas 之中。 -

ImageData物件

+## `ImageData`物件 -

{{domxref("ImageData")}} 物件代表canvas區中最基礎的像素。

+{{domxref("ImageData")}} 物件代表 canvas 區中最基礎的像素。 -

包含它只可讀的屬性:

+包含它只可讀的屬性: -
-
width
-
影像中的寬度,以pixels為單位
-
height
-
影像中的高度,以pixels為單位
-
data
-
{{jsxref("Uint8ClampedArray")}} 代表一維陣列包含RGBA 格式。整數值介於0到255之間(包含255)。
-
+- `width` + - : 影像中的寬度,以 pixels 為單位 +- `height` + - : 影像中的高度,以 pixels 為單位 +- `data` + - : {{jsxref("Uint8ClampedArray")}} 代表一維陣列包含 RGBA 格式。整數值介於 0 到 255 之間(包含 255)。 -

data 屬性返回一個{{jsxref("Uint8ClampedArray")}},它可被當作為pixel的初始資料。每個pixel用4個1byte值做代表分別為透明值(也就是RGBA格式)。每個顏色組成皆是介於整數值介於0到255之間。而每個組成在一個陣列中被分配為一個連續的索引。從左上角 pixel 的紅色組成中的陣列由索引 0 為始。Pixels 執行順序為從左到右,再由上到下,直到整個陣列。

+`data` 屬性返回一個{{jsxref("Uint8ClampedArray")}},它可被當作為 pixel 的初始資料。每個 pixel 用 4 個 1byte 值做代表分別為**紅**,**綠**,**藍**,**透明值**(也就是**RGBA**格式)。每個顏色組成皆是介於整數值介於 0 到 255 之間。而每個組成在一個陣列中被分配為一個連續的索引。從左上角 pixel 的紅色組成中的陣列由**索引 0** 為始。Pixels 執行順序為從左到右,再由上到下,直到整個陣列。 -

{{jsxref("Uint8ClampedArray")}} 包含height × width× 4 bytes的資料,同索引值從0到 (height×width×4)-1

+{{jsxref("Uint8ClampedArray")}} 包含`height` × `width`× 4 bytes 的資料,同索引值從 0 到 (`height`×`width`×4)-1 -

例如,讀取影像的藍色組成的值。從pixel 的第200欄、第50行,你可以照著下面的步驟:

+例如,讀取影像的藍色組成的值。從 pixel 的第 200 欄、第 50 行,你可以照著下面的步驟: -
blueComponent = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2];
+```js +blueComponent = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2]; +``` -

使用Uint8ClampedArray.length屬性來讀取影像pixel的陣列大小

+使用`Uint8ClampedArray.length`屬性來讀取影像 pixel 的陣列大小 -
var numBytes = imageData.data.length;
-
+```js +var numBytes = imageData.data.length; +``` -

創造一個 ImageData物件

+## 創造一個 `ImageData`物件 -

可以使用{{domxref("CanvasRenderingContext2D.createImageData", "createImageData()")}}方法創造一個全新空白的ImageData 物件。

+可以使用{{domxref("CanvasRenderingContext2D.createImageData", "createImageData()")}}方法創造一個全新空白的`ImageData` 物件。 -

這裡有兩種createImageData()的方法:

+這裡有兩種`createImageData()`的方法: -
var myImageData = ctx.createImageData(width, height);
+```js +var myImageData = ctx.createImageData(width, height); +``` -

這個方法是有規定大小尺寸.所有pixels預設是透明的黑色。

+這個方法是有規定大小尺寸.所有 pixels 預設是透明的黑色。 -

下面的方法一樣是由anotherImageData參考尺寸大小,由ImageData 物件創造一個與新的一樣的大小。這些新的物件的pixel皆預設為透明的黑色。

+下面的方法一樣是由`anotherImageData`參考尺寸大小,由`ImageData` 物件創造一個與新的一樣的大小。這些新的物件的 pixel 皆預設為透明的黑色。 -
var myImageData = ctx.createImageData(anotherImageData);
+```js +var myImageData = ctx.createImageData(anotherImageData); +``` -

得到pixel資料的內容

+## 得到 pixel 資料的內容 -

可以使用getImageData()這個方法,去取得canvas內容中ImageData 物件的資料含pixel 數據(data)

+可以使用`getImageData()`這個方法,去取得 canvas 內容中`ImageData` 物件的資料含 pixel 數據(data) -
var myImageData = ctx.getImageData(left, top, width, height);
+```js +var myImageData = ctx.getImageData(left, top, width, height); +``` -

這個方法會返回ImageData物件,它代表著在這canvas區域之中pixel 的數據(data) 。從各角落的點代表著 (left,top), (left+width, top), (left, top+height), and (left+width, top+height)。這些作標被設定為canvas 的空間座標單位。

+這個方法會返回`ImageData`物件,它代表著在這 canvas 區域之中 pixel 的數據(data) 。從各角落的點代表著 (`left`,`top`), (`left+width`, `top`), (`left`, `top+height`), and (`left+width`, `top+height`)。這些作標被設定為 canvas 的空間座標單位。 -
-

注釋: 在ImageData 物件中,任何超出canvas外的pixels皆會返回透明的黑色的形式。

-
+> **備註:** 在`ImageData` 物件中,任何超出 canvas 外的 pixels 皆會返回透明的黑色的形式。 -

這個方法也被展示在使用canvas操作影像之中。

+這個方法也被展示在[使用 canvas 操作影像](/zh-TW/docs/Web/API/Canvas_API/Manipulating_video_using_canvas)之中。 -

調色盤

+### 調色盤 -

這個範例使用getImageData() 方法去顯示在鼠標下的顏色。

+這個範例使用[getImageData() ](/zh-TW/docs/Web/API/CanvasRenderingContext2D/getImageData)方法去顯示在鼠標下的顏色。 -

首先,需要一個正確的滑鼠點layerX​​​​​​​layerY。在從getImageData() 提供pixel 陣列中(array)該點的pixel 數據(data) 。最後,使用陣列數據(array data)在<div>中設置背景色和文字去顯示該色。

+首先,需要一個正確的滑鼠點`layerX`*​​​​​​​*和 `layerY`。在從[getImageData()](/zh-TW/docs/Web/API/CanvasRenderingContext2D/getImageData) 提供 pixel 陣列中(array)該點的 pixel 數據(data) 。最後,使用陣列數據(array data)在`
`中設置背景色和文字去顯示該色。 - +```html hidden + +
+``` -
var img = new Image();
+```js
+var img = new Image();
 img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg';
 var canvas = document.getElementById('canvas');
 var ctx = canvas.getContext('2d');
@@ -97,38 +100,40 @@ function pick(event) {
   color.textContent = rgba;
 }
 canvas.addEventListener('mousemove', pick);
-
+``` -

{{ EmbedLiveSample('A_color_picker', 610, 240) }}

+{{ EmbedLiveSample('A_color_picker', 610, 240) }} -

在內容中寫入pixel 資料

+## 在內容中寫入 pixel 資料 -

可以使用putImageData() 方法將自訂pixel 數據(data) 放入內容中:

+可以使用[putImageData() ](/zh-TW/docs/Web/API/CanvasRenderingContext2D/putImageData)方法將自訂 pixel 數據(data) 放入內容中: -
ctx.putImageData(myImageData, dx, dy);
-
+```js +ctx.putImageData(myImageData, dx, dy); +``` -

dxdy參數表示填入你所希望的座標,將它代入內容中左上角的pixel 數據(data)。

+`dx` 和 `dy`參數表示填入你所希望的座標,將它代入內容中左上角的 pixel 數據(data)。 -

For example, to paint the entire image represented by myImageData to the top left corner of the context, you can simply do the following:

+For example, to paint the entire image represented by `myImageData` to the top left corner of the context, you can simply do the following: -
ctx.putImageData(myImageData, 0, 0);
-
+```js +ctx.putImageData(myImageData, 0, 0); +``` -

灰階和負片效果

+### 灰階和負片效果 -

In this example we iterate over all pixels to change their values, then we put the modified pixel array back to the canvas using putImageData(). The invert function simply subtracts each color from the max value 255. The grayscale function simply uses the average of red, green and blue. You can also use a weighted average, given by the formula x = 0.299r + 0.587g + 0.114b, for example. See Grayscale on Wikipedia for more information.

+In this example we iterate over all pixels to change their values, then we put the modified pixel array back to the canvas using [putImageData()](/zh-TW/docs/Web/API/CanvasRenderingContext2D/putImageData). The invert function simply subtracts each color from the max value 255. The grayscale function simply uses the average of red, green and blue. You can also use a weighted average, given by the formula `x = 0.299r + 0.587g + 0.114b`, for example. See [Grayscale](http://en.wikipedia.org/wiki/Grayscale) on Wikipedia for more information. -