Click here to Skip to main content
Click here to Skip to main content

A Panel control that you can flip over

, 20 Mar 2007
Rate this:
Please Sign up or sign in to vote.
This article shows how to create a 3D style effect using only GDI+ image manipulations
Screenshot - flippanel.gif

Introduction

I bought a MacBook Pro a while ago, and I found that there are a lot of interesting visual effects used in the software that comes pre-loaded. One of these I really liked was in the Dashboard application, where you can click on an area of a window and it flips over to show you the available settings for the applet. In an application I'm working on, I thought it'd look good to have a Panel control that I can add a control to and have it flip over to show a control I've added to the back.

Background

My first approach to implementing this idea was to use WPF since it has 3D built in. However, the sample code I found for putting standard controls on a 3D surface really didn't give the image quality I was looking for. So, I decided to go with my own implementation using only GDI+.

How to Use the Code

The code is pretty simple to use in your application. Here is the code I used in the sample application to set up the FlipPanel:

// Add a TextBox to the front
TextBox t1 = new TextBox();
t1.Multiline = true;
t1.Size = new Size(201, 201);
t1.Text = "this is the front";
flipPanel1.Front = t1;
// Add a TextBox to the back
TextBox t2 = new TextBox();
t2.Multiline = true;
t2.Size = new Size(201, 201);
t2.Text = "this is the back";
flipPanel1.Back = t2;
// Set the animation speed
flipPanel1.TimerInterval = 5;

Then, you can just call flipPanel1.Flip() to initiate a flip action.

How it Works

The basic method that this code uses is as follows:

  1. Paint the front and back controls to separate bitmaps
  2. Calculate the shading for each vertical line of the forward-facing image (UPDATE! This doesn't really create the effect I want! )
  3. Draw the forward-facing image to the screen, using the overloaded Graphics.DrawImage() that can skew images. I use this method to automatically calculate a simple perspective effect.

Let's Get Some Perspective

Thanks to the suggestion of mcstarSatx, I realized that what really gives the impression of 3D is perspective! Not shading so much! I think I was hung up on shading because of some research I did in school about shape from shading algorithms. In any case, I added some code to do a simple perspective effect, and it looks an order of magnitude better. I left in the option of using shading, but it really doesn't add much to the visual effect besides slowing it down...

So, let's figure out how perspective works. If you take a sheet of paper, hold it up in front of your face (orthogonally), all four corners look like they're essentially the same distance from you. Now, turn the paper 45 degrees from your face. Where are those same four corners? The ones farther away from you look like they're farther away! They don't look much darker! That's why I was a blockhead for thinking shading was the most important factor in creating a 3D effect.

A Simple Way to Create Perspective

Perspective transforms really aren't the easiest to calculate, especially when you're constrained to only use GDI+. So, to get something working quickly, since I've got other things to do, I decided to just use a simple shear operation, which you even get for free from Graphics.DrawImage(). First, in addition to state variables which represent the x values of the left and right corners, I keep track of a variable that represents the y value of the top of the control. Then, during each time step of the animation, I can just increment or decrement that value to create an image shear.

PointF[] destPoints = { new PointF(m_X1, 0), 
new PointF(m_X2, m_Y1),
new PointF(m_X1, this.Height) };
// m_Y1 is the variable that determines the perspective
e.Graphics.DrawImage(m_PageA, destPoints);

The Secret Formula

I left the option of using shading in the code, but it's not that useful. I'll leave this part of the article intact in case anybody is ever interested.

The most difficult part of writing this control was getting the animation to look even remotely realistic. In my first approach, I didn't use any shading, and just animated a skew of the image to approximate a rotation in 3D. This worked OK, but really wasn't believeable. So, I decided to do some trigonometry and figure out how to shade the image as it rotated.

The Secret Formula

As you can see from the figure, it's really not that complicated of a formula. From the diagram, y represents the factor I use for shading, and it's calculated from x and theta, as: y = x * Math.Tan(theta).

So, after I figure out what value to use for shading, how do I do the shading? It's pretty simple. The first thing to realize is that instead of doing anything complicated using colors, I'm actually just using y as an alpha value. That way, I really don't have to worry about what's underneath the shading layer. Since I'm flipping the image along the vertical (y) axis, I know that the shading value for every horizontal point along the same vertical axis will be the same, so I use Graphics.DrawLine() to draw a line over the image using the alpha value I've calculated. I put pretty many comments in the code, so if you read that you should be able to understand what's going on.

License

This article, along with any associated source code and files, is licensed under The BSD License

About the Author

thebeekeeper

United States United States
Whoa! I'm thebeekeeper. I'm from Milwaukee, WI but I'm living in Boston, MA right now. I work for a very large organization doing digital signal processing, but sometimes I write programs for computers!
 
Go look at my web-site! (thebeekeeper.net)

Comments and Discussions

 
GeneralProblem when adding it to a form Pinmembermt110422-Oct-09 3:59 
GeneralRe: Problem when adding it to a form Pinmemberthebeekeeper22-Oct-09 4:55 
GeneralSomething Similar in WPF PinmemberChristopher Totty29-Aug-08 10:42 
GeneralSOurce code PinmemberTaras Tim Bredel5-Dec-07 22:02 
QuestionDesigner? PinmemberCoderJ26-May-07 17:26 
GeneralI like it. Pinmembersalomo26-Mar-07 22:55 
GeneralRe: I like it. Pinmemberthebeekeeper27-Mar-07 4:53 
GeneralSuggestion PinmemberChadwick Posey20-Mar-07 13:30 
GeneralIncreasing realism PinmembermcstarSatx20-Mar-07 10:55 
GeneralRe: Increasing realism Pinmemberthebeekeeper21-Mar-07 4:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140709.1 | Last Updated 20 Mar 2007
Article Copyright 2007 by thebeekeeper
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid