Powerful Printing in Flash

Use Flash’s robust printing support to add print functionality to your Flash movies or Web applications. By using off-screen movie clips and ActionScripts movie clip copying commands, you can create effective printouts assembled on-the-fly.

Flash’s support for printing via the ActionScript print() commands remains a seldom-used, often-overlooked set of features Flash offers. Dont be fooled, however: Flash is capable of producing sophisticated, high-quality printouts. In fact, since Flash is working with vector graphics formats, it can produce printouts of a quality which often surpasses that of the Web browser’s printing. For my company’s last software project, we used Flash to add printing support to the Web-based application we were developing. We found that by moving printing to Flash, we could surpass the capabilities of the Web browsers native support and offer much richer printouts to our users.

The secret to providing print interfaces in Flash lies in using off-screen movie clips and copying the portions of the interface to be printed to these off-screen clips. The advantages of handling printing in this manner, as we will see, is that the Flash developer maintains much more control over what is printed and how it is printed: we don’t have to be constrained to printing what appears on the main movie interface.

It will be easier to follow the example code below if you are familiar with attaching new movie clips programmatically using the ActionScript attachMovie() command, and with using the eval() statement to look up existing movie clips. You might want to review the ActionScript documentation on these commands if you are unfamiliar with them.

Your Sample Flash Movie
Imagine a hypothetical situation: the client, an art museum, needs a simple drawing program in Flash for their Web site to promote a new art exhibit. They want to reach kids, and the Flash movie is supposed to increase interest in visiting the exhibit by allowing them to create their own artwork (perhaps in the style of the coming exhibit). The client also requires the following:

  • The movie must allow the user to print the drawings, so that the printout can be used as a free pass for kids to the exhibit.
  • The printout must contain info on the exhibit (name, hours, etc.), as well as the date the printout was made.

Figure 1 shows the main interface for the Flash movie.

 
Figure 1: Main Movie Interface. The movie clip where drawing will take place has been outlined to make it visible.

This sample Flash movie is the beginning of a small drawing program; it allows users to select one of 3 colors, as well as a tool to draw with (currently, only a circle). When users click on the drawing area, the movie places a circle at the clicked point in the selected color. The drawing area is actually its own movie clip, called drawingArea, and has been outlined to make it visible during development.

The ActionScript code to implement the drawing is as follows:

circleCount = 0;drawingArea.onPress = function() {	// make a copy of the circle movie, and name it circle plus// its sequence number appended as a suffix (i.e. circle0, // circle1, etc.) and place it on the clip drawingArea clipdrawingArea.attachMovie("circle","circle" + circleCount,circleCount);	// get a reference to this new clip	var circleClip = eval("drawingArea.circle" + circleCount);	// move the new clip to where the mouse was clicked	circleClip._x = drawingArea._xmouse;	circleClip._y = drawingArea._ymouse;		// set color of the new clip based on the value checked in the 	// colorGroup radio button group	var clipColor = new Color(circleClip);	switch (colorGroup.getValue()) {		case "red": 			clipColor.setRGB(0xff0000);			break		case "green": 			clipColor.setRGB(0x00ff00);			break;		case "blue": 			clipColor.setRGB(0x0000ff);			break;	}	// increment the total number of circles	circleCount++;};

Now, when users click the drawing area, a new circle of the selected color appears. Notice that the mouse clicks relative to the drawingArea movie clip (drawingArea._xmouse and drawingArea._ymouse), not to the main, or _root, clip. When you move the new circle clip, you do so relative to the clip that contains it, namely the drawingArea clip.

Printing Options
To meet the client’s printing requirements, you have 2 choices: you can use the Flash Player context menu (the popup menu available by right-clicking on the Flash movie) or you can use the ActionScript print() command. To print using the context menu, the user right-clicks on the Flash movie and selects Print from the pop-up menu (see Figure 2).

 
Figure 2: The Flash Player Context Menu. The standard context menu in the Flash player, which includes the default printing option.

Determine which frames should print by labeling frames in the movie with #p. Beware, however?this strategy has a couple of problems:

  • Your users might not know the context menu exists, so clearly indicate that the movie supports printing by using your own print button.
  • The ability to customize the printout format is limited in this application. You’ll need to add the exhibit info and date.

The native ActionScript printing commands (print(), printAsBitmap(), and printNum()) are much more powerful than the Flash Player menu’s print command. A full explanation of these commands is available in the Macromedia documentation. Note that, unlike printing from the context menu, these commands allow you to specify what is printed: movie clip, a set of frames, or a level in the movie. Here, you’ll use the most basic command: print().

Adding Printing to Your Movie
To add printing support, drop a button on your interface and wire its ActionScript handler (the function which handles the user’s click) up to ActionScripts print() command. In this case, send in a reference to the drawingArea clip and specify the bframe parameter. The button handler looks like this:

printButton.onPress = function() {print(drawingArea, "bframe")}

Now when users click on the button, Flash sends the printer the image of the drawingArea clip, including all the circle clips attached to it.

Controlling the Printout Format
You still need to add the exhibit info and date to the printout. Here is one way to print a movie clip that is on the user interface: add a couple of textfields to the drawingArea clip. By default, make these fields invisible and then immediately before printing, make them visible. Right after printing, turn them off again.

This solution is not ideal because users will see an awkward flickering as the textfields appear and disappear just before and after printing. Also, in general, there is no guaruntee that Flash will send the image of the drawingArea clip to the printer at the exact moment the textfields are visible. If Flash is a fraction of a second late, they may not appear in the printout.

 
Figure 3: The Printing Clip. Notice the printing clip is located outside the visible area of the movie.

The solution, as I mentioned at the beginning, is to use an off-screen movie clip. Copy what is on the drawingArea clip to a movie clip outside the visible area, and print that off-screen clip. It turns out that Flash is perfectly capable of printing clips that are beyond the borders of the visible area (see Figure 3).

Create another clip called printingClip. Make it the same size as drawingClip, but keep it out of the visible area of the movie. To that clip, add a pair of TextFields at the top for the exhibit info and date. To further improve the look of the printout, you can stick in a border as well.

The print button needs to make a copy of what is on the current drawing area. To do this, change the print button handler:

printButton.onPress = function() {	// we need to make a  copy of circleCount circlesfor (var i = 0; i < circleCount; i++) {	// first find the circle clip on the drawing area		var drawnCircle = eval("drawingArea.circle" + i);		// create a new circle clip on the print area	printingArea.attachMovie("circle","circle" + i,i);	var printCircle = eval("printingArea.circle" + i);			// move the new circle clip to the same position as the other clip	printCircle._x = drawnCircle._x;	printCircle._y = drawnCircle._y;		// set color of the new circle clip	var drawnCircleColor = new Color(drawnCircle);	var printCircleColor = new Color(printCircle);	printCircleColor.setRGB(drawnCircleColor.getRGB());			}

The final movie includes a date field on the printout, so just before calling print(), fill in the date:

printingArea.dateField.text = new Date();

Then call print():

print(printingArea,"bframe");

There you have it! A print UI that you can customize to support your printing needs. Plus, if the client has new formatting requests, you can easily manipulate this printing interface without affecting the main UI.

Share the Post:
Share on facebook
Share on twitter
Share on linkedin

Overview

Recent Articles: