Canvas在Flyme主题的应用实践

Posted 魅族技术

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Canvas在Flyme主题的应用实践相关的知识,希望对你有一定的参考价值。

基本概览

Canvas是html5中新增的新标签,提供了一套强大的使用javascript绘制画布的API。

简要概括Canvas功能,主要包括:

  1. 形状绘制,包括线条及其组成的其他形状;而绘制又分为Fill和Stroke两种形式,前者填充整个形状,后者只绘制边框;
  2. 文本绘制,往往同时需要对其Style进行设置;
  3. 图片绘制,一方面对图像进行裁剪缩放等处理,另外也可以通过对修改图片内容数据imagedata来达到更精准的像素级图像控制;
  4. 另外提供对绘制状态的控制,以及对绘制状态的转换;
  5. 通过requestAnimationFrame以及setInterval在Canvas上实现动画效果。如下图:


应用实践

Flyme主题编辑工具是提供给Flyme主题开发者在线编辑制作个性化主题的工具,支持实时预览编辑效果,并按要求保存所需编辑信息。点击这里的链接看效果:http://designer.meizu.com/resources/theme/html/index.html

应用一:文字图像绘制

在Flyme主题在线编辑工具中,需要提供给开发者实时的编辑预览,主要是显示手机的各个操作界面,包括文字和图标及一些背景和分隔线。

暂时考虑到两种实现方案:1. DIV+CSS+DOM操作;2. Canvas显示+JS绘制。

该应用有两个特征:1. 界面元素比较多,包括较多的图片、文字说明以及线条等其他形状;2. 开发者需要频繁替换图片并实时查看显示效果。

一方面,过多的DOM节点对页面性能会造成影响;另一方面,使用JavaScript绘制Canvas比DOM操作效率要高;我们使用Canvas方案来实现预览界面的显示和绘制。该部分的实现代码比较基础,不一一列举。主要应用到文本、图片、线条的绘制,部分预览效果图如下:

应用二:android .9.png图片绘制

Android .9.png介绍

Android .9.png图片在安卓中一般用作背景图片使用,通过图片最外层一个像素的黑边信息来确定拉伸区域和内容区域,除拉伸区域外的其他部分并不随图片放大而放大,而是保持原始大小,从而保证使用最小尺寸的图片完成任意大小内容的正确显示,确保不规则背景图任意缩放后不变形。

Android .9.png图示例结构图如下:左侧为缩放后的示意图;右侧为放大结构示意图,四周最外层黑色块为.9信息,两个绿色框(由于对应左边和上边的黑点只有一个像素,所以这里是两条线)的交集部分为缩放拉伸区域,另外两个黑色框的交集部分为内容显示区域。



Android .9.png绘制原理

以短信背景图气泡为例,首先了解.9.png图片的绘制原理,主要分三步:1. 获取到图片的.9信息(黑边的坐标位置),这样就可以确定拉伸区域和内容区域;2. 根据拉伸区域的坐标位置,正确的绘制图片(根据内容多少进行缩放);3. 根据内容区域的坐标位置,绘制内容到正确位置。

清楚了.9.png的显示原理,很快就可以找到解决方法:1. 通过Canvas的getImageData接口获取到.9.png的像素数据;2. 取其最外层一个像素点数据便可以找到对应黑边的位置;3. 再根据这些位置点截取原图的各块来进行对应绘制。我们使用的是jCanvas.js,具体实现细节可参考jcanvas.js中的draw方法源码。下面列出效果图(短信背景图和资讯背景图):

已编译的Android .9.png黑边信息获取

实际绘制过程中,还会遇到被编译过的.9.png,这些图不能简单的根据以上信息来取.9信息,而是从png图片结构分析着手取得,绘制的后续步骤完全一致,获取被编译后.9.png。图片.9信息的示例代码截图如下:


应用三:在线截屏

开发者在使用Flyme主题在线编辑工具打包时,需要系统为开发者新编辑的主题截屏生成主题预览图提供给用户预览,这样免去了开发者手工截屏上传的麻烦,提高系统智能性。

我们使用Canvas的toDataURL接口解决该需求,把在Canvas上绘制的内容转换成Base64格式,然后通过JSZip来将其存储为本地图片。由于内容图片都是经过开发者上传到了我们的服务器,因此也避免了截屏时候内容跨域安全问题。另外,为了保证预览图片的高质量和主题包的体积小,我们使用jpeg格式,采用.75的质量比例,示例代码截图如下:


应用四:形状截取

手机APP的icon颜色形状都设计的各不相同,为了保证桌面的整体美观协调,Flyme系统为第三方图标提供了可以应用默认形状的机制,使用后,第三方icon会被默认的形状截取,整体上保证了桌面的美观。

通过设置canvas global属性globalCompositeOperation值为destination-in,我们在Canvas上预览也达到同样的效果,该属性还提供了其他的可选值对应不同的截取方式,不一一列举。示例代码和效果图如下(以QQ和微博icon为例):



结语

以上便是Canvas在Flyme主题在线编辑工具中的应用分享。我们可以看到Canvas完成了很多传统web方式较难实现或不能实现的需求,或者在对比传统web方式上,更高效、便捷,应用下来感觉非常方便。

当然,Canvas功能强大远不止如此,在该项目中我们也计划后续更多的尝试应用Canvas来解决更多需求,例如使用Canvas动画来完成手机动态壁纸的预览以及手机各操作页面的动画,期待Canvas给我们带来更多惊喜!


以上是关于Canvas在Flyme主题的应用实践的主要内容,如果未能解决你的问题,请参考以下文章

第513期Canvas 最佳实践(性能篇)

MFC-UnionRect获得两个矩形的并集部分

Kafka实践:到底该不该把不同类型的消息放在同一个主题中?

[Canvas前端游戏开发]——FlappyBird详解

canvas应用一:简易时钟

Python 项目实践三(Web应用程序) 第三篇