clutter-1.0 动画效果学习

原创 2012年03月23日 15:14:52

一.ClutterAnimation

这个类实现的功能比较简单,而且,最主要是,进行动画演示后,actor的外观不会回归原来的位置,必须要经过时间轴反转变回原来的的状态.

二.ClutterAnimator:

比较喜欢clutter_animator_set函数,可以指定起点,过程关键点,以及终点,而且每次都可以按照这个路径运行效果,对于一些单向重复的过程很有用.


三.下面是一个例子.

#include <stdlib.h>
#include <clutter/clutter.h>

/*actor队列*/
GQueue *queue;  
/*actor结构体*/
typedef struct Item
{
	ClutterActor *actor;
	ClutterAnimator *move_c2r_animator;
	ClutterAnimator *move_c2l_animator;
}Item;
/*定义方向枚举*/
typedef enum direction 
{
	right, 
	left
}direction;

/*定义全局方向亦是,默认从右移入,从左移出*/
direction g_direct = left;

/*定义动画持续时间*/
#define DURATION	500

/*
 * 从中间向右移动画开始的回调函数
 */
static void
_to_c2r_animation_started_cb (ClutterTimeline *timeline, 
		gpointer user_data);

/*
 * 从中间向左移动画开始的回调函数
 */
static void
_to_c2l_animation_started_cb (ClutterTimeline *timeline, 
		gpointer user_data);

/*
 * 从中间向右移动画结束的回调函数
 */
static void
_to_c2r_animation_done_cb (ClutterAnimator *animator,
		gpointer user_data);

/*
 * 从中间向右移动画结束的回调函数
 */
static void
_to_c2l_animation_done_cb (ClutterAnimator *animator,
		gpointer user_data);

/*
 * 设置actor的一些初始信息
 * 初始时actor通过把位置设置在stage外使actor不可见.
 */
	static void 
set_actor_property (ClutterActor *actor)
{

	clutter_actor_set_size (CLUTTER_ACTOR (actor), 500, 400);
	clutter_actor_set_position (CLUTTER_ACTOR (actor), -500, -400);
	clutter_actor_hide (CLUTTER_ACTOR (actor));
}

/*
 *将一个从中间向左移动画和一个从中间向右移动画与一个actor联系起来.
 *并为每个动画的时间线添加开始和结束的回调函数.
 *注意: clutter_animator_set的参数不能将gfloat与int,不然容易出现Segment fault.
 */
	static void 
bind_animation_to_item (Item *item)
{
	gfloat stage_w;
	gfloat actor_w;
	ClutterTimeline *timeline;

	stage_w = clutter_actor_get_width (CLUTTER_ACTOR (clutter_stage_get_default ()));
	actor_w = clutter_actor_get_width (item->actor);

	item->move_c2r_animator = clutter_animator_new ();
	clutter_animator_set_duration (item->move_c2r_animator, DURATION);

	clutter_animator_set (item->move_c2r_animator,
			item->actor, "x", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 150.0,
			item->actor, "y", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 200.0,
			item->actor, "x", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, stage_w + actor_w,
			item->actor, "y", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, 200.0,
			item->actor, "scale-x", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 1.0,
			item->actor, "scale-y", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 1.0,
			item->actor, "scale-x", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, 0.1,
			item->actor, "scale-y", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, 0.1,
			item->actor, "rotation-angle-y", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 0.0,
			item->actor, "rotation-angle-y", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, 180.0,

			NULL);

	timeline = clutter_animator_get_timeline (item->move_c2r_animator);
	g_signal_connect (timeline, "completed",
			G_CALLBACK (_to_c2r_animation_done_cb),
			item);
	g_signal_connect (timeline, "started",
			G_CALLBACK (_to_c2r_animation_started_cb),
			item);

	item->move_c2l_animator = clutter_animator_new ();
	clutter_animator_set_duration (item->move_c2l_animator, DURATION);

	clutter_animator_set (item->move_c2l_animator,
			item->actor, "x", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 150.0,
			item->actor, "y", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 200.0,
			item->actor, "x", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, -actor_w,
			item->actor, "y", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, 200.0,
			item->actor, "scale-x", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 1.0,
			item->actor, "scale-y", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 1.0,
			item->actor, "scale-x", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, 0.1,
			item->actor, "scale-y", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, 0.1,
			item->actor, "rotation-angle-y", CLUTTER_EASE_IN_OUT_CUBIC,
			0.0, 0.0,
			item->actor, "rotation-angle-y", CLUTTER_EASE_IN_OUT_CUBIC,
			1.0, 180.0,
			NULL);

	timeline = clutter_animator_get_timeline (item->move_c2l_animator);
	g_signal_connect (timeline, "completed",
			G_CALLBACK (_to_c2l_animation_done_cb),
			item);
	g_signal_connect (timeline, "started",
			G_CALLBACK (_to_c2l_animation_started_cb),
			item);
}

/*
 * 从中间向右移动画开始的回调函数
 */
	static void
_to_c2r_animation_started_cb (ClutterTimeline *timeline, 
		gpointer user_data)
{
	Item *item = (Item *)user_data;
	if (item == NULL)
		return;

	clutter_actor_show (item->actor);
}

/*
 * 从中间向左移动画开始的回调函数
 */
	static void
_to_c2l_animation_started_cb (ClutterTimeline *timeline, 
		gpointer user_data)
{
	Item *item = (Item *)user_data;
	if (item == NULL)
		return;

	clutter_actor_show (item->actor);
}

/*
 * 从中间向右移动画结束的回调函数
 */
	static void
_to_c2r_animation_done_cb (ClutterAnimator *animator,
		gpointer user_data)
{
	Item *item = (Item *)user_data;
	g_assert (item!= NULL);

	if (g_direct == right)
		g_queue_push_tail (queue, item);
}

/*
 * 从中间向右移动画结束的回调函数
 */
	static void
_to_c2l_animation_done_cb (ClutterAnimator *animator,
		gpointer user_data)
{
	Item *item = (Item *)user_data;
	g_return_if_fail (item != NULL);

	if (g_direct == left)
		g_queue_push_tail (queue, item);
}

/*
 *将当前居中原比例显示的一项item调至最底部,也即是从当前画面移除
 *变成等待队列的最后一项
 *注意:	如果移动方向是从左向右: 
 *即当前item的从中间移动到右边的动画有效,且:
 * 此item的从中间到右的item动画正向
 *否则, 当前item的从中间移到左边的动画有效,且:
 *	此item的从中间到左的item动画正向
 *
 */
raise_item_to_bottom (Item *item)
{
	ClutterTimeline *timeline;

	if (item == NULL)
		return;

	if (g_direct == left)
	{
		timeline = clutter_animator_get_timeline (
				item->move_c2l_animator);
		clutter_timeline_set_direction (timeline,CLUTTER_TIMELINE_FORWARD);
		clutter_animator_start (item->move_c2l_animator);
	}
	else
	{

		timeline = clutter_animator_get_timeline (
				item->move_c2r_animator);
		clutter_timeline_set_direction (timeline, CLUTTER_TIMELINE_FORWARD);

		clutter_animator_start (item->move_c2r_animator);
	}
}

/*
 *将等待显示的第一项item调至最顶部,也即是移到到显示居中位置
 *注意:	如果移动方向是从左向右: 
 *即当前item的从中间移动到左边的动画有效,且:
 * 此item的从中间到左的item动画反向
 *否则, 当前item的从中间移到右边的动画有效,且:
 *	此item的从中间到右的item动画反向
 */
	static void 
raise_item_to_top (Item *item)
{
	ClutterTimeline *timeline;

	if (item == NULL)
		return;

	if (g_direct == left)
	{
		timeline = clutter_animator_get_timeline (
				item->move_c2r_animator);
		clutter_timeline_set_direction (timeline, CLUTTER_TIMELINE_BACKWARD);
		clutter_animator_start (item->move_c2r_animator);
	}
	else
	{
		timeline = clutter_animator_get_timeline (
				item->move_c2l_animator);
		clutter_timeline_set_direction (timeline, CLUTTER_TIMELINE_BACKWARD);

		clutter_animator_start (item->move_c2l_animator);
	}
}
/*
 *处理键盘事件.
 *如果当然有有动画正在播放,则忽略键盘事件
 *如要是向左方向键,说明actor从右边移入,从左边移出
 *如果是向右方向键,说明actor从左边移入,从右边移出
 */
	static gboolean
_on_stage_key_cb (ClutterActor *actor, 
		ClutterEvent *event,
		gpointer user_data)
{
	static Item *curr_item = NULL;
	GQueue *queue = (GQueue *)user_data;

	if (curr_item != NULL)
	{
		if (clutter_timeline_is_playing (clutter_animator_get_timeline
					(curr_item->move_c2r_animator)))
			return;
		if (clutter_timeline_is_playing (clutter_animator_get_timeline
					(curr_item->move_c2l_animator)))
			return;
	}

	guint keyval = clutter_event_get_key_symbol (event);

	switch (keyval)
	{
		case CLUTTER_Left:
			g_direct = left;
			break;
		case CLUTTER_Right:
			g_direct = right;
			break;
		default:
			return;
	}

	raise_item_to_bottom (curr_item);
	curr_item = g_queue_pop_head (queue);
	raise_item_to_top (curr_item);
}

/*
 * main函数.
 * 缺少一些资源释放
 * 编译命令: gcc *.c -o main `pkg-config --cflags --libs --clutter-1.0`
 * */
int main (int argc, char *argv[])
{
	gfloat x, y;
	ClutterActor *stage;
	ClutterColor stage_color = {0x00, 0x00, 0x00, 0xff};
	ClutterColor rect_color = {0xff, 0x00, 0x00, 0xff};
	queue = g_queue_new ();

	clutter_init (&argc, &argv);

	stage = clutter_stage_get_default ();
	clutter_stage_set_title (CLUTTER_STAGE (stage), "Hello");
	clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);
	clutter_actor_set_size (stage, 800, 800);

	int i;
	for (i = 0; i < 5; i++)
	{
		Item *item = (Item *)malloc (sizeof (Item));
		item->actor = clutter_rectangle_new_with_color (&rect_color);
		set_actor_property (CLUTTER_ACTOR (item->actor));
		clutter_container_add_actor (CLUTTER_CONTAINER (stage), CLUTTER_ACTOR (item->actor));
		bind_animation_to_item (item);
		g_queue_push_tail (queue, item);
	}

	/*添加键盘事件*/
	g_signal_connect (stage, "key-press-event", G_CALLBACK (_on_stage_key_cb), queue);

	clutter_actor_show (stage);

	clutter_main ();

	return EXIT_SUCCESS;

}


相关文章推荐

opengl学习笔记4-动画效果

  • 2013年09月26日 22:04
  • 797KB
  • 下载

一步一步学习 JQuery (八) JQuery 的动画效果

常用方法 hide(): 在 HTML 文档中, 为一个元素调用 hide() 方法会将该元素的 display 样式改为 none. 代码功能同 css(“display”, “none”); sh...

iOS学习之自定义弹出UIPickerView或UIDatePicker(动画效果)

前面iOS学习之UIPickerView控件的简单使用 用到的UIPickerView弹出来是通过 textField.inputView = selectPicker;   textField.in...

jquery学习之tab切换及动画效果,涉及animate(),siblings()

tab01

jQuery学习之旅 Item9 动画效果

1、元素的显示和隐藏 display:none; 隐藏 display:block; 显示 简单显示和隐藏方法 a) show() 显示 b) hide() 隐藏 c) t...

android 动画效果学习

Android 平台提供了两类动画。 一类是Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果(旋转、平移、放缩和渐变)。 第二类就是 Frame动画,即顺序的播放事先做好的图像,与...

Android开发学习SurfaceView显示动画效果

一、基础知识: SurfaceView继承自View,View负责在主线程中更新动画,而SurfaceView是在一个新线程中更新动画。   SurfaceView类的主要方法: ...

windows phone开发学习--storyboard的动画效果

在windows phone应用程序的开发中,比较炫的动画效果能增加用户的体验感,初级的如平移和翻转这些动画,高级的就涉及到游戏中的一些动画了。目前做的这个应用正好需要这么一个效果,于是学习了一下如何...

jQuery学习笔记(4)——动画效果

jQuery动画效果jQuery提供了较为丰富和简单的动画效果,但是效果是为了可用性服务的,如果简单的堆砌效果,往往适得其反。jQuery的动画效果: 隐藏/显示 淡入/淡出 滑动 自定义动画 显示和...

ios开发动画效果的基本学习介绍

前言:在开发APP中,我们会经常使用到动画效果。使用动画可以让我们的APP更酷更炫,最重要的是优化用户体验,但取决于动画的质量。像QQ、微信、新浪微博等APP,动画效果就很好了,至少我很喜欢它们的动画...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:clutter-1.0 动画效果学习
举报原因:
原因补充:

(最多只允许输入30个字)