Click here to Skip to main content
16,017,899 members
Articles / Desktop Programming / Windows Forms
Article

A Panel control that you can flip over

Rate me:
Please Sign up or sign in to vote.
3.84/5 (9 votes)
20 Mar 2007BSD4 min read 75.7K   2.5K   43   12
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:

C#
// 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.

C#
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


Written By
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

 
PraiseThanks for making this Pin
Member 1413004031-Jul-21 18:41
Member 1413004031-Jul-21 18:41 
QuestionExisting controls Pin
N. Henrik Lauridsen17-Sep-15 20:36
N. Henrik Lauridsen17-Sep-15 20:36 
GeneralProblem when adding it to a form Pin
mt110422-Oct-09 3:59
mt110422-Oct-09 3:59 
GeneralRe: Problem when adding it to a form Pin
thebeekeeper22-Oct-09 4:55
thebeekeeper22-Oct-09 4:55 
GeneralSomething Similar in WPF Pin
Christopher Totty29-Aug-08 10:42
Christopher Totty29-Aug-08 10:42 
Since I found this posting while searching for something like this except in WPF, I'm sure someone else has or will do the same thing. So, here is a post I ran across which does something similar using WPF.

http://www.interact-sw.co.uk/iangblog/2007/05/17/wpf-flippable-3D-list[^]
GeneralSOurce code Pin
Taras Tim Bredel5-Dec-07 22:02
Taras Tim Bredel5-Dec-07 22:02 
QuestionDesigner? Pin
CoderJ26-May-07 17:26
CoderJ26-May-07 17:26 
GeneralI like it. Pin
bitdisaster26-Mar-07 22:55
bitdisaster26-Mar-07 22:55 
GeneralRe: I like it. Pin
thebeekeeper27-Mar-07 4:53
thebeekeeper27-Mar-07 4:53 
GeneralSuggestion Pin
Chadwick Posey20-Mar-07 13:30
Chadwick Posey20-Mar-07 13:30 
GeneralIncreasing realism Pin
mcstarSatx20-Mar-07 10:55
mcstarSatx20-Mar-07 10:55 
GeneralRe: Increasing realism Pin
thebeekeeper21-Mar-07 4:13
thebeekeeper21-Mar-07 4:13 

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

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