[ Team LiB ] Previous Section Next Section

25.1 Dynamic Buttons

Images wrapped in anchor tags are a common navigational device. Instead of plaintext, this method allows you to create buttons similar to those created in the operating system or even to create fanciful icons. In most cases it is best to leave these as graphics created in your favorite graphics editor, because the time between changes is relatively long. However, if you have a button that changes often, it may make sense to create it dynamically with PHP. The content of the button, the label, needs to be available as a string in PHP. It could be a statement setting the value of a variable. It could also be a value retrieved from a file or a database.

An illustration will make this idea clear. Many corporate Web sites have a section for press releases. Instead of just a list of text links, your client wants a graphic of a flaming newspaper for each press release, all under the title "Hot off the Press." Each burning newspaper has text over the top with the headline from the press release. With a small company that issues only one press release a month, you are better off creating these graphics by hand. With a company that issues a press release each week, it starts to make sense to automate the process. You can put the press releases into a database and generate a graphic on the fly as surfers view the list of press releases. One advantage of this approach is that if the CEO finds out you're putting flaming newspapers on the site, you can make a minor modification and the graphics become the company logo with the press-release title over it.

Seriously, you must consider the tradeoffs associated with dynamically created graphics. You don't want to save yourself 15 minutes a month if it makes every page download 30 seconds longer. If you've been working with the Web for any time at all, you know to reuse graphics throughout the site because the browser caches them. The first page may take longer to load, but each successive page 0is faster because the graphics are already loaded in the browser. Dynamic graphics can be cached, of course, but the browser uses the URL to cache files. The GET-method form variables are part of the URL, so http://www.site.com/button.php?label=home&from=1 and http://www.site.com/button.php?label=home&from=2 may create two identical graphics but are different as far as the browser cache is concerned.

These are only some of the issues involved with dynamic buttons. To demonstrate the process, I'll provide an example and describe the steps. Listing 25.1 is a script that creates a PNG image of a button with a text label. The button is rectangular and has some highlighting and shadowing. The label has a drop-shadow effect applied to it and is centered both vertically and horizontally. The output is shown in Figure 25.1.

Listing 25.1 PNG button
<?php
    /*
    ** PNG button
    ** Creates a graphical button based
    ** on form variables.
    */

    class Button
    {
        private $image;
        public function __construct($width, $height, $label, $font)
        {
            $this->image = imagecreate($width, $height);
            $colorBody = imagecolorallocate($this->image,
                0x99, 0x99, 0x99);
            $colorShadow = imagecolorallocate($this->image,
                0x33, 0x33, 0x33);
            $colorHighlight = imagecolorallocate($this->image,
                0xCC, 0xCC, 0xCC);

            //create body of button
            imagefilledrectangle($this->image,
                1, 1, $width-2, $height-2,
                $colorBody);

            //draw bottom shadow
            imageline($this->image,
                0, $height-1,
                $width-1, $height-1,
                $colorShadow);

            //draw right shadow
            imageline($this->image,
                $width-1, 1,
                $width-1, $height-1,
                $colorShadow);

            //draw top highlight
            imageline($this->image,
                0, 0,
                $width-1, 0,
                $colorHighlight);

            //draw left highlight
            imageline($this->image,
                0, 0,
                0, $height-2,
                $colorHighlight);

            //determine label size
            $labelHeight = imagefontheight($font);
            $labelWidth = imagefontwidth($font) * strlen($label);

            //determine label upper left corner
            $labelX = ($width - $labelWidth)/2;
            $labelY = ($height - $labelHeight)/2;

            //draw label shadow
            imagestring($this->image,
                $font,
                $labelX+1,
                $labelY+1,
                $label,
                $colorShadow);

            //draw label
            imagestring($this->image,
                $font,
                $labelX,
                $labelY,
                $label,
                $colorHighlight);
        }

        public function drawPNG()
        {
            header("Content-type: image/png");
            imagepng($this->image);
        }

        public function drawJPEG()
        {
            header("Content-type: image/jpeg");
            imagejpeg($this->image);
        }
    }

    //set parameters if not given
    if(!isset($_REQUEST['width']))
    {
        $_REQUEST['width'] = 100;
    }

    if(!isset($_REQUEST['height']))
    {
        $_REQUEST['height'] = 30;
    }

    if(!isset($_REQUEST['label']))
    {
        $_REQUEST['label'] = "CLICK";
    }

    if(!isset($_REQUEST['font']))
    {
        $_REQUEST['font'] = 5;
    }

    $b = new Button($_REQUEST['width'], $_REQUEST['height'],
        $_REQUEST['label'], $_REQUEST['font']);
    $b->drawPNG();
?>
Figure 25.1. Output from Listing 25.1.

graphics/25fig01.gif

The first step the script takes is to make sure it has valid information for all the parameters. These include the size of the button and the text with which to label the button. I've chosen to use the built-in fonts, which are numbered one through five. Chapter 16 has descriptions of functions for loading different fonts, and I encourage you to modify my script to incorporate them.

The next step is to create an image. There are two ways to do this. You can create a blank image of a specific size, or you can load an existing image file. I've chosen the former because it allows the script to make buttons of any size. You can make much more stylish buttons using the latter method. This is another good exercise.

The button will be drawn with three colors: a body color, a highlight color, and a shadow color. I've chosen to go with three shades of gray. These colors must be allocated with the imagecolorallocate function. Using the body color, the script makes a rectangle that is one pixel smaller than the entire image. The border around this rectangle is created with four lines. The lines on the bottom and right sides are drawn in the shadow color, and the top and left sides are drawn with the highlight color. This creates an illusion of the button being three-dimensional.

To finish the button, the script draws the label. First, the text is drawn slightly off center in the shadow color. Then the text is drawn in the highlight color over it and exactly centered, making the text look as though it is floating over the button.

At this point the script has created the image and needs to send it to the browser. It is very important that the header be sent to let the browser know that this file is an image. Without it, you get a garbled bunch of strange characters.

This wraps up the script that creates a button, but to really make use of it, we have to use it in the context of a Web page. Listing 25.2 demonstrates the minimal steps. I've created an array of four button labels I want to create. I then loop through the array, each time creating an image tag. The source of the image is the previous script. I pass the script some parameters to set the size of the button and the label. I leave the font as the default, but I could have set that as well. The output is shown in Figure 25.2.

Listing 25.2 Creating buttons dynamically
<?php
    //define button labels
    $label = array("HOME",
        "ABOUT US",
        "OUR PRODUCTS",
        "CONTACT US");

    //display all buttons
    foreach($label as $text)
    {
        //link back to this page
        print("<a href=\"$SERVER['PHP_SELF']}\">");

        //create dynamic image tag
        print("<img src=\"25-1.php");
        print("?label=" . htmlentities($text));
        print("&amp;width=145");
        print("&amp;height=25");
        print("\" border=\"0\"");
        print("width=\"145\" height=\"25\">");

        print("</a><br>\n");
    }
?>
Figure 25.2. Output from Listing 25.2.

graphics/25fig02.jpg

    [ Team LiB ] Previous Section Next Section