资讯专栏INFORMATION COLUMN

JavaScript 编程精解 中文第三版 十九、项目:像素艺术编辑器

Meils / 3542人阅读

摘要:相反,当响应指针事件时,它会调用创建它的代码提供的回调函数,该函数将处理应用的特定部分。回调函数可能会返回另一个回调函数,以便在按下按钮并且将指针移动到另一个像素时得到通知。它们为组件构造器的数组而提供。

来源:ApacheCN『JavaScript 编程精解 中文第三版』翻译项目

原文:Project: A Pixel Art Editor

译者:飞龙

协议:CC BY-NC-SA 4.0

自豪地采用谷歌翻译

我看着眼前的许多颜色。 我看着我的空白画布。 然后,我尝试使用颜色,就像形成诗歌的词语,就像塑造音乐的音符。

Joan Miro

前面几章的内容为你提供了构建基本的 Web 应用所需的所有元素。 在本章中,我们将实现一个。

我们的应用将是像素绘图程序,你可以通过操纵放大视图(正方形彩色网格),来逐像素修改图像。 你可以使用它来打开图像文件,用鼠标或其他指针设备在它们上面涂画并保存。 这是它的样子:

在电脑上绘画很棒。 你不需要担心材料,技能或天赋。 你只需要开始涂画。

组件

应用的界面在顶部显示大的元素,在它下面有许多表单字段。 用户通过从字段。 当前选择的工具决定了,当用户使用指针设备与图片交互时,发生的事情。 它们作为一个对象而提供,该对象将出现在下拉字段中的名称,映射到实现这些工具的函数。 这个函数接受图片位置,当前应用状态和dispatch函数作为参数。 它们可能会返回一个移动处理器,当指针移动到另一个像素时,使用新位置和当前状态调用该函数。

class PixelEditor {
  constructor(state, config) {
    let {tools, controls, dispatch} = config;
    this.state = state;

    this.canvas = new PictureCanvas(state.picture, pos => {
      let tool = tools[this.state.tool];
      let onMove = tool(pos, this.state, dispatch);
      if (onMove) return pos => onMove(pos, this.state);
    });
    this.controls = controls.map(
      Control => new Control(state, config));
    this.dom = elt("div", {}, this.canvas.dom, elt("br"),
                   ...this.controls.reduce(
                     (a, c) => a.concat(" ", c.dom), []));
  }
  setState(state) {
    this.state = state;
    this.canvas.setState(state.picture);
    for (let ctrl of this.controls) ctrl.setState(state);
  }
}

指定给PictureCanvas的指针处理器,使用适当的参数调用当前选定的工具,如果返回了移动处理器,使其也接收状态。

所有控件在this.controls中构造并存储,以便在应用状态更改时更新它们。 reduce的调用会在控件的 DOM 元素之间引入空格。 这样他们看起来并不那么密集。

第一个控件是工具选择菜单。 它创建