From 70e1e2aa82681b2c4ba3f0facccc21d0c2ed4698 Mon Sep 17 00:00:00 2001 From: wizardforcel <562826179@qq.com> Date: Sun, 13 May 2018 12:10:47 +0800 Subject: [PATCH] 19. --- 19.md | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 117 insertions(+), 3 deletions(-) diff --git a/19.md b/19.md index a035f15..70f1095 100644 --- a/19.md +++ b/19.md @@ -38,9 +38,9 @@ 这种方法有许多变种,每个变种都有自己的好处和问题,但它们的中心思想是一样的:状态变化应该通过明确定义的渠道,而不是遍布整个地方。 -我们的组件将是与界面一致的类。 他们的构造函数被赋予一个状态,它可能是整个应用状态,或者如果它不需要访问所有东西,是一些较小的值,并使用它构建一个`dom`属性,也就是表示组件的 DOM。 大多数构造函数还会接受一些其他值,这些值不会随着时间而改变,例如它们可用于分派操作的函数。 +我们的组件将是与界面一致的类。 他们的构造器被赋予一个状态,它可能是整个应用状态,或者如果它不需要访问所有东西,是一些较小的值,并使用它构建一个`dom`属性,也就是表示组件的 DOM。 大多数构造器还会接受一些其他值,这些值不会随着时间而改变,例如它们可用于分派操作的函数。 -每个组件都有一个`setState`方法,用于将其同步到新的状态值。 该方法接受一个参数,该参数的类型与构造函数的第一个参数的类型相同。 +每个组件都有一个`setState`方法,用于将其同步到新的状态值。 该方法接受一个参数,该参数的类型与构造器的第一个参数的类型相同。 ## 状态 @@ -72,7 +72,7 @@ class Picture { 我们希望能够将图片当做不变的值,我们将在本章后面回顾其原因。 但是我们有时也需要一次更新大量像素。 为此,该类有`draw`方法,接受更新后的像素(具有`x`,`y`和`color`属性的对象)的数组,并创建一个覆盖这些像素的新图像。 此方法使用不带参数的`slice`来复制整个像素数组 - 切片的起始位置默认为 0,结束位置为数组的长度。 -`empty `方法使用我们以前没有见过的两个数组功能。 可以使用数字调用`Array`构造函数来创建给定长度的空数组。 然后`fill`方法可以用于使用给定值填充数组。 这些用于创建一个数组,所有像素具有相同颜色。 +`empty `方法使用我们以前没有见过的两个数组功能。 可以使用数字调用`Array`构造器来创建给定长度的空数组。 然后`fill`方法可以用于使用给定值填充数组。 这些用于创建一个数组,所有像素具有相同颜色。 颜色存储为字符串,包含传统 CSS 颜色代码 - 一个井号(`#`),后跟六个十六进制数字,两个用于红色分量,两个用于绿色分量,两个用于蓝色分量。这是一种有点神秘而不方便的颜色编写方法,但它是 HTML 颜色输入字段使用的格式,并且可以在`canva`s绘图上下文的`fillColor`属性中使用,所以对于我们在程序中使用颜色的方式,它足够实用。 @@ -218,3 +218,117 @@ PictureCanvas.prototype.touch = function(startEvent, ``` 对于触摸事件,`clientX`和`clientY`不能直接在事件对象上使用,但我们可以在`touches`属性中使用第一个触摸对象的坐标。 + +## 应用 + +为了能够逐步构建应用,我们将主要组件实现为画布周围的外壳,以及一组动态工具和控件,我们将其传递给其构造器。 + +控件是出现在图片下方的界面元素。 它们为组件构造器的数组而提供。 + +工具是绘制像素或填充区域的东西。 该应用将一组可用工具显示为``元素,每个工具带有一个选项,并设置`"change"`事件处理器,用于在用户选择不同的工具时更新应用状态。 + +```js +class ToolSelect { + constructor(state, {tools, dispatch}) { + this.select = elt("select", { + onchange: () => dispatch({tool: this.select.value}) + }, ...Object.keys(tools).map(name => elt("option", { + selected: name == state.tool + }, name))); + this.dom = elt("label", null, "🖌 Tool: ", this.select); + } + setState(state) { this.select.value = state.tool; } +} +``` + +通过将标签文本和字段包装在`