风火轮 – 飞入动画效果

在动画基类的基础上,再实现各种动画效果,只需专注于各种逻辑实现,倒也不是太难的事。

今天实现第二个动画效果-飞入。

1.  飞入效果

代码很少,因为只需要确定不同时间的位置,故只重载BuildDisplayRect:

头文件

/**

*@class TCbwAnimationEffect_ FlyIn

*@brief 动画基类

*

* 处理飞入动画效果

*@author 陈斌文

*@version 1.0

*@date 2015-03-04

*@QQ: 282397369

*/

class TCbwAnimationEffect_FlyIn : publicTCbwAnimationEffect { // 飞入

typedefTCbwAnimationEffect inherited;

virtualTRect __fastcall BuildDisplayRect(OBJECTMAT * m);

public:

__fastcallTCbwAnimationEffect_FlyIn();

staticTCbwAnimationEffect * Build();

};

然后实现:

// ***************************** 飞入效果**************************************

__fastcallTCbwAnimationEffect_FlyIn::TCbwAnimationEffect_FlyIn()

:TCbwAnimationEffect() {

EffectType= cetFlyIn;

}

TCbwAnimationEffect *TCbwAnimationEffect_FlyIn::Build() {

returnnew TCbwAnimationEffect_FlyIn;

}

// BuildDisplayRect是根据索引确定相应位置

TRect __fastcallTCbwAnimationEffect_FlyIn::BuildDisplayRect(OBJECTMAT * m) {

TPointstartPos(m->LeftTopPosition.x, m->LeftTopPosition.y),

endPos(m->LeftTopPosition.x,m->LeftTopPosition.y);

if(cedFromBottom == EffectOptionType || cedFromLeftBottom == EffectOptionType ||

cedFromRightBottom== EffectOptionType) // 自底部

startPos.y= FHeight;

if(cedFromTop == EffectOptionType || cedFromLeftTop == EffectOptionType ||

cedFromRightTop== EffectOptionType) // 自顶部

startPos.y= -m->Mat.rows;

if(cedFromLeft == EffectOptionType || cedFromLeftBottom == EffectOptionType ||

cedFromLeftTop== EffectOptionType) // 自左侧

startPos.x= -m->Mat.cols;

if(cedFromRight == EffectOptionType || cedFromRightBottom == EffectOptionType ||

cedFromRightTop== EffectOptionType) // 自右侧

startPos.x= FWidth;

intx = startPos.x + (endPos.x - startPos.x) * (FCurrentIndex + 1)

/FPeriodLength;

inty = startPos.y + (endPos.y - startPos.y) * (FCurrentIndex + 1)

/FPeriodLength;

TRectresult(x, y, x + m->Mat.cols, y + m->Mat.rows);

returnresult;

}

// ***************************** 飞入效果**************************************

2.  界面处理

现在到了处理界面的时候,因为在飞入效果中,还需要再设定效果选项。

在选择对象的时候,可以再顺带判断是否有动画项,简化处理,当只有一个动画项的时候再进行编辑处理。

TCbwAnimationEffect* FCurrentEffectItem;

vector<TCbwAnimationEffect*> FAllAnimationEffects;

vector<TCbwAnimationEffect*> __fastcall GetSelectEffectItems();

////////////////////////////////////////////////////////////////////////////////////////

vector<TCbwAnimationEffect *>__fastcall TForm::GetSelectEffectItems() {

vector<TCbwAnimationEffect*> selectedEffectItems;

FCurrentEffectItem= NULL;

for(int i = 0; i < cSelectedObjects->MetaNumber; ++i) {

TCbwObject* object = cSelectedObjects->Meta(i);

CBW_ITERATOR(vector<TCbwAnimationEffect*>, FAllAnimationEffects)

if((*it)->ContainsObject(object)){

selectedEffectItems.push_back(*it);

break;

}

}

if(selectedEffectItems.size()== 1)

FCurrentEffectItem= selectedEffectItems[0];

returnselectedEffectItems;

}

再通过SelectAnimationEffect(FCurrentEffectItem)完成界面按钮的控制。

再深入研究下PPT中的动画项效果选项,发现其有两部分:固定的序列项,即作为一个对象、整批发送、按段落三个选项,其余为各动画项相应的属性项。

                  

因此,在基类中加入效果选项属性,100以内为相应选项,100: 作为一个对象,101:整批发送,102:按段落

intEffectOptionType; // 效果选项,

这样可以兼容所有效果选项(应该不会超过100项的吧)

而各个类型的效果选项,可以硬编码实现,也可以配置实现。从灵活角度,当然是配置实现了,后续也有利于国际化语言包。

void __fastcall TForm::SelectAnimationEffect(TCbwAnimationEffect* effectItem) {

intindex = -1;

if(effectItem)

index= effectItem->EffectType - 1;

for(int i = 0; i < Gallery_FlashEffect->GalleryGroups->Count; ++i) { // 确保只添加一次

TdxRibbonGalleryGroup* group = Gallery_FlashEffect->GalleryGroups->Items[i];

for(int j = group->Items->Count - 1; j >= 0; --j) {

TdxRibbonGalleryGroupItem* item = group->Items->Items[j];

boolshouldBeSelected = (item->ImageIndex == index);

if(item->Selected!= shouldBeSelected)

item->Selected= shouldBeSelected;

}

}

boolhasItemFlag = (effectItem != NULL);

Button_Flash_Preview->Enabled= hasItemFlag;

Button_Flash_Effect->Enabled= hasItemFlag;

Button_Flash_Effect->ItemLinks->Clear();

if(!TGlobalVariables::XmlForStringResource|| !effectItem)

return;

CbwXmlNode* effectNode =TGlobalVariables::XmlForStringResource->RootNode->NodeByName("Effect",true);

if(!effectNode)

return;

UnicodeStringbasePath = THelper::File::GetApplicationPath() +effectNode->AttributeValueByName("path");

UnicodeStringcn = effectItem->ClassName();

UnicodeStringprefix = "TCbwAnimationEffect_";

cn.Delete(1,prefix.Length());

CbwXmlNode* destNode = effectNode->NodeByAttribute("name", cn);

if(destNode){

for(intoptionIndex = 0; optionIndex < destNode->ElementNumber; ++optionIndex) {

CbwXmlNode* optionNode = destNode->Elements(optionIndex);

TdxBarSeparator* sep = new TdxBarSeparator(Application->MainForm);

Button_Flash_Effect->ItemLinks->Add()->Item= sep;

sep->Caption= optionNode->AttributeValueByName("caption");

for(inti = 0; i < optionNode->ElementNumber; ++i) {

CbwXmlNode* itemNode = optionNode->Elements(i);

TdxBarButton* button = TCbwDevExp::CreateMenuItem(Button_Flash_Effect,

actEffect,itemNode->AttributeValueByName("caption"), i, true, false,

basePath+ itemNode->AttributeValueByName("glyph"));

}

}

}

CbwXmlNode* baseNode = effectNode->NodeByName("optionItem");

if(baseNode){

TdxBarSeparator* sep = new TdxBarSeparator(Application->MainForm);

Button_Flash_Effect->ItemLinks->Add()->Item= sep;

sep->Caption= baseNode->AttributeValueByName("caption");

for(inti = 0; i < baseNode->ElementNumber; ++i) {

if(i&& effectItem->RelativeObjectNumber() == 1) // 单个对象,只有一项

break;

CbwXmlNode* itemNode = baseNode->Elements(i);

TdxBarButton* button = TCbwDevExp::CreateMenuItem(Button_Flash_Effect,

actEffect,itemNode->AttributeValueByName("caption"), 100 + i, true, false,

basePath+ itemNode->AttributeValueByName("glyph"));

}

}

}

配置文件大体如下,实现到哪个效果,再相应添加配置项:

从网上再找相应的图标,放到res\effect目录下

再加上相应的按钮处理

void __fastcall TForm::Button_Flash_PreviewClick(TObject*Sender)

{

PreviewCurrentEffect();

}

//---------------------------------------------------------------------------

void __fastcall TForm::actEffectExecute(TObject*Sender)

{

int tag =THelper::Util::GetActionTag(Sender);

ChangeCurrentEffect(tag);

}

//---------------------------------------------------------------------------

void __fastcall TForm::ChangeCurrentEffect(inttype) {

if(!FCurrentEffectItem)

return;

FCurrentEffectItem->EffectOptionType= type;

PreviewCurrentEffect();

}

void __fastcall TForm::PreviewCurrentEffect(){

if(!FCurrentEffectItem)

return;

FCurrentEffectItem->RefreshAllObjects();

FCurrentEffectItem->SetBounds(ScrollBox->Width,ScrollBox->Height);

Graphics::TBitmap* bitmap = new Graphics::TBitmap; // bitmap将用于显示

bitmap->PixelFormat= pf24bit;

bitmap->Width= ScrollBox->Width;

bitmap->Height= ScrollBox->Height;

RECTdisplayRect = Rect(ScrollBox->HorzScrollBar->Position,

ScrollBox->VertScrollBar->Position,ScrollBox->HorzScrollBar->Position +

ScrollBox->Width,ScrollBox->VertScrollBar->Position +

ScrollBox->Height);

Graphics::TBitmap* FPreviewBitmap = new Graphics::TBitmap;

FPreviewBitmap->PixelFormat= pf24bit;

FPreviewBitmap->Width= PaintBox->Width;

FPreviewBitmap->Height= PaintBox->Height;

TCanvas* canvas = FPreviewBitmap->Canvas;

canvas->Rectangle(0,0, 10000, 10000);

CBW_ITERATOR(CbwObjects,Objects)(*it)->Canvas = canvas;

CBW_ITERATOR(CbwObjects,Objects) {

TCbwObject* object = *it;

if(!CanObjectBeVisible(object) || !object->CanContinueWithRect

(displayRect,CBW_CONTINUE_DRAW) || object->Selected)

continue;

object->Draw();

}

PostPaint(canvas);

bitmap->Canvas->CopyRect(Rect(0,0, bitmap->Width, bitmap->Height), canvas,

displayRect);

CBW_ITERATOR(CbwObjects,Objects)(*it)->Canvas = PaintBox->Canvas;

TRestoreApplicationCurrentStatus(TGraphApp::CurrentStatus, cfsAnimation);

BYTE* backData = THelper::Graphics::GetBitmapData(bitmap);

FCurrentEffectItem->First();

while(!FCurrentEffectItem->Eof){

FCurrentEffectItem->Draw(ScrollBox->Handle,backData, bitmap->Width, bitmap->Height);

FCurrentEffectItem->Next();

//               THelper::Util::Delay(40);

Sleep(10);

}

deletebackData;

deleteFPreviewBitmap;

deletebitmap;

}

这下可以看到效果:

发现一个小小问题,点击各效果选项,效果选项的按钮图标没有相应改变。再花2分钟应该能解决。

以后每天没事的时候,实现一两个PPT动画效果,貌似一个月能实现完成。

在这之后,再实现潮流、跑马灯等效果,可以控制LED屏了,值得搞下。

时间: 2024-08-07 08:38:01

风火轮 – 飞入动画效果的相关文章

jQuery实现加入购物车飞入动画效果

当您在电商购物网站浏览中意的商品时,您可以点击页面中的“加入购物车”按钮即可将商品加入的购物车中.本文介绍借助一款基于jQuery的动画插件,点击加入购物车按钮时,实现商品将飞入到右侧的购物车中的效果. HTML 首先载入jQuery库文件和jquery.fly.min.js插件. <script src="jquery.js"></script> <script src="jquery.fly.min.js"></scri

JQuery模拟实现天猫购物车动画效果

测试程序源代码下载地址:源码 一.功能描述: 1.点击购买按钮,模拟抛物线将物品弹到购物车里: 2.购物车添加物品后,显示+1动画: 效果图如下: 实现如下: 1.导入jquery相关的包: <script type="text/javascript" src="jquery-2.1.1.min.js"></script> <script src="jquery.fly.min.js"></script&

css3 动画效果与公司框架简易动画的差异

先看一下该网站的效果 http://2014guangzhouchezhan.dongfeng-citroen.com.cn/mobile/ 该站里面的动画效果由简易动画与css3动画2种方式混合达到的. 一.特点与差异. 1.简易动画直接通过对dom元素追加class类名与属性参数 像这样 <img src="images/page02/text01.png"  class="text01 cmn-animate" cfg="{action:[{s

风火轮 – 动画效果

风火轮越来越有广告范,之前实现的素材导入功能已能解决50%的用户需求,即可以拖入现成的动画.视频及图片素材,效果见QQ空间之前的某篇日志. 从进化发展角度来看,现在的很多产品,纯硬件的竞争已是薄利见血,软件功能提升才是王道. 所以,软件实现得加强.电子黑板如此,风火轮也如此. 准备实现动画效果. 闭门造车是白手起家的最脑残做法,所以先放眼成熟产品,看哪些功能与UI可以借鉴. 做素材,一般会选取FLASH.Photoshop,而动画效果,PPT是大家耳熟能详的. 仔细研究一下,决定采用PPT的界面

风火轮 –动画效果:浮入与劈裂

今天花了一个半小时,实现两个动画效果:浮入与劈裂. 浮入效果 头文件 enum CbwFloatDirection { // 浮入方向 cfdUp = 0, // 上浮 cfdDown = 1 // 下浮 }; /** * @class TCbwAnimationEffect_ FloatIn * @brief 动画基类 * * 处理浮入动画效果 * @author 陈斌文 * @version 1.0 * @date 2015-03-05 * @QQ: 282397369 */ class T

风火轮 –动画效果:擦除、形状、轮子、随机线条、翻转远近、缩放、旋转、弹跳效果

今天再花了一个白天时间,把PPT动画的进入效果全部实现. 浮入效果 头文件 class TCbwAnimationEffect_Erase : public TCbwAnimationEffect { // 擦除 virtual void __fastcall BuildMaskMat(cv::Mat& destMat, cv::Mat& srcMat, TRect displayRect); public: __fastcall TCbwAnimationEffect_Erase();

风火轮 – 动画效果:浮入与劈裂

今天花了一个半小时,实现两个动画效果:浮入与劈裂. 1.  浮入效果 头文件 enum CbwFloatDirection { // 浮入方向 cfdUp= 0, // 上浮 cfdDown= 1 // 下浮 }; /** *@class TCbwAnimationEffect_ FloatIn *@brief 动画基类 * * 处理浮入动画效果 *@author 陈斌文 *@version 1.0 *@date 2015-03-05 *@QQ: 282397369 */ class TCbwA

Android应用系列:仿MIUI的Toast动画效果实现(有图有源码)

前言 相信有些人用过MIUI,会发现小米的Toast跟Android传统的Toast特么是不一样的,他会从底部向上飞入,然后渐变消失.看起来效果是挺不错的,但是对于Android原生Toast是不支持自定义动画的.那这个效果到底是怎么实现的呢?下面就来告诉你.... 分析 如果园友看过我的另一篇博客<Android:剖析源码,随心所欲控制Toast显示>,就会知道其实原生Toast就是infate出一个View实例,然后将其加载到WindowManager上面来达到显示效果.我们很多人都知道W

Android应用系列:仿MIUI的Toast动画效果实现

前言 相信有些人用过MIUI,会发现小米的Toast跟Android传统的Toast特么是不一样的,他会从底部向上飞入,然后渐变消失.看起来效果是挺不错的,但是对于Android原生Toast是不支持自定义动画的.那这个效果到底是怎么实现的呢?下面就来告诉你.... 分析 如果园友看过我的另一篇博客<Android:剖析源码,随心所欲控制Toast显示>,就会知道其实原生Toast就是infate出一个View实例,然后将其加载到WindowManager上面来达到显示效果.我们很多人都知道W