diff --git a/files/zh-cn/learn/javascript/client-side_web_apis/drawing_graphics/index.md b/files/zh-cn/learn/javascript/client-side_web_apis/drawing_graphics/index.md index 0ad9d8cdf4a4c5..beec017be57228 100644 --- a/files/zh-cn/learn/javascript/client-side_web_apis/drawing_graphics/index.md +++ b/files/zh-cn/learn/javascript/client-side_web_apis/drawing_graphics/index.md @@ -1,25 +1,27 @@ --- title: 绘图 slug: Learn/JavaScript/Client-side_web_APIs/Drawing_graphics +l10n: + sourceCommit: 4dec42ed700040565e8af0e14ff104054ebc20f5 --- {{LearnSidebar}}{{PreviousMenuNext("Learn/JavaScript/Client-side_web_APIs/Third_party_APIs", "Learn/JavaScript/Client-side_web_APIs/Video_and_audio_APIs", "Learn/JavaScript/Client-side_web_APIs")}} -浏览器包含一些非常强大的图形编程工具,从可缩放矢量图形(Scalable Vector Graphics,简称 [SVG](/zh-CN/docs/Web/SVG))语言到用于在 HTML {{htmlelement("canvas")}} 元素上绘制图形的 API(参阅 [Canvas API](/zh-CN/docs/Web/API/Canvas_API) 和 [WebGL](/zh-CN/docs/Web/API/WebGL_API))。本文对 {{htmlelement("canvas")}} 进行介绍,并提供更多的学习资源。 +浏览器包含一些非常强大的图形编程工具,从可缩放矢量图形(Scalable Vector Graphics,简称 [SVG](/zh-CN/docs/Web/SVG))语言到用于在 HTML {{htmlelement("canvas")}} 元素上绘制图形的 API(参见 [Canvas API](/zh-CN/docs/Web/API/Canvas_API) 和 [WebGL](/zh-CN/docs/Web/API/WebGL_API))。本文将介绍 canvas,并提供更多的学习资源。 - +
@@ -32,30 +34,27 @@ slug: Learn/JavaScript/Client-side_web_APIs/Drawing_graphics
前提: JavaScript 基础(见 JavaScript 第一步创建 JavaScript 代码块JavaScript 对象入门),JavaScript 对象)、Web API 基础知识客户端 API 基础知识。
-## 网络图形 +## Web 中的图形 -我们来讨论 HTML 的 [多媒体和嵌入式](/zh-CN/docs/Learn/HTML/Multimedia_and_embedding) 模块,早先的网页只有单调的文字,后来才引入了图像,起初是通过 {{htmlelement("img")}} 元素的方式,后来出现了类似于 {{cssxref("background-image")}} 的 CSS 属性和 [SVG](/zh-CN/docs/Web/SVG) 图像等方式。 +我们来讨论 HTML 的[多媒体和嵌入](/zh-CN/docs/Learn/HTML/Multimedia_and_embedding)模块,早先的网页只有单调的文字,后来才引入了图像,起初是通过 {{htmlelement("img")}} 元素的方式,后来出现了类似于 {{cssxref("background-image")}} 的 CSS 属性和 [SVG](/zh-CN/docs/Web/SVG) 图像等方式。 -然而,这还不够好。当你能够使用 [CSS](/zh-CN/docs/Learn/CSS) 和 [JavaScript](/zh-CN/docs/Learn/JavaScript) 让 SVG 矢量图动起来时,位图却依然没有相应的支持。同时 SVG 动画的可用工具也少得可怜。有效地生成动画、游戏画面、3D 场景和其他的需求依然没有满足,而这些在诸如 C++ 或者 Java 等底层语言中却司空见惯。 +然而,这还不够好。当你能够使用 [CSS](/zh-CN/docs/Learn/CSS) 和 [JavaScript](/zh-CN/docs/Learn/JavaScript) 让 SVG 矢量图(因为其由标记表示)动起来时,位图却依然没有相应的支持。同时 SVG 动画的可用工具也少得可怜。Web 仍然无法高效地创建动画、游戏、3D 场景,而其他需求则通常由底层语言(如 C++ 或 Java)来应对。 -当浏览器开始支持 HTML 画布元素 {{htmlelement("canvas")}} 和相关的 [Canvas API](/zh-CN/docs/Web/API/Canvas_API)(由苹果公司在 2004 年前后发明,后来其他的浏览器开始跟进)时,形势开始改善。下面你会看到,canvas 提供了许多有用的工具,特别是当捆绑了由网络平台提供的一些其他的 API 时。它们用来生成 2D 动画、游戏画面和数据分析图,以及其他类型的 app。 +当浏览器于 2004 年开始支持 HTML 画布元素 {{htmlelement("canvas")}} 和相关的 [Canvas API](/zh-CN/docs/Web/API/Canvas_API) 时,形势开始改善。下面你会看到,canvas 提供了许多用于创建 2D 动画、游戏、数据可视化和其他应用类型的有用工具,特别是当捆绑了由 Web 平台提供的一些其他的 API 时。 -下面的例子显示的是一个基于 canvas 的简单的 2D 弹跳球动画,前面我们在 [JavaScript 对象入门](/zh-CN/docs/Learn/JavaScript/Objects/Object_building_practice) 的章节中见到过。 +下面的例子显示的是一个基于 canvas 的简单的 2D 弹跳球动画,前面我们在[介绍 JavaScript 对象](/zh-CN/docs/Learn/JavaScript/Objects/Object_building_practice)模块中见到过。 {{EmbedGHLiveSample("learning-area/javascript/oojs/bouncing-balls/index-finished.html", '100%', 500)}} -大约在 2006 - 2007 年,Mozilla 开始测试 3D 画布。后来演化为 [WebGL](/zh-CN/docs/Web/API/WebGL_API),它获得了各大浏览器厂商的认可,于是大约在 2009 - 2010 年间得到了标准化。WebGL 可以让你在 web 浏览器中生成真正的 3D 图形。下面的例子显示了一个简单的旋转的 WebGL 立方体。 +大约在 2006—2007 年,Mozilla 开始测试 3D 画布实现。后来演化为 [WebGL](/zh-CN/docs/Web/API/WebGL_API),它获得了各大浏览器厂商的认可,于是大约在 2009—2010 年间得到了标准化。WebGL 可以让你在 Web 浏览器中生成真正的 3D 图形。下面的例子显示了一个简单的旋转的 WebGL 立方体: {{EmbedGHLiveSample("learning-area/javascript/apis/drawing-graphics/threejs-cube/index.html", '100%', 500)}} -由于原生的 WebGL 代码非常复杂,本文主要针对 2D 画布。然而,你也可以通过 [WebGL 介绍页面](/zh-CN/docs/Web/API/WebGL_API) 找到 WebGL 原生代码的教程,来学习如何更容易地使用 WebGL 库来创建一个 3D 场景。 - -> [!NOTE] -> 画布的基本功能有良好的跨浏览器支持。但存在例外:IE 8 及以下不支持 2D 画布,IE 11 及以下不支持 WebGL。 +由于原生的 WebGL 代码非常复杂,本文主要针对 2D 画布。然而,你也可以通过[初识 WebGL](/zh-CN/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL) 找到 WebGL 原生代码的教程,来学习如何更容易地使用 WebGL 库来创建一个 3D 场景。 ## 主动学习:开始使用 \ -要在网页中创建 2D 或者 3D 场景,必须在 HTML 文件中插入一个 {{htmlelement("canvas")}} 元素,以界定网页中的绘图区域。这很简单,如下所示: +要在网页中创建 2D _或_ 3D 场景,必须从 HTML {{htmlelement("canvas")}} 元素开始。该元素用于定义页面中的绘图区域。这与在页面中包含元素一样简单: ```html @@ -63,82 +62,75 @@ slug: Learn/JavaScript/Client-side_web_APIs/Drawing_graphics 网页中会生成一块 320 × 240 像素的画布。 -在 canvas 标签内,你可以放置一些反馈信息,如果用户的浏览器不支持画布功能,这些内容就会显示出来。 +在 `` 标签内,你可以放置一些回退内容。这会向不支持画布的浏览器或屏幕阅读器的用户描述画布内容。 ```html -

卧槽你的浏览器竟然不支持 canvas!

+

为无法查看画布的用户提供的画布描述。

``` -当然这条信息实在是没什么用!在实际情况中最好提供与画布内容相关的反馈信息。比如,如果无法渲染实时更新的股价曲线图,就应提供一幅静态的、最近的股价曲线图,并用 alt 显示出价格信息。 +回退内容应为画布内容提供有用的替代内容。比如,如果你要渲染不断更新的股价曲线图,回退内容可以是最新股价图的静态图像,并带有替代文本(以文本的形式说明价格)或指向各个股票页面的链接列表。 + +> [!NOTE] +> 屏幕阅读器无法获取画布内容。需要在画布元素的 [`aria-label`](/zh-CN/docs/Web/Accessibility/ARIA/Attributes/aria-label) 属性填写描述性文本,或者在起始和结束的 `` 标签里嵌入回退内容。画布内容不是 DOM 的一部分,但嵌入的回退内容是 DOM 的一部分。 ### 创建画布并确定尺寸 让我们开始吧:创建画布,准备尝试绘制图形。 -1. 首先下载 [0_canvas_start.html](https://github.com/mdn/learning-area/blob/main/javascript/apis/drawing-graphics/getting-started/0_canvas_start.html) 文件,用文本编辑器打开。 -2. 在 {{htmlelement("body")}} 标签下面填加以下代码。 +1. 首先在本地拷贝一份 [0_canvas_start](https://github.com/mdn/learning-area/tree/main/javascript/apis/drawing-graphics/getting-started/0_canvas_start) 文件夹。包含三个文件: + - “index.html” + - “script.js” + - “style.css” +2. 打开“index.html”,在 {{htmlelement("body")}} 的起始标签下面填加以下代码。 ```html -

添加恰当的反馈信息。

+

添加恰当的回退信息。

``` - 我们为 `` 元素添加了一个 `class`,使得在网页中选择多个画布时会容易些。这里我们移除了 `width` 和 `height` 属性 (你可以随时添上。但是我们会在下方用 JavaScript 把它们添加回来)。不明确指定宽高时,画布默认尺寸为 300 × 150 像素。 + 我们为 `` 元素添加了一个 `class`,使得在网页中选择多个画布时会容易些。这里我们移除了 `width` 和 `height` 属性(你可以随时添上,但是我们会在下方用 JavaScript 把它们添加回来)。不明确指定宽高时,画布默认尺寸为 300 × 150 像素。 -3. 现在,请在 {{htmlelement("script")}} 元素内添加以下 JavaScript 代码: +3. 现在,打开“script.js”并添加以下 JavaScript 代码: ```js - var canvas = document.querySelector(".myCanvas"); - var width = (canvas.width = window.innerWidth); - var height = (canvas.height = window.innerHeight); + const canvas = document.querySelector(".myCanvas"); + const width = (canvas.width = window.innerWidth); + const height = (canvas.height = window.innerHeight); ``` - 这里我们用 `canvas` 变量来存储画布的引用。第二行中我们将 {{domxref("Window.innerWidth")}}(可视区域宽度)赋值给一个新变量 `width` 和画布的 `canvas.width` 变量,(第三行同理)。然后我们就得到了一个充满窗口的画布。 - - 你还可以看到我们使用了多个等号为多个变量进行连续赋值,这在 JavaScript 中是允许的,很适合为多个变量同时赋一个相同的值。后文中你会发现,使用 `width` 和 `height` 变量可以更快捷地访问画布的长宽(比如在画布正中央绘制一条垂直线)。 - -4. 如果现在保存文件,浏览器中什么也不会显示,这并没有问题,但是滚动条还是可见的,这就是问题了。原因是我们的“全窗尺寸画布”包含 {{htmlelement("body")}} 元素的外边距({{cssxref("margin")}}),使得文档比窗口略宽。为使滚动条消失,需要删除 {{htmlelement("body")}} 元素的 {{cssxref("margin")}} 并将 {{cssxref("overflow")}} 设置为 `hidden`。在文档的 {{htmlelement("head")}} 中添加以下代码即可: - - ```html - - ``` + 这里我们用 `canvas` 常量来存储画布的引用。第二行中我们将 {{domxref("Window.innerWidth")}}(可视区域宽度)赋值给一个新常量 `width` 和画布的 `width` 属性。第三行中,我们将 {{domxref("Window.innerHeight")}}(可视区域高度)赋值给一个新常量 `height` 和画布的 `height` 属性。然后我们就得到了一个充满浏览器窗口的画布。 - 此时滚动条就消失了。 + 你还可以看到我们使用了多个等号来进行链式赋值,这在 JavaScript 中是允许的,很适合为多个变量同时赋一个相同的值。我们想要使用 width/height 变量来更方便地访问画布的宽和高,因为它们是后面很有用的值(例如,你想在画布宽度的一半处绘制某个东西)。 > [!NOTE] -> 如上文所讲,一般情况下图片的尺寸可以通过 HTML 属性或 DOM 属性来设定。你也可以使用 CSS,但问题是画布在渲染完毕后其尺寸就是固定的了,如果试图调整,就会与其他图象一样(其实渲染好的画布就是一副图片),所显示的内容将变得像素化或扭曲变形。 +> 如上文所讲,一般情况下图片的尺寸可以通过 HTML 属性或 DOM 属性来设定。你也可以使用 CSS,但问题是大小调整是在画布渲染后进行的,就会与其他图像一样(其实渲染好的画布就是一幅图片),所显示的内容将变得像素化或扭曲变形。 -### 获取画布上下文(canvas context)并完成设置 +### 获取画布上下文并完成设置 画布模板设置还有最后一步。我们需要获得一个对绘画区域的特殊的引用(称为“上下文”)用来在画布上绘图。可通过 {{domxref("HTMLCanvasElement.getContext()")}} 方法获得基础的绘画功能,需要提供一个字符串参数来表示所需上下文的类型。 -这里我们需要一个 2d 画布,在 `