This guide will explain how to create a animated menu template.

The first thing to contemplate is what we want to create. I have recently downloaded StarWreck, In The Pirkinning

It is a funny movie and makes for a nice DVD to give to a friend.

Lets get started ...

First I wanted to have a background image I can work with. I found this page and eventually got a nice enough, stary background image.


Next we should get something to animate, how about the shuttle.
This will lead to something like The image to the right

Of course the white frame needs to go.
So open the context menu and select [Properties ...].
Now click on [Color] and choose WHITE (0xFFFFFF)
Next modify Delta to become 0. This means that only
this one color is going to be filtered out and not a range.

And finally click on [Add] to activate the color filter.

This is what the menu should look like now.

Before anything else we should determine the length of the menu.
Open the [Property] dialog for the background.
Change into the [Geometry] - tab.

Set the ending time (in my example to 10 sconds).

Now lets look at the animation part ...


We want to have the shuttle fly around the earth. For this effet to look original, we have to calculate a eliptical orbit, which should follow about the yellow path...

For NTSC we have :
The number of steps required are 10 seconds * 30 frames per second = 300
The width = 720, height = 480

Note: I am using awk to do the math. BASH alone would not be suited. You can also use PERL or any other interpreted language which allows to print to stdout.

  PI         = 3.141592654;
  DEGTOPI    = PI / 180.0;
  iNrOfSteps = 300;
  iWidth     = 720;
  iHeight    = 480;

  function createCircle(radius)
    rr = radius * radius;
    for(t=0;t<iNrOfSteps;t++)  {
      # full circle == 2*PI
      alpha = t / iNrOfSteps * 2.0 * PI;
      x = radius * sin ( alpha );
      y = sqrt ( rr - x * x );

      X[t] = x;
      Y[t] = y;
      Z[t] = 0.0;
      if ( ( alpha > 0.5 * PI ) && ( alpha < 1.5 * PI ) )  {
        Y[t] = -y;

  function rotateX(angle)
    a = angle * DEGTOPI;
    for (t=0;t<iNrOfSteps;t++)  {
      Y[t] = cos(a) * Y[t] - sin(a) * Z[t];
      Z[t] = sin(a) * Y[t] + cos(a) * Z[t];

  function rotateY(angle)
    a = angle * DEGTOPI;
    for (t=0;t<iNrOfSteps;t++)  {
      X[t] = cos(a) * X[t] + sin(a) * Z[t];
      Z[t] =-sin(a) * X[t] + cos(a) * Z[t];

  function rotateZ(angle)
    a = angle * DEGTOPI;
    for (t=0;t<iNrOfSteps;t++)  {
      X[t] = cos(a) * X[t] - sin(a) * Y[t];
      Y[t] = sin(a) * X[t] + cos(a) * Y[t];

 END {

  # First we create a centered circle with set radius
  # Next we rotate the circle around the X-Axis ( make a Ellipse out of it)
  rotateX(  75.0 );
  # and we also rotate around the Z-Axis
  rotateZ(  50.0 );
  rotateY( -30.0 );

  # Lastly we print the valus to stdout
  for(t=0;t<iNrOfSteps;t++)  {
    if ( ( t > 119 ) && ( t < 183 ) )
    printf ( "%d %d\n", X[t] + 422, Y[t] + 230 );

I drew the yellow line by hand to get a feel for where I want to go.

The script to the right will approximate the orbit close enough. In order to accelerate the development of this algorithm I wrote a tiny project, which loads the above image.

Then I wrote the awk script to calculate the values and write them to a temp file. This file was read in and the positions were drawn.

Total time for this project was one day.

Next we had to suppress the path which should be behind the globe. For this I simply found the samples which are affected.

In order to give some depth to the animation we should also resize the shuttle. Thankfully the script above handles the transfomation in 3D space, so that we also have the Z - Axis values for the circle.

After about 15 minutes of trial and error I had the Z values normalized ( in the range between 0 and 1) and could use them to set the scale of the shuttle.

So in order to preview this I added a timer and drew the animation ...

In the final script I replaced the last loop from the script above with the one to the right to have the desired effect. ---->

Here is a snipplet of the generated output, which is used by QDVDAuthor to animate the object.


	# Lastly we print the valus to stdout
	for(t=0;t<iNrOfSteps;t++)  {
		# The Z index (size of image) is off by 90deg. thus the [300/4 = 75] offset.
		iZIndex = t + 75;
		if ( iZIndex >= iNrOfSteps )
			 iZIndex -= iNrOfSteps;
		if ( ( t > 119 ) && ( t < 190 ) )  {
			printf ( "%d::rect.x1=0\n",     t );
			printf ( "%d::rect.y1=0\n",     t );
			printf ( "%d::rect.width=1\n",  t );
			printf ( "%d::rect.height=1\n", t );
		else {
			zoom= (Z[iZIndex]+115.0)/230.0 * 0.7;
			angle=-zoom*360.0/ 0.7;
			printf ( "%d::pos.x=%d\n",       t, X[t] + 422 );
			printf ( "%d::pos.y=%d\n",       t, Y[t] + 230 );
			printf ( "%d::rect.width=251\n", t        );
			printf ( "%d::rect.height=251\n",t        );
			printf ( "%d::scale.x=%f\n",     t, zoom  );
			printf ( "%d::scale.y=%f\n",     t, zoom  );
			printf ( "%d::rotate=%f\n",      t, angle );

To animate an object (the shuttle in our example), go to the Properties dialog
and click on [Animation Script]. This will open the AnimationDialog where you can cut and paste the awk script over.

Template Creation:

So after we have a menu which we like, we have to create a template out of it.

Lets go to [DVDMenu->Store as Template ...]

After we filled in all the information we click on the [Define Dropzones >>>] button.

After you press [Define Dropzones >>>] you get to this page,

where you have to click on the objects you want to become the DropZone. Note, that only ButtonObjects can be chosen as DropZones.

This is the last step in the creation process. If you open the TemplateDialog now, the new template should be displayed in the appropriate templates - tab.

I hope you enjoy the program and the posibility to create templates with 'Q' DVD-Author.

Other interesting links: Gallery 3D
CRISS Personal links

Varol ;)

Last updated July 14'th 2006