拿了奖金怎么感谢老板:如何用HTML5 PhoneGap写个Path...

来源:百度文库 编辑:偶看新闻 时间:2024/04/25 00:40:16

如何用HTML5+PhoneGap写个Path出来?

Posted on December 30, 2011, 2:55 pm, by Easy, under WebForMobile.

最近Path这个应用很火爆,网上也出现了不少仿Path菜单的项目。即使在原生APP里边,Path的效果也是非常赞的。

我突然想,Web APP是不是也能做出类似Path那样的效果呢?于是就有了OPath这个项目,它的客户端部分是完全用PhoneGap+HTML5开发的。

坦白的讲,OPath比Path差得不是一点半点,但是比很多国产的原生应用体验要好,下边是演示视频。

http://you.video.sina.com.cn:8080/api/sinawebApi/outplayrefer.php/vid=68928297_1088413295_bx69HHcwCTPK+l1lHz2stqkP7KQNt6nkiWK8v1OnJwdcQ0/XM5GfatQF6CvfB9kEqDhAQpA2d/Yk3ho/s.swf

看完视频如果你对效果还满意的话,请接着往下看。我会和大家分享如何做一个这样的应用,包括整个前端(HTML5)和后端(PHP)。

这个项目也是在MIT协议下完全开源的(同样包括前端和后端),项目链接在文章最末尾。

PS:我只在iPod Touch4的iOS5系统上进行了测试,其他平台可能存在兼容性问题,需要自行测试和修复。

框架选择

PhoneGap就不用说了,有了它才能打包。我们要选的里边的前端框架。虽然之前我已经做了一个基于Jquery Mobile的Tab类模板,但是很明显,Path并没有采用Tab方式的菜单。

加上Path的控件都是自己的风格,所以自己渲染样式是逃不掉的,于是最后我选择了采用 Mobile-boilerplate  + iScroll4 来做这个项目。

Mobile-boilerplate

Mobile-boilerplate 是一个移动设备用的HTML5空白模板,它处理掉了非常多的兼容细节,比如viewport之类的。想了解详情的同学可以去看Mobile-boilerplate里边的注释,写得非常详细,还有相关issue的链接。

下载Mobile-boilerplate将解压出来的目录作为我们项目的根目录。Mobile-boilerplate已经包含了js和css目录,其中js下的libs里边有JQuery。

 

我首先在Mobile-boilerplate的模板基础上做了下登录页面,完成后的效果是这样的:

 

这个界面很简单,直接用CSS来实现就可以了,遵守Mobile-boilerplate的结构,在css/style.css中部200行左右的位置开始写入自己的css。

 

API接口的用户认证

接下来我们说说API方式用户认证的实现。在OPath项目中,我们采用用户名+密码换token,以后操作通过token鉴权的方式。

因为这种方式实现起来很方便。做PHP的同学都知道,PHP的Session机制是通过PHP SESSION ID来标示用户的,一般情况下这个标示通过Cookie存储在浏览器中。

我们的思路就是,将这个SESSION ID直接作为token就好啦。于是我们实现了get_token接口:

最核心的逻辑就这几行

session_start();
$token = session_id(); // 将Session id作为token
$_SESSION['token'] = $token; // 在Session中存储用户信息,供以后的操作认证使用。
$_SESSION['uid'] = $user['id'];
$_SESSION['name'] = $user['name'];
$_SESSION['email'] = $user['email'];
$_SESSION['level'] = $user['level'];

token在生成后,通过json格式返回给客户端。

客户端发送Ajax请求和解析参数

现在回到客户端这边来,当用户在登录页面填好账号后,我们需要将这些数据发送到服务器端,换取token。使用JQuery,这个很简单:

我们用 jQuery.parseJSON 解析返回的JSON数据,然后在登录正确后,将账号和token保存到本地。这里的kset其实是我写的一个快捷函数,它只是简单封装了下HTML5的LocalStorage。

function kset( key , value )
{
window.localStorage.setItem( key , value );
}

function kget( key )
{
return window.localStorage.getItem( key );
}

function kremove( key )
{
window.localStorage.removeItem( key );
}

LocalStorage里边的数据是持久化的,在应用被关闭后依旧存在。顺便说下,在Chrome和Safari的调试工具里边,Resource的Tab里边可以直接看到当前应用的LocalStorage还有IndexedDB的数据,不用去找其他的工具来查看这些值。这在调试应用的时候非常方便。

由于开发的应用是HTML5的,我首先会实现标准浏览器支持的部分,用Safari来进行调试;在最后才实现需要PhoneGap的部分,进行真机调试,这样可以节省很多调试时间。

Path主页面

Path的主页面很帅,实现细节也很多,我挑重点说。先放一张做完后的效果:

整体的布局上,其实我们可以直接沿用iScroll4的Demo,顶栏固定,将原来的Footer换成那个加号按钮就可以了。加号按钮的实现网上有CSS版本的,但是在Android上会出现严重的毛边,所以我直接用图片代替了。(Android上CSS圆角毛边的问题非常烦人,从这个地方可以一眼认出是否是WebAPP;iOS上则非常干净。)考虑到iPod Touch(我主要用这个)的杯具性能,我只简单做了个位置移动效果,觉得细节不够的同学可以自己加旋转和弹簧效果,用JQuery很容易做。说实话我觉得原版Path的那个加号按钮展开后很难按准 T__T

页面上方的Profile Picture部分放到iScroll的wrapper内,scroll最上方;下边的【加载更多】按钮,放到wrapper内,scroll最下方。均通过CSS指定固定高。

其他的布局细节可以查看path.html和style.css源文件。

Retina屏幕下的图片模糊问题

在iScroll的基础上,我很快就完成了主页面的布局,但是当我放到头像和图片后,杯具发生了!在Android上看的时候很正常,但是在Touch上图片会变得非常模糊。

按Mobile-boilerplate的viewport设定,整个页面宽度应该会变成 设备宽,对Touch来说就是320px。

很快我就意识到这应该是Retina屏幕带来的问题,因为Retina屏将标准屏幕一个像素改用4个像素显示,所以图像和周围的矢量图对比起来就模糊了。

而在Android上都采用一个像素显示,所以没有这个问题。

Google了下,网上的解决方案是这样的:

对于直接的图片应用,比如说

采用Retina屏幕的iOS设备会去找同目录下的 image@2x.png进行显示。

对于通过CSS引用的图片,比如说

则需要使用link标签按条件载入专用的CSS。

我测试了下,没有成功,更主要的还是觉得这个方案不爽,额外CSS什么的弱爆了。然后自己试出来了一个方案:

因为模糊的原理已经很清楚了,那么只要朝这个方向去想就行。

对于直接引用图片的情况,很容易想到解决方案:原本100*100的图片,我做成200*200,然后在img标签中指定高和宽为100*100。这样在Retina屏幕上可以按像素点进行显示,在其他屏幕的设备上,浏览器会自己先缩放后显示,测试效果很清晰。

通过CSS引用的情况比较麻烦,我睡了一觉才想出来,如果div#avatar要显示100*100的背景,那么将它的高和宽指定为200*200,配上200*200的背景图片,最后,Zoom:0.5。

其他页面需要注意的地方

其他页面基本上都是体力劳动了,Path Feed列表渲染时有两个需要注意的细节:

一是我们用的模板本身是用