Scribblify - 富于想象力的艺术






4.98/5 (15投票s)
用这款适合所有年龄段的独特涂鸦应用,释放你最狂野的创意。
- 应用名称: Scribblify
- 目标平台: 联想 Horizon 一体机
- 选定类别: 娱乐
- 编程平台: C++、AGK / C#、CSS3、HTML5、JavaScript
- 摘要: 用这款独特的涂鸦应用,释放你最狂野的创意;老少皆宜!
开发者事后总结
2013年应用创新大赛的提交阶段现已结束,我终于有时间喘口气,回顾过去六周的极速开发过程。在这篇冗长的事后总结长文中,我将谈谈我在制作一款与联想Horizon一体机和Aura界面兼容的有趣且娱乐性的桌面应用程序时所遇到的各种成功和挑战。本文不会是代码堆砌,而是一个详细且希望能提供深刻见解的解释,说明我在开发过程中采取的一些方法以及如何克服了许多障碍。
前言
当我第一次查看联想一体机的规格时,我立刻被其巨大的27英寸屏幕和全1080p分辨率以及10点多点触控功能所吸引。一个素描应用似乎是自然的选择,我立刻设想了一个桌面绘图板,所有家庭成员都可以围坐在一起享受。事实证明,我不是唯一有这种愿景的人。娱乐类别中至少还有两个其他作品也是绘图应用,尽管它们都有各自的独特之处。CodeProject之外可能存在其他类似概念,但我很难浏览不熟悉的AIC 2013网站。
三年前,我为iPhone(后来也为iPad)开发了一款名为Scribblify的绘图应用。它使用Objective C开发,是一款严格意义上的移动iOS应用程序。界面和所有功能都设计用于低分辨率(480x320)和有限的硬件能力。这款应用最独特的特点包括我创建的原创且高度多样化的画笔、对称绘图功能和特殊颜色效果模式。这款应用的目标不是与任何严肃的插画应用竞争,而是让任何人,无论年龄或技能水平,都能即时创作出色彩丰富且独特的艺术作品。Scribblify获得了一定的追随者,尤其是在学校;下载量超过25万,它在全球范围内持续受到喜爱。
上图:Scribblify的原始移动版本,大约在2010年。尽管此后该应用进行了更新,包括对视网膜屏和iPad的支持,但整体界面仍然以移动设备为中心,设计为适合480x320的区域;在桌面版本上使用这样的界面,充其量只会感到局促。
凭借开发创意绘图应用程序的一般熟悉度和之前为触摸设备(包括移动和桌面)开发的经验,我提议作为本次比赛的一部分,从头开始为桌面平台重新开发Scribblify。从理论上讲,直接移植原始版本可能可行,但移动设备与桌面设备行为的显著差异以及我最初设计的相对原始的GUI使得这种做法不理想,在大尺寸一体机上也不直观。
大约六周的扎实开发时间和三次核心编程方法论的重大变更之后,我的成品被上传到CodeProject。它不可避免地包含一些小问题,并且缺少我希望包含的一些功能,但考虑到我遇到的时间限制和开发障碍,我仍然认为它是一个巨大的成功。
上图:最终产品。经过一个半月的紧张开发和三次开发平台之间的转换,Scribblify的新一体机版本最终呈现。
原型开发 - AGK (App Game Kit)
在开始开发生产级应用程序之前,我想先创建一个功能原型,以检验我计划的整体可行性,并了解应用程序在实际触摸设备上的运行方式。为此,我转向了一个名为AGK(App Game Kit)的小型开发套件,该套件由TheGameCreators几年前发布。AGK支持BASIC(一级)和C++(二级)开发分支,并提供轻松部署到各种平台,包括iOS、Android、Blackberry、Windows和Mac。
事实上,AGK完全能够制作出精良且快速的桌面应用程序;我最终获得2012年AIC奖项的作品Ballastic就是使用AGK开发的。今年至少还有三位竞争者也使用了AGK。然而,对于这款应用,我知道AGK缺少我想要的一些基本功能,而且下一个版本要到12月才能准备好。即便如此,我还是使用AGK创建了一个非常基本的原型,用于测试联想AIO的触摸响应和一些特定于应用程序的功能。
上图:卑微的开始,2013年10月5日。这是Scribblify AIO桌面版的原始原型,在AGK中构思,用于测试触摸响应和一些我希望包含在最终提交中的绘画相关效果,包括镜像模式和颜色选择。
AGK由OpenGL驱动,因此可以非常高效地处理纹理和图像操作。然而,当前版本不原生支持动态绘制到纹理或渲染缓冲区(下一次更新预计会支持)。您可以禁用主缓冲区的清除[EnableClearColor(0)],这样它将保留绘制到其上的任何内容,但这有点不可预测,并且在尝试覆盖界面元素时会导致更多问题,因为它们也将基本上被“烘焙”到屏幕中。还有许多其他可行的方法,包括内存块操作(即,迭代像素并手动修改它们)和标准精灵克隆,但要创建一个独立于其他元素的简单绘图画布仍然比理想情况更麻烦——同样,下一个测试版应该能解决这个问题。
基础开发 - HTML5 Canvas 2D
我在网络相关开发方面有很多经验。我经常考虑将Scribblify带到桌面的一个平台是HTML5及其原生canvas元素,现在所有浏览器都很好地支持它。然而,我从来没有太大的动力这样做(只有一个人正式提出过请求),直到这次比赛开始两周后我才开始付诸行动。尽管我过去在一些项目中曾涉及canvas渲染,但在接下来的几周里,我从未像现在这样深入了解它。
HTML5 canvas 2D在联想Horizon上的初步基准测试非常有希望。事实上,当使用HTML5中可用的原生绘图功能(即绘制线条、矩形、填充)时,即使进行复杂的运算,Chrome也能稳定达到60 FPS。我在联想上测试的每个现有HTML5应用程序都使用基于形状的绘图操作,并且运行流畅。然而,这些应用程序大多数只支持单点触控,并且没有一个包含Scribblify所需的丰富基于图像的纹理和组件。因此,要找出Scribblify通过canvas 2d实现真正性能可行性的唯一方法是实际构建应用程序!
在此开发阶段,我选择不使用除原生 HTML5 canvas 功能之外的任何框架。因此,所有与上下文转换和渲染相关的繁重工作都必须手动开发。HTML5 的默认 canvas 功能相当底层,或者说我可能只是被所有支持简单精灵绘制和易于对象转换的开源框架和产品(包括 AGK)宠坏了。对于 HTML5 canvas 操作,对图像应用简单的旋转可能是一个相当复杂的问题,它涉及保存上下文的当前状态,转换整个 canvas,将图像绘制到新转换的上下文(通过偏移量来补偿左上角的锚点),然后恢复 canvas 的先前状态。
上图:Scribblify HTML5 2D Canvas 版本的最终迭代,2013年10月27日。所有用户界面元素都是标准 HTML 组件(使用 CSS 样式和 JavaScript 控制),而 canvas 渲染本身使用原生 HTML5 canvas 方法完成(无外部库)。
在使用纯 Canvas HTML5 方法时,我遇到的最大障碍之一是动态改变画笔颜色。当使用 Canvas 支持的原始绘图形状和命令时,您可以轻松设置描边和填充颜色(例如,context.fillStyle = '#FF0000';)。事实上,您可以传入任何 RGB/RGBA/HSL/HEX 格式,它都能正常工作,就像 CSS 一样。一旦描边或填充颜色被分配,所有后续对上下文的调用都将使用指定的填充颜色,直到您再次更新它或将上下文恢复到其先前的状态。这就是几乎所有基于 Canvas 的绘图应用程序改变画笔颜色的方式,它快速高效。您可以通过创建具有独特形状的自定义图标字体(即不同的画笔)来发挥更多创意——Canvas 填充命令同样会影响文本;文本对象也可以像任何其他 Canvas 元素一样进行转换,这为您提供了比单独的原始形状命令更多的灵活性。
不幸的是,上述着色方法不适用于Scribblify。Scribblify的标志性画笔严重依赖于阴影色调来创建有机和抽象的纹理效果,这是使用纯色无法实现的。通过使用文本或原始形状和画布填充函数,您将始终得到实心颜色。当然,您可以调整整体不透明度或应用额外的后处理效果,例如柔和边缘,但结果仍然不适合Scribblify,并且会带来额外的开销。另一种巧妙的方法是读取源图像的像素,为每个通道(R、G、B、Alpha)存储一个单独的实例,然后通过使用HTML5中可用的“lighter”复合模式将全局透明度乘以目标颜色值来实时将它们组合成一个新图像。这种方法的缺点是它在少数特殊情况下无法按预期工作,例如在透明画布上创建结果图像。还有另一种方法是遍历画笔的所有像素并手动更新每个像素的色调。当定期调用该命令时,这是可以接受的,但Scribblify中的颜色效果要求用户在绘图时每帧进行多次颜色更改操作,因此这种方法会严重影响帧率。
对于 Scribblify 的 HTML5 2D canvas 版本,我最终采取了一个相对简单的两步方法,以高效地设置画笔颜色,即使每帧多次,同时保留原始纹理的细节。第一步是使用与所需画笔颜色匹配的填充色,将一个原始矩形绘制到临时 canvas 上。然后,使用“destination-atop”复合模式,将源图像绘制到矩形上方。结果将保留源图像的透明度,同时使用矩形的着色(为了有效工作,源图像应该是灰度)。然后,使用“multiply”复合模式(最近才被纳入 Chrome),再次将原始源图像绘制到之前的输出之上,以恢复灰度色调,但保留最终颜色。canvas 上下文的 drawImage() 方法可以接受另一个 canvas 作为其参数,而不是图像,因此您可以将临时 canvas 直接传递给主 canvas 来绘制经过颜色处理的画笔。
仅仅在短短三周内,我在HTML5 canvas方法上取得了卓越的进展。在此过程中,我完成了大部分关键的界面组件,包括画笔选择器、基本颜色选择器、大小和透明度滑块以及基本的颜色效果选项。如前所述,我做出了开发决定,严格使用HTML、CSS和JavaScript组件作为GUI,而不是不必要地在canvas中编写所有代码。在我看来,只有当功能无法以更简单、更合乎逻辑的方式(例如使用常见的HTML组件)完成时,才使用canvas操作才有意义。(我最初将顶部颜色选择器栏编码为一个动态生成的canvas元素,但为了简单起见,将其恢复为由CSS样式化的简单DIV容器块)。借助jQuery和众多扩展,一些与界面设计相关的任务得到了极大的简化。
唉,即使我在这个 Scribblify 的 2D canvas 版本中取得了所有成功,一旦涉及到多点触控和颜色效果,我发现性能仍远未达到最佳。帧率会下降到 10-20 FPS,尤其是在用多根手指快速绘制时,这与我创造真正沉浸式绘画体验的愿景不符。与更传统的基于矢量和形状的路径绘制相比,通过 drawImage() 进行的图像绘制操作被证明是 2D canvas 渲染的一个主要瓶颈。
最终开发 - WebGL 救援
在只剩下几周时间的情况下,我开始探索 WebGL 替代我的原生 2D canvas 方法。我不精通 OpenGL,更不用说在如此短的期限内。然而,我预感 Chromium 快速的 WebGL 渲染能力能够解决将许多纹理精灵快速连续绘制到渲染缓冲区或 canvas 的问题。我探索了各种开源和 MIT 许可的 WebGL 框架,以寻找一个能够让我现有的 canvas 工作轻松过渡,并获得使用 WebGL 带来的硬件加速性能优势的框架。
我发现的一个有趣的解决方案叫做WebGL-2d。这个小型的JavaScript库可以在初始化后,用一行JavaScript代码立即将任何2D canvas转换为WebGL canvas。原生的2D canvas操作在后台透明地转换为WebGL操作,然后生成的canvas使用WebGL渲染到屏幕上。令我沮丧的是,这个库已经有几年没有更新了,并且缺少许多我已经用2D canvas编写的canvas函数,包括图像旋转的上下文转换等基本功能。在截止日期临近,而且应用程序还有很多工作要做的情况下,我没有足够的WebGL经验来充分进行必要的更改。我探索的另一个框架是pixi.js,它非常流畅,并且根据用户的浏览器轻松支持2D和WebGL canvas模式。但它是一个非常新的引擎,需要大量的修改才能将我的canvas数据迁移到它,因为它不包含一些关键元素的预构建功能,包括动态调整图像颜色的能力。
我的最终决定是继承相对成熟、采用 MIT 许可的 Cocos2d HTML5 框架用于 canvas 本身,同时保留我之前为核心用户界面开发的所有组件。Cocos2d HTML5 最初只支持 canvas 操作,但最近它也集成了 WebGL。由于我使用标准 HTML 组件和库开发了整个 GUI,因此将它们移植到基于 C2D 的 HTML5 应用程序几乎没有问题。然而,我所有的原始 HTML5 canvas 绘图操作都必须进行相当大的修改,并使用新语法移植到 C2D。我大约花了一周时间才将所有绘图代码移植到 C2D。WebGL 具有更直接、更准确的颜色转换(尤其是在使用 C2D 库封装时)以及以闪电般的速度处理纹理绘制的额外优势。
上图:Scribblify 应用接近完成,现在使用 WebGL 驱动的 Cocos2d HTML5 引擎,即使在多点触控和持续颜色切换的情况下也能达到惊人的 60 FPS。
关键时刻。我测试了Scribblify新的支持WebGL的版本,并监测了帧率。即使所有十根手指同时绘图,并使用操作最密集的画笔,我通常也能保持大约60 FPS!它偶尔会下降,尤其是在镜像模式下,但从未达到明显可察觉的程度。
总结 - Aura 界面要求
只剩下一周时间,我仍然有一些重要的 GUI 组件需要处理。Aura 界面指南对为该平台设计的应用程序规定了几项严格的要求。其中有两项特别引起了我的注意。1.) 应用程序必须全屏显示,没有浏览器边框或任务栏。2.) 应用程序不能使用任何原生对话窗口。由于我的应用程序是基于 Chromium 的,我知道全屏的最佳方法是将其编译成一个原生可执行外壳。(还涉及到本地安全方面的考虑,因此仅仅使用“信息亭”模式是不够的)。一些开源项目正好支持这一点,包括 app.js 和 node-webkit。Node-webkit 维护更活跃,支持选项更广泛,所以我最终采取这种方法来打包我的 Web 应用程序,并通过一个 EXE 全屏启动它。
对于基于网络的应用程序,使用默认对话框窗口是自然且容易的。Scribblify需要支持最基本的本地保存绘图功能。这可以通过简单的JavaScript功能实现,将画布数据转换为URL/PNG后调用“另存为”对话框窗口。加载图像同样可以通过使用文件输入元素让用户从计算机中选择文件来完成。但为了符合Aura的要求,我最终开发了一个自定义的本地画廊系统,包含保存和加载功能。使用Node.js,解决了本地网络应用程序中的文件系统限制,并且可以轻松执行通用的文件系统操作。这个画廊功能耗费了相当大的精力,但最终使应用程序感觉更加精致和完整。
上图:Scribblify 完成的画廊视图。从画廊中,用户可以预览他们之前保存的艺术作品,查看全屏版本,删除特定作品,或将任何项目导入回画布进行额外合成。
我无法强调我对众多开源库和组件的感激之情。我能够使用许多现有库作为Scribblify一些重要部分的基礎——用于高级颜色选择器的颜色选择器小部件(jQuery MiniColors)、用于滑块控件的jQuery UI、用于画笔选择器触控功能的iDangerous Swiper、用于基本全屏画廊预览的Lightbox、用于各种颜色调整例程的colors.js、用于系统文件操作的node.js、用于EXE编译的node-webkit、用于WebGL功能的Cocos2d HTML5、用于增强jQuery UI元素触控支持的jquery.ui.touch-punch...
感人时刻
关于开发过程中遇到的问题,最后一个注脚。似乎联想 Horizon 在狂乱的触摸动作或不止用指尖进行交互时,有时会出现触摸无法成功捕获或释放的奇怪现象。其他开发者在 CodeProject 论坛和其他地方,在使用各种不同平台开发时也报告了这个问题。同样的问题在 Chrome/Chromium 中也很突出,尤其是在将整个手掌按在屏幕上并稍微移动时(这在 Horizon 上通过 Chrome 运行的任何网站或 Web 应用中都是如此)。Chrome 在 touchstart 时将每次触摸存储在一个 TouchList 对象中,但当许多触摸同时接触时,有些触摸永远不会释放。最终,12 个限制的 TouchList 数组被填满,所有后续触摸都会停止,直到浏览器重新启动。因此,手动干预只能在一定程度上解决这个问题(TouchList 对象是不可变的,不能由客户端更改)。我向 Chromium 团队详细描述了这个错误,他们尽力分析,但得出结论这是一款设备特定的 Windows 独有问题,他们无法在自己的 10 点触控设备上使用我为测试构建的相同演示应用程序重现。
我花了相当多的时间来弥补Chromium允许范围内的触摸问题。如果一个或多个触摸被错误地记录,应用程序将默默地处理与HUD交互时的替代操作,这通常不会被注意到(除了偏好设置中的选项切换可能会偶尔出现异常行为)。如果用户立即触发不可能的触摸数量,将出现一个警报,解释情况并提供一些关于未来如何预防的指导(只使用指尖)。此时,Scribblify会自动将其当前作品保存到画廊,并鼓励用户重新启动应用程序以恢复完整的触摸控制。他们可以忽略警告,可能仍然可以进行一定程度的绘画,但某些手指将不可用。我相信这个问题将通过Horizon的固件/驱动程序更新来解决,因为它似乎无法在其他设备上重现。
专为所有年龄和技能水平设计
正如我一直以来的座右铭一样,我的最高目标是创建一个功能强大且功能丰富的应用程序,既能让专业艺术家享受,也能让儿童和非艺术家在创作伟大艺术时获得同样的乐趣。在开发阶段,我向各种各样的人群展示了这款应用程序,从两岁的孩子到97岁的老妇人,所有人都毫无问题地创作出充满活力和抽象的艺术作品,并乐在其中。我相信,凭借这一点,我的使命成功了!
原文如下
介绍
用Scribblify,一款独一无二的绘图和绘画工具,让所有年龄和技能水平的儿童和成人尽情发挥创意。从自然到抽象,以及介于两者之间的一切,Scribblify让任何人都能轻松创作出精彩的艺术作品——只有想象力能限制你。这款应用条目将是现有移动应用程序的桌面移植版,专门为一体机开发,并由应用创新大赛推广。桌面版将包含更多样化的用户界面和其他独特功能,以适应联想一体机上的可用功能,包括最多10个同时触控和宽屏高清显示。
这款为一体机设计的桌面应用程序将包含数十种手工制作的画笔,每种画笔都具有独特的外观和行为。大多数画笔与别处所见的截然不同,从有机到超现实。此外,还将提供许多令人兴奋的颜色效果,以支持创意混合、等离子颜色等。种类繁多的专属画笔、预设背景、高级颜色效果和镜像绘画功能确保为所有人带来无尽的娱乐。
背景
Scribblify 自 2011 年以来一直作为移动应用程序存在。作为一款移动产品,必须精心设计界面和功能集,以支持低分辨率手机和相关设备。直到 2013 年应用创新大赛,Scribblify 的桌面版本从未被构想过,更不用说开发了;它一直是一款仅限移动设备的应用程序,从而隔离了很大一部分潜在用户。
不难看出,为更大、更强大的设备开发此类应用程序的好处,包括本次挑战赛推广的27英寸全高清一体机。凭借足够大的屏幕尺寸(足以铺满咖啡桌)和10点多点触控技术,我立刻设想了一个Scribblify的桌面版本,它将使整个家庭能够围坐在一体机旁,像在大画布上用手指画画一样创作出璀璨的艺术作品。
视觉享受
作为视觉预告,下面展示了Scribblify核心基础和艺术可能性的截图。请注意,这些截图来源于应用程序的原始移动版本。然而,原始版本中的大部分画笔、效果和功能也正在新的桌面应用程序中实现。另一方面,整体界面将重新设计,以反映一体机上更大的屏幕空间。
幕后
Scribblify 的原始移动版本是使用 Objective C 和 OpenGL ES 1.0 为 iOS 开发的。随后,使用兼容的 C++ OpenGL ES 库从头开始开发了 Android 移植版本。一体机版本再次使用与 PC 兼容的解决方案和库从头开始开发。部分媒体资产(特别是画笔和背景)将继承自移动版。核心绘图和着色方法也将根据需要移植,以有效模仿移动版中的基本功能。
Scribblify 最终桌面版将使用的具体框架和底层编程语言仍在评估中。在一体机的初步测试中,AGK(App Game Kit)的 C++ 第二层版本将用于快速开发具有完整传感器支持的功能原型。由 The Game Creators 开发的 AGK 具有一套针对传感器的特定方法,可轻松利用英特尔最新产品线中的许多传感器。
自去年秋天以来,AGK已支持英特尔超极本系列笔记本电脑和所有主要移动设备中提供的所有传感器;这些命令应与联想系列电脑保持通用兼容性。由于AGK框架支持C++开发,因此在此项目的原型阶段可以根据需要添加额外的传感器支持。
对于 Scribblify 而言,多点触控是应用程序所需的最重要的传感器。AGK 提供了对十几个简单触控命令的集成支持,使得快速捕获触控数据并根据需要进行处理变得容易。它内置支持区分点击、按住和拖动,以及每次触控的先前和当前坐标。一些此类命令的非常简单的示例如下:
// AGK: Basic multitouch functionality
// Determine if the device supports multitouch
if (agk::GetMultiTouchExists())
{
// Get total number of active touches
int touchCnt = agk::GetRawTouchCount(0);
// Get index of first touch
int touchIndex = agk::GetRawFirstTouchEvent(1)
// If touch index is greater than 0, handle touches
while (touchIndex > 0)
{
// Store some properties of the current touch
Touch touch;
touch.startX = agk::GetRawTouchStartX(touchIndex);
touch.startY = agk::GetRawTouchStartX(touchIndex);
touch.currentX = agk::GetRawTouchCurrentX(touchIndex);
touch.currentY = agk::GetRawTouchCurrentY(touchIndex);
touch.mode = agk::GetRawTouchType(touchIndex);
// Perform needed actions based on touch data
// Check for other touches
touchEvent = agk::GetRawNextTouchEvent();
}
}
一旦通用原型被证明成功,Scribblify桌面版的开发可能会转向其他开发领域。不幸的是,AGK可能尚未支持确保此应用程序平稳和多功能性能所需的一系列所需功能。因此,将根据需要评估其他基于OpenGL的解决方案,以将原型转换为精良的应用程序。最终部署的替代平台的细节仍在审查中,但可能包括基于HTML5的Web应用程序(使用Canvas和其他非WebGL技术)或使用现成的基于OpenGL框架的C++/C#衍生应用程序。关键是在比赛截止日期前快速开发出一个可用的应用程序,之后再进行 minor 更新。
一体机
如本文所述,本项目是现有移动应用程序的首次PC移植。该应用程序正在全新开发,部分现有媒体和核心功能从移动版本移植过来。本版本将包含许多移动设备中没有的功能,专门强调一体机的能力。主要升级包括:
- 最多支持10个同时触控(而移动版本最多支持两个)
- 更突出和直观的界面,以反映更大的屏幕空间
- 使用1920高清分辨率的16:9画布绘图功能
- 额外的镜像模式,以多种形式快速创建对称艺术。
- 考虑通过Aura界面提供的多用户功能
历史
文章第一版;是为2013年应用创新大赛提交的原始快速参赛作品的补充。