Scribblify 如何通过 Node.js* 和 Chromium* 嵌入式框架提供跨平台 GUI





0/5 (0投票)
Scribblify 绘图应用程序凭借其 10 点触控功能和基于 Google Chrome* 的 GUI,利用英特尔® 开发人员区的资源,在 2013 年英特尔® 应用创新竞赛中荣获大奖。
引言
对于出生于威斯康星州的开发者 Matt Pilz 来说,第三次是幸运的。Pilz 是 LinkedPIXEL 的创始人,他的创造力和辛勤工作受到了英特尔举办的一系列开发者挑战赛评委的青睐。最近,他的 Scribblify 绘图应用程序凭借其 10 点 触控 功能和基于 Google Chrome* 的 GUI,利用英特尔® 开发人员区 的资源,在 2013 年英特尔® 应用创新竞赛 中荣获大奖。2013 年春天,Pilz 凭借一款通过手势控制的绘图应用程序 Magic Doodle Pad 赢得了英特尔® 感知计算挑战赛。2012 年,他的动作游戏 Ballastic 因其针对 Ultrabook™ 设备进行了优化而获奖。
与他之前的比赛经历一样,Scribblify(图 1)的想法早于比赛,但 Scribblify 最初是运行在手持设备上的。作为从比赛赞助商 联想 处获得 联想 Horizon* 一体机 (AIO) 的 200 名参赛者之一,Pilz 对将他的涂鸦应用扩展到全尺寸屏幕的前景感到兴奋。“当我读到联想 Horizon 一体机 拥有 1920 HD 分辨率和 27 英寸的大屏幕及触控功能时,我意识到能够创建一个巨大画布版本的这款应用程序,这样就可以在派对桌或其他大表面上绘画,这将多么有趣,”他说。“我的设想就在那里。”要实现这一点,Pilz 必须修改程序,使其能够很好地在比原始版本宽四到六倍的屏幕上运行,并接受 10 个同步触点的输入,而不是一个。
Scribblify 的起源
Pilz 于 2010 年开始涉足移动应用开发,大约在他获得第一台 Apple iPod touch* 移动设备时。LinkedPIXEL 于次年发布了 Scribblify 的早期版本。“第一个界面是为 480x320 分辨率设计的。一切都做得非常简约,以支持当时非常有限的硬件,”他回忆道。iOS 版 Scribblify* 于 2011 年 1 月登陆 App Store。“它确实走红了,并且每个月都在不断进步,”Pilz 说。所以大约一年前,他又发布了 Google Android* 版本。
Pilz 将 Scribblify 描述为一个具有特殊功能的休闲绘图和涂鸦程序。“它之所以与众不同,在于它的画笔和颜色效果,”他说。他自己设计的画笔(图 2)包含了许多此类绘图应用中不常见的纹理。“我真心认为其中大部分都相当独特,”他说,但他很快补充道,Scribblify 并不是要与高端插画应用竞争。“类似 Photoshop* 的应用程序的 iPad 版本有一个相当陡峭的学习曲线,”Pilz 说。“然后你还有一些有限的绘图应用程序,它们只提供一个圆形画笔和几个选项。没有一款能够达到我对 Scribblify 的设想水平,这款应用适用于所有年龄段的人,可以轻松上手使用。”
挑战
Pilz 面临的第一个主要障碍是决定使用哪种技术来构建 Microsoft Windows* 版的 Scribblify。他从 TGC 的 App Game Kit*(他用来制作 Ballastic 的引擎)开始。“这使我能够创建一个粗略的原型,但它不支持我在这款应用中想要的许多功能。”要获得比赛资格,应用程序必须为联想的 Aura* 多用户界面构建,并且不能依赖于底层操作系统的大部分功能。指南中的一项规定是,开发人员不得使用任何本机 Windows 对话框。“通过我的应用程序,用户可以轻松地浏览标准的对话框来保存他们的艺术作品或打开不同的图像,”Pilz 说,例如,在与文件系统交互时。“但这会偏离英特尔试图实现的目标……即让每个应用程序几乎成为一个沙盒。”
Pilz 的解决方案是使用 Node.js*,这是一个事件驱动的、服务器端的 JavaScript* 框架,用于为 V8(Chrome 浏览器内部的 JavaScript 引擎)构建网络服务。根据 Node 的创建者 Ryan Dahl 的说法,Node 框架通过使用事件循环使 I/O 非阻塞,并由于内置的事件池而促进了异步文件 I/O。
“Node.js 的一个主要目的是开发 Web 应用,并将其作为桌面应用程序本地使用,而不受操作系统限制,”Pilz 说。“您不必依赖安装 Windows;Node.js 是支持整个应用程序的后端。”使用该框架和名为 Node-Webkit 的库,Pilz 使用他使用标准 Web 技术定制构建的界面和图库系统,轻松保存和加载艺术文件。该应用程序运行在 Chromium* 嵌入式框架 (CEF) 之上,该框架提供了与 Chrome 相同的强大 HTML 和 JavaScript 渲染器。
Scribblify 如何保存和删除图像
Scribblify 应用首次加载时,通过 Node.js 检索用户的公共文档目录
// Initialize Node.js file system
var fs = require('fs');
// Get User's Documents Folder (Win 7+)
var galleryPath = process.env['USERPROFILE'] + "\Documents\Scribblify\";
galleryPath = galleryPath.replace(/\/g, "/"); // Use forward slashes
// See if folder exists, otherwise create it
if(!fs.existsSync(galleryPath))
{
fs.mkdir(galleryPath);
}
当用户请求保存图像时,HTML5 画布将被转换为图像数据
var saveImg = canvas.toDataURL();
A unique filename is generated based on timestamp, and Node.js saves the image data to the system.
// Write image data buffer to file
var data = saveImg.replace(/^data:image/w+;base64,/, "");
var buf = new Buffer(data, 'base64');
var fName = galleryPath + destFilename;
fs.writeFile(fName, buf, function(err) {
if(err)
{
console.log(err);
}
});
如果用户希望从图库中删除图像,Node.js 可以轻松实现这一点
fs.unlinkSync(galleryPath + targetImg);
获取现有文件列表以显示在图库中要稍微复杂一些,因为我还检查以确保只检索 PNG 文件(而不是目录或其他可能存在的文件)。
var fileList = fs.readdirSync(currentPath);
var result = [];
for (var i in fileList) {
var currentFileFull = currentPath + '/' + fileList[i];
var currentFile = fileList[i];
var fileExt = currentFile.split(".").pop().toUpperCase();
var stats = fs.statSync(currentFileFull);
if (stats.isFile() && fileExt == "PNG") {
result.push(currentFile);
}
else if (stats.isDirectory()) {
// Directory instead...
}
}
列表生成后,可以使用标准的 HTML 和 JavaScript 技术加载存储在数组中的图像路径。这既用于图库显示,也用于将特定艺术作品导入画布。
虽然 Pilz 能够使用他已经熟悉的(包括前端的 HTML5 原生画布元素和后端的 Node.js)技术原型化应用程序的大部分内容,但应用程序中最具突破性的一些功能简直是“爆炸式”的。“我试图在 Web 应用中做一些很少有人尝试过的事情——创建一个完整的创意绘图应用程序,使用复杂的纹理画笔,而不是程序生成的形状,”他说。
该程序最初运行良好,但 Pilz 很快发现了一个问题。“当使用超过几个触点或绘制速度过快时,应用程序会因为画布元素的性能而延迟几秒钟,然后才会继续,”他说,他指的是新应用程序的响应能力。这次寻找解决方案的经历让他找到了 Cocos2d-x,这是一个在 MIT 许可证下可用的开源跨平台框架,最近为其 JavaScript 分支添加了 WebGL 支持。
Cocos2d-Javascript 让 Pilz 更轻松地将他的代码移植到 WebGL,他表示 WebGL 性能更好,并且得到他的 AIO 开发系统中的显卡的大力支持。“现在,Cocos2d-Javascript 使用 WebGL 将绘图渲染到屏幕……并且以每秒 60 帧的速度运行。这优化了体验,并使其非常有趣,”Pilz 说。Scribblify 使用标准的 HTML 来实现界面元素和用户交互;Pilz 将其描述为标准 HTML 和 JavaScript 的混合体,混合了包括用于后端处理的 Node.js 和用于简化 WebGL 渲染的 Cocos2d-Javascript 在内的其他引擎。
对于一般性问题,Pilz 求助于 Stack Overflow,这是一个免费的问答网站,面向开发专业人士和业余爱好者。“我曾经几次在那里研究特定任务,或者卡在某个问题上,”他说。“这是一个快速简便的参考,可以看到其他人推荐了什么。”对于特定于 Cocos2d-x 和 Node.js 的帮助,Pilz 大量参考了这些产品的 API;当然,他使用 CodeProject* 不仅是为了这个项目,也是为了这些年来的其他项目。“我每次想深入研究某些编程主题时都会去那里,”他说。“他们有与本次比赛相关的非常有用的讨论论坛,并且能够快速回答问题。”
Pilz 还发现了一个 bug,涉及 Chromium 如何与联想 Horizon 驱动程序集协同处理触摸,导致一些触摸没有被释放,尤其是在快速使用时。他的解决方案是构建一个小的“检查和平衡系统”,如果错误地记录了过多的触摸,则会发出警报。“它将自动将用户的艺术作品保存到图库,并提醒他们应该重新启动应用程序,”他说。然后,它会提供有关如何防止此类问题的指南。“例如,如果用户用整个手掌触摸它,它会显示警报‘你不应该那样做,只用指尖’。它还会建议你重新启动,”他说。“在比赛期间,我已将此作为 正式 bug 报告 提交给了 Chromium 开发者。”
var canvas = document.getElementById('canvas');
canvas.addEventListener('touchstart', touchStartFunction, false);
canvas.addEventListener('touchend', touchEndFunction, false);
canvas.addEventListener('touchcancel', touchCancelFunction, false);
canvas.addEventListener('touchmove', touchMoveFunction, false);
canvas.addEventListener('touchleave', touchLeaveFunction, false);
Chromium* 嵌入式框架(Google Chrome* 即基于此)早已支持原生触控控件,实现起来非常方便。可以使用简单的事件处理程序绑定各种形式的触摸,包括 touchstart、touchend、touchcancel、touchmove 和 touchleave。
比赛的时间限制——以及 Pilz 使用的框架的限制——导致他推迟或放弃了 Scribblify 的某些功能的实现。“我想要添加的一个重要功能是完整的撤销和重做系统,但我不知道如何在不拖慢系统的情况下实现这一点,”Pilz 说。所以目前,只有一个橡皮擦和一个用于清空画布的按钮。他还想包含更多的绘图模式和更多的画笔。
调试
开发基于 Web 的应用程序的好处之一是,大多数现代浏览器都配备了全面的调试工具,Pilz 表示这在整个开发过程中都非常有价值。
“对我来说,也许最有价值的是 Chrome 开发者工具支持功能齐全的 JavaScript 调试器。这使我能够创建断点并逐行步进代码,并在整个过程中监控特定变量和属性,尤其是在遇到问题时,”他说。同时,Pilz 能够分析特定的文档对象模型 (DOM) 元素并即时更新样式,以更快地获得期望的结果。Pilz 还发现联想在 lenovodev.com 上提供的开发者资源非常有帮助,特别是 Horizon 应用集成要求(需要登录)。
多用户
Scribblify for AIO 支持 10 个同步触点,这意味着多达 10 个用户可以同时在画布上绘图。考虑到比赛的时间限制,Pilz 的首要考虑因素是他能够轻松集成多点触控功能的程度。“当我最终决定使用 HTML5 及相关技术开发基于 Web 的应用程序时,我知道,如果我使用一个已经支持桌面多点触控的 Web 基础,处理多点触控的复杂性就可以大大缓解,”他说。
值得庆幸的是,CEF 在其桌面和移动版本中一直支持这种功能。Pilz 说,由于整个应用程序都通过 CEF 提供支持,因此可以轻松地存储和检索 AIO 支持的任意数量的 触控 数据。
其他文章
- All-in-One PC: What are the developer possibilities?
- 面向第四代英特尔®酷睿™处理器的英特尔®处理器显卡开发人员指南
- 为新一代一体式电脑开发沉浸式应用程序
更多创新
在你使用 Scribblify 或观看 LinkedPIXEL 的 演示视频 之前,很难体会到它的画笔是多么不寻常。“我认为画笔本身是 Scribblify 最具创新性的方面,”Pilz 说。“所有设计和画笔都是我自己的发明,[而且]每一个都有许多不同的属性来控制它在屏幕上绘制时的外观和行为。它们非常独特。”
Pilz 还为他花了六周时间几乎从头开始构建的用户界面感到自豪。“能够用十根手指同时绘制,使用 10 点多点触控,或者一个人在一边,一个人在另一边同时绘制,我认为这是一种创新的体验,”他说。Pilz 承认在可能的情况下也采取了一些捷径。“我使用了一些库,比如用于高级颜色选择器,”他说。“一些 MIT 许可的库加快了该过程,这样我就不必重新发明轮子了。”
Scribblify 还提供了一种创新的颜色选择和混合方式。“你可以添加许多不同的颜色效果,而不仅仅是选择一种基本颜色,”Pilz 说。“你可以真正地将两种颜色混合在一起,或者使用等离子颜色,甚至添加我称之为‘颜色变化’的功能,该功能会在你绘制时混合深浅色调,以创建更自然的艺术作品。”
最近,Pilz 一直在努力将 Scribblify 转换为原生的 Windows 8 应用,以便通过 Windows 应用商店分发——包括通过专门的联想 Windows 8 应用商店。为了以最简化的方式满足要求,即将推出的 Scribblify 版本将由 Internet Explorer* 11 提供支持,而不是 Chromium,并且由于不支持 Node.js,将使用新的方法来处理文件输入/输出。Scribblify 的 Windows 应用商店版本预计将在 2014 年 4 月至 5 月期间发布。
关于比赛
2013 年英特尔应用创新竞赛号召 Code Project、Habrahabr、ThinkDigit 和 CSDN 的应用开发者提交适用于 Windows 平板电脑和一体机设备的跨金融、医疗、零售、教育、游戏和娱乐行业的应用创意。获奖创意将获得开发系统——200 台平板电脑和 300 台来自赞助商联想的一体机中的一台——并有六周时间将创意转化为演示应用。获奖应用 在此列出 在 英特尔® 开发人员区。
在 500 个创意中,创建了 276 个演示应用,其中五个被选为每个类别中的最佳,总共 30 名获奖者。评判标准包括每个应用展示其宿主平台能力的好坏程度、它在市场细分中的表现如何,以及它是否解决了目标终端用户的需求。当然,获奖应用必须看起来专业并采用良好的图形,性能良好,无故障,并在适当时利用传感器。