|
iPhone 桌面特效设计和实现 转载请注明出处: http://www.pengliu.org/proj/iphone_desktop.html 简介苹果公司的 iphone 手机得到业界好评,由于工作需要,我对桌面特效的实现做了深 入研究,现作简单总结。本文研究的特效包括:
iphone 桌面的截图:
实现思路基于动画原理实现抖动和缩放动画实际是在一定的时间间隔内顺序显示一系列的相关图片实现的,由于人的视 觉有惯性,当时间间隔足够短时,就会看到物体动起来。抖动和缩放都可以基于 动画的原理实现:
图标的拖动拖动的实现比较简单,只需随鼠标不断改变图标的位置并实时显示即可。有一点 要注意,当在新的位置绘制图片时,要把原来的擦掉,否则就会出现“贪吃蛇”现象,造 成混乱。 Alpha 混合半透明采用 Alpha 混合来实现,即将拖动的图标绘制在一个带 Alpha 混合的层 上,然后将这个层 bilbit 到绘制层即可。 为了屏蔽背景色,可能还会用到 color key。 桢数据的管理根据上述分析,为了实现一个图标的抖动和缩放,我准备 3 桢图由于抖动,2 桢图用于缩放,当图标很多时,图片数据就会很多,管理是个问题。为了便于管 理,并且考虑到绘制速度问题,我采用了矩阵的方式来组织。 假设有 N 个图标,每个图标有 M 桢图。在程序启动时,把所有图片读到一块 mem dc 中排列成一个 N 行 M 列的矩阵。一个图标的 M 桢图放在同一行中,有 多少个图标就有多少个行。 下图是一个 5 桢 3 个图标的数据布局图:
绘制方法考虑到绘制速度和 Alpha 混合的需要,我设置了 4 个 dc:
绘制的伪代码如下:
for (i = 0; i < NR_PANEL; i++) {
if (blending)
bilbit (texture_dc, frame_id , icon_id, W, H ,
blending_dc, 0, 0, 0);
else
bilbit (texture_dc, frame_id, icon_id, W, H,
drawing_dc, 0, 0, 0);
}
bilbit (blending_dc, 0, 0, W, H, drawing_dc, 0, 0, 0);
bilbit (drawing_dc ,0, 0, W, H, screen_dc, 0, 0, 0);
针对每个 panel,首先从 texture_dc 取祯数据,bilbit 到 drawing_dc 上;若是拖动的桢 bilbit 到 blending_dc 上;当所有 panel 绘 制完毕后,将 blending_dc bilbit 到 drawing_dc 上;所有的 panel 和绘制 完后,将 blending_dc 的数据 bilbit 到 drawing_dc ,最后把 drawing_dc 的数据 bilbit 到 screen_dc,显示出来。 同步动画的计时和实时重绘由一个定时器 (timer) 来控制,没过一定的时间间隔, 就会产生一个 TIMER 消息,此时屏幕所有的图标的要重新绘制一次,绘制完毕 后要修改当前桢,为一次绘制作准备。 数据结构IPPANELIPPANEL 指的是一个 panel 容器,它是图标的容器,每个图标都显示在一个 panel 中。该结构定义了一个区域和图标 id 。
typedef struct _IPPANEL {
RECT rect;
int icon_id;
} IPPANEL;
IPANIMATIONIPANIMATION 定义了一个动画,它定义了动画的起点、终点,起始祯和终止祯
typedef struct _IPANIMATION {
POINT start_point;
POINT end_point;
int start_frame_id;
int end_frame_id;
} IPANIMATION;
IPICONIPICON 定义了一个图标,给出了图标的当前显示位置,当前要显示的桢,动作 类型和动画信息。 在这里定义并处理了三种动画类型,一是抖动,二是放大,三是滑动。
typedef struct _IPICON {
int x;
int y;
int type;
int cur_frame;
IPANIMATION animation;
int panel_id;
} IPICON;
核心控制流程IPICON 是核心数据结构,一个 IPICON 代表一个 ICON 对象;Timer 是同步全 局的控制中心,它每隔一个 interval 会重绘所有图标。
case TIMER:
/* 擦除屏幕 */
SetBrushColor (drawing_dc, COLOR_black);
FillBox (drawing_dc, 0, 0, SCREEN_W, SCREEN_H);
for (i = 0; i < NR_PANEL; i++) {
switch (incon.type) {
case AM_NORMAL:
... swapping...
break;
case AM_ZOOMIN:
... Zoom in ...
break;
case AM_SLIDE:
... slide ...
break;
}
}
bilbit (blending_dc, 0, 0, W, H, screen_dc, 0, 0, 0);
bilbit (drawing_dc, 0, 0, W, H, screen_dc, 0, 0, 0);
其它 |