案例研究 - deviantART muro 中的 HTML5

Mike Dewey
Mike Dewey

简介

2010 年 8 月 7 日,deviantART 庆祝了其十周年纪念日。 为了庆祝我们的生日,我们发布了一款名为 deviantART muro 的 HTML5 绘图工具。 该工具可作为独立的 Web 应用,以及用于向论坛评论添加图片的轻量级绘图工具。

deviantART 社区对这款新绘图工具充满热情表示,该工具本身现在看到的流量和一些规模合理的网络媒体资源一样多。自发布以来,系统大约每 5 秒使用 deviantART muro 提交一次新绘图。 这只是已完成的绘图数;还有很多绘图已经开始,并未保存。

下文介绍了一些背景信息,介绍了我们如何使用 HTML5、为什么选择使用我们所采用的技术,以及我在为一家大型网站编写首批完整 HTML5 应用的过程中发现的东西。

我的背景

2005 年末,我是一名开发者,负责 Draw Here 所使用的绘图工具。该工具是由小书签启动的“网络涂鸦”工具。 它用于在所有网页上绘制图片。Draw Here 最初是使用 SVG 创建的(Firefox 1.5 测试版刚刚问世;它是首批支持 SVG 的浏览器之一)。

在 Internet Explorer 上,我们在后台创建 SVG,但目前是使用 VML 渲染绘图。WebKit 当时不支持 SVG,因此我移植了我们的代码,以使用画布渲染 SVG(当时只有 WebKit 才支持这项新技术)。有一次,我甚至创建了一个端口,以便使用粘贴在一起的大量 div 元素在旧版浏览器上渲染我们的 SVG 代码。(当然,这只是个玩笑,表明它确实可以实现,而且使用起来非常慢,而且操作起来非常慢。)

在全盛时期,Draw Here 每天被用来创作大约 100 幅画。 虽然它并没有对主要 Web 应用进行最终润色,但它已经足够“玩转”了,并不仅仅只是一次实验。2006 年年中,该项目被废弃了,但这个网站如今还在走动不畅 - 主要只是为了开怀大笑。

deviantART muro 使用的技术

鉴于我在早期使用各种 HTML5 技术的背景,我受邀担任 deviantART muro 的首席开发者。任何阅读本文的人都能理解我们为什么决定采用 HTML5,而不是 Silverlight 或 Flash 等基于插件的技术。我们想要的是强大的产品,也要采用开放标准。

在画布和 SVG 之间做出选择

我们决定使用画布绘制图层有些人可能会想知道何时应使用画布以及何时应使用 SVG。使用这两种技术可以实现很多相似之处。正如 Draw Here 所证明的那样,这两种技术都可用于创建绘图应用。

我发现,如果您想保留已绘制对象的手柄,那么 SVG 是个很好的选择。例如,如果您希望用户能够绘制一条线,然后能够拖动这条线的一小部分以更改其形状,那么使用 SVG 会变得非常简单。但使用画布同样会造成很多尴尬的情况。

使用画布时,您只要在画布上发射内容,然后就忘记了。 空白画布和绘制了一小时的画布在行为上与代码完全相同,并且占用的内存大致相同。虽然光栅绘图程序通常可以很好地处理火灾并忘记技术,但它确实会导致某些问题变得困难。例如,在画布中创建快速撤消函数比在 SVG 中要难得多。在 SVG 中,您只需保留最后几条线条的手柄,撤消操作只需拉出这些对象即可。对于画布,绘制线条后,您不知道线条下面是什么内容,因此移除线条需要重新绘制其所在的区域。

在决定将 HTML5 用于画布后 我们决定在各处使用一些其他 HTML5 的好东西例如,我们如何使用 localStorage 来跟踪用户的画笔设置。这样,当他们按照自己喜欢的方式设置好不同的画笔后,下次使用我们的工具时,就可以重新使用这些设置。 localStorage 意味着我们不必使用 Cookie,也不必为了获得这些偏好设置而运行服务器。

使用画布

画布在过去五年中取得了长足的进步。使用“Draw Here”时,我们实际上没有发布自己的画布端口 因为效果不好现在,我可以肯定地说,它的效果可能比您想象的要好。 通常,清理一大块画布并重新绘制复杂的形状,能够以超越人类的感知的速度进行。我发现偶尔速度过慢的唯一一点就是使用 getImageData() 对像素进行采样。操作速度显然取决于画布大小,但是,在较大的画布上,在错误的时间执行 getImageData() 可能需要足够长的时间,让用户觉得应用响应速度很慢。

在阅读各种画布教程后,我最初感觉画布是一种很重的东西,应谨慎使用,可能在一个页面上使用一两次。我不知道是否每个人都能理解,但我确实理解了,所以刚开始接触 deviantART muro 的时候,就比较少用。但一段时间后,我发现很多小地方都可以用画布省下很多麻烦。 例如,应用的模型指明应该有一个颜色选择器,该选择器由两个显示主色和辅色的重叠三角形组成:

颜色选择器
颜色选择器

我的第一反应是开始构思一种使用传统 HTML 和 CSS 创建这个小界面小组件的方法。 擅长修改 CSS 的人可能会指出通过 CSS 实现这一切的方法,但改变颜色的两个部分的三角形使得这一点并不那么明显。

当我想到只使用画布时,我用单个 DOM 元素和几行 JavaScript 来制作这个微件。deviantART muro 到处使用了画布节点。每个图层都是一个画布,更改图层顺序只需切换 Z-index 即可。显示绘图区域的缩小视图的缩放“导航器”调色板只是另一种画布,它偶尔会将图层画布用作源图片来调用 drawImage()。即使是绘制区域光标(一个可根据笔刷大小和缩放调整大小的双色调圆圈)也是悬浮在鼠标下方的画布。

我们之所以能够比其他 HTML5 技术更自由地使用画布,是因为 Google 的 ExplorerCanvas 库可以在 Internet Explorer 中模拟画布。接下来我将转到下一部分。

Internet Explorer (IE)

更多主流网站尚未使用 HTML5 的主要原因是 他们不想失去 Internet Explorer 用户大多数开发者听到 deviantART 开发了 HTML5 绘图应用程序时,首先想到的第一个问题是:“对 IE 做了什么?”

我们一开始就决定要尽最大努力使 Internet Explorer 正常运行,但我们所做的工作最不常见。由于网络社区采取了一种措施,即网站只有在每个已知浏览器上的呈现效果都一样时才能启动,因此用户无法判断其是否缺少浏览器。对普通用户而言,速度问题归咎于他们的互联网连接,并且每个网页的呈现方式大体相同。因此,他们会根据任意的小界面内容(例如返回按钮的颜色)来决定自己喜爱的浏览器。

我们决定使用 HTML5 规范创建想到的任何很酷的功能,并尝试使其在 Internet Explorer 中运行,如果不起作用,我们仅弹出一个模态窗口,说明该功能不可用,因为他们的浏览器尚未实施网络标准。

我们最初尝试使用 Google 的 ExplorerCanvas (exCanvas) 实现了工作。它在大多数情况下都非常擅长模仿画布。不过,这样做有一个缺点。 在画布上做出的每个描边都是底层 VML 转换中的一个 DOM 对象。对于大多数您可能在画布上尝试的操作而言,这没关系,但 deviantART muro 的某些 Brush 通过将大量笔画堆叠在一起来创建形状。当 Internet Explorer 遇到包含数千个节点的 VML 时,即使是在速度较快的机器上,Internet Explorer 也会发生故障。因此,对于许多绘制调用,我们实际上必须进入实际 VML 并编写代码,运用一些技巧,将节点串联在一起,并使用移动命令指定应该有间隙的位置。界面中许多小控件和元素都使用了 canvas 标记,因为这些小用途通常适用于 exCanvas。

除了使用 exCanvas 实现一些功能之外,我们还建议用户,如果安装了 Google Chrome 内嵌框架插件,则可以继续使用 Internet Explorer 版本。Google Chrome 内嵌框架是一款插件,可将 Google Chrome 的呈现引擎嵌入到 Internet Explorer 中。 从用户的角度来看,他们仍然在使用自己熟悉的浏览器;但是在封面下,我们的网页使用 Chrome 的 HTML5 功能和更快的 JavaScript 呈现。

我以前知道移植到 Chrome 内嵌框架中应该很容易,但我没有意识到这有多简单。只需输入一个额外的元标记,就大功告成了 在 IE 中即可开始使用

摘要

使用 HTML5 规范中的新技术让我感到非常开心。我想说,我使用的所有工具都已做好充分准备。即使您需要一些工具在 IE 中都能完美地运行,也可以结合使用画布和 exCanvas,有大量功能可供使用。在 SVG 和 VML 之间编写翻译层也令人惊讶。一旦您开始使用这项技术,就相当于进入了一个全新的世界。

参考