Creating a Microsoft .NET Compact Framework-based Animation Control

Alex Yakhnin
IntelliProg, Inc.

March 2003

Applies to:
    Microsoft® .NET Compact Framework
    Microsoft Visual Studio® .NET 2003
    Microsoft Windows® CE .NET

Summary: Learn how to build a .NET Compact Framework-based animation control. (8 printed pages)

Download AnimationControl.msi.

Contents

Introduction
Creating a Storyline
Let's animate
Movie Time!
Conclusion

Introduction

During a recent project, one of the requirements was to show an animated GIF on a Microsoft® .NET Compact Framework Windows® Form. Version 1.0 of the .NET Compact Framework does not include the capability to display animated GIF files nor does it incorporate the ImageAnimator helper class from the full .NET Framework. The ImageAnimator class allows animation of an image that has time-based frames.

Even though it is possible to write C# code to read the animated GIF in GIF86a format, I have chosen a more simplistic and straightforward way to display animation in my program.

Creating a Storyline

If you open an animated GIF in the GIF editor of your choice, you will see that this file consists of a few images (frames) that follow each other:

Figure 1. Animation frames

These images are stored in a compressed format with information on the size, quantity and delay time between the frames. This information is read by the program that displays the animation.

Many of the GIF editors allow you to extract the image frames into a sequential "storyboard" of the frames:

Figure 2. Storyboard

I saved this into a single bitmap file, which I later converted into GIF format as it uses less memory within the .NET Compact Framework. Now I am going to show you how to use this image to create a .NET Compact Framework-based Animation control.

Let's animate

The way in which we're going to animate the bitmap is rather simple. It relies on the fact that when you're using an image in the .NET Compact Framework, you don't necessarily have to display the entire image you've loaded into memory. One of the overloaded methods of the graphics.DrawImage method accepts a Rectangle object as a parameter. This rectangle will be our way of framing each image in the storyboard bitmap. By moving the position of the frame rectangle, we can dynamically load a different section of the bitmap to be displayed on our form.

We add a new class AnimateCtl into a .NET Compact Framework project and derive this class from System.Windows.Forms.Control:

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Imaging;

public class AnimateCtl : System.Windows.Forms.Control
{
   // Add class implementation here
}

Let's add a public Bitmap property to the class that will be used to pass the bitmap from the client. Don't forget to declare a private member for the bitmap, for use within the class:

private Bitmap bitmap;
public Bitmap Bitmap
{
   get
   {
return bitmap;
   }
   set
   {
      bitmap = value;
   {
{

The control we create will draw the frames by using the DrawImage method of the Graphics object retrieved from the control:

private void Draw(int iframe)
{
      //Calculate the left location of the drawing frame
      int XLocation = iframe * frameWidth;

      Rectangle rect = new Rectangle(XLocation, 0, frameWidth, 
        frameHeight);

      //Draw image
      graphics.DrawImage(bitmap, 0, 0, rect, GraphicsUnit.Pixel);
}

This method accepts the current frame number that needs to be drawn. We then create the drawing rectangle by calculating its left position.

In order to implement the looping logic of the control I've chosen to utilize the System.Windows.Forms.Timer.

Although quite a few other options exist to provide the same functionality such as System.Threading.Timer or even create a separate thread, the usage of the System.Windows.Forms.Timer proved to be a more simple and convenient approach. Let's add the following code in the control's constructor:

public AnimateCtl()
{
   //Cache the Graphics object
   graphics = this.CreateGraphics();
   //Instantiate the Timer
   fTimer = new System.Windows.Forms.Timer();
   //Hook up to the Timer's Tick event
   fTimer.Tick += new System.EventHandler(this.timer1_Tick);
}

In the constructor we cache the Graphics object from the control's instance and create a new instance of the Timer. And we should not forget to hook into the Timer's Tick event. We are ready to insert the StartAnimation method that will actually start the animation:

public void StartAnimation(int frWidth, int DelayInterval, int LoopCount)
{

      frameWidth = frWidth;
      //How many times to loop
      loopCount = LoopCount;
//Reset loop counter
      loopCounter = 0;
      //Calculate the frameCount
      frameCount = bitmap.Width / frameWidth;
      frameHeight = bitmap.Height;
      //Resize the control
      this.Size(frameWidth, frameHeight);
      //Assign delay interval to the timer
      fTimer.Interval = DelayInterval;
      //Start the timer
      fTimer.Enabled = true;
}

This method accepts a few parameters that are very important for animation: frame width, delay interval and loop count.

And don't forget the looping logic:

private void timer1_Tick(object sender, System.EventArgs e)
{
         if (loopCount == -1) //loop continuously
         {
            this.DrawFrame();
         }
         else
         {
            if (loopCount == loopCounter) //stop the animation
               fTimer.Enabled = false;   
            else
               this.DrawFrame();
         }
}

private void DrawFrame()
{
      if (currentFrame < frameCount-1)
      {
         //move to the next frame
currentFrame++;
      }
      else
      {
         //increment the loopCounter
         loopCounter++;
         currentFrame = 0;
      }
      Draw(currentFrame);
}

In the code above in the timer1_Tick event we check the loopCount that keeps track of the how many loops have already been drawn and compare it to the loopCounter that we captured when the StartAnimation method was called.

Movie Time!

We are done with the AnimateCtl and ready to test it in action. As a first step we need to add the image file with "storyboard" into your project. We can do this by making this file an embedded resource or just by telling Visual Studio .NET 2003 to copy this file as a part of the project. Right click on the project in the solution explorer and select "Add Existing ItemÂ…" from the pop up menu. Browse to the image file and make sure that the Build Action property for this file is set to "Content".

Now let's insert the following into your Form's constructor:

public Form1()
{
//
      // Required for Windows Form Designer support
      //
      InitializeComponent();

      //Instantiate control
      animCtl = new AnimateCtl();
      //Assign the Bitmap from the image file
      animCtl.Bitmap = new Bitmap(@"/Program 
        Files/AnimateControl/guestbk.gif");
      //Set the location
      animCtl.Location = new Point(50, 50);
      //Add to control to the Form
      this.Controls.Add(animCtl);
}

In the code above we assign the Bitmap property of the animation control with the Bitmap object that was created from our image file.

Place two buttons on your form in the designer and add the code to their click events:

private void button1_Click(object sender, System.EventArgs e)
{
      animCtl.StartAnimation(92, 100, 3);
}


private void button2_Click(object sender, System.EventArgs e)
{
      animCtl.StopAnimation();
}

When running the project and tapping on the "Start Animation" button you should see the animation:

Figure 3. The final product

The amount of frames incorporated into the pseudo-animated GIF files could vary as well as the delay time between the frames. You would certainly need to adjust the DelayInterval parameter when calling the StartAnimation method for different animations.

In no way is this code considered in its final version. The AnimateCtl does not provide all required functionality that could be incorporated into animated GIF's. For example, AnimateCtl control can't handle a different delay times between the frames. Such as, you might want to show the very first frame a little bit longer than others. The code provided with this article is a good starting point for you to extend this control for your needs.

Please keep in mind that displaying a high-resolution graphics animation could impose a heavy load on the system resources. Be aware of the memory and resource constraints of the some of the devices you could be running this code on. Don't forget to test it thoroughly and make sure that your application is not hogging up all the memory or taking up all the processor time.

Conclusion

Although the .NET Compact Framework is a subset of the full .NET Framework developers still have the power to create compelling user interfaces which are more attractive to end users. By utilizing available GIF editor tools and the drawing capabilities of the .NET Compact Framework are able to display the animation in their Smart Device projects.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
animateControl v1.0.3 的功能特点: 1、完全兼容swiper的loop模式,完美支持swiper的嵌套。 2、完美支持animate.css,能够为页面中的任意元素添加动画。 3、完美支持为单个元素同时添加多个animate.css动画效果(无需进行HTML标签的嵌套),并且,可以随意控制这些动画效果的播放方式。 4、能够设置每一个动画效果的播放方式:同步播放、依次播放、循环播放。 5、能够设置每一个动画效果的动画类型:进入动画、表演动画、退出动画(在animate.css的源码中,opacity值从0至100的是进入动画,没有opacity属性的是表演动画。opacity值从100到0的是退出动画)。 6、实现了排版效果、动画效果、动画控制的完美分离,极大的提高了开发效率,能够在很短的时间内实现复杂的动画效果控制。 7、animateControl 不与swiper结合时,可对网页中的其它元素添加动画效果,并进行控制。 8、能够让不懂JS代码的人,经过简单的学习,就能快速的制作HTML5+CSS3动态微网页。 9、在 v1.0.3 中对整个核心代码进行了优化,大大提升了运行速率,使动画播放更流畅。 10、在 v1.0.3 中简化了所有参数的名称,让使用变得更加简单(用更少的代码,就能实现更复杂的效果)。 11、本次发布的动画控制器文件为min版,大大减少了文件的体积(下载解压后,文件位置在:js/swiper.animate.min.js)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值