OK!
So, you want to make a Flash container with all your own graphics and buttons and load your FPP presentation into it? Here you go... a quick "embed pano 101". 
What you'll end up with is a "skinned" player which displays your FPP panorama with an irregular outline (not a rectangle!) -- including buttons to load panoramas, buttons to pan/tilt/zoom, and a button to "go fullscreen".
Topping it all off you'll be able to go fullscreen and leave some of your buttons & graphics behind, then leave fullscreen and get your buttons back. This allows you to display what you want when you want it. The FPP XML in this example will show some thumbnails in fullscreen, which display larger photos.
As a bonus in this example, we will load lower resolution panoramas into the player when not in fullscreen; then, when going fullscreen, we will load higher resolution panoramas. Once loaded, these higher resolution panoramas will stay in the cache and be seen in fullscreen and not fullscreen. So, there's a lot packed into this 'little' example!
Note: This tutorial was designed and works with FPP v2.2. See comment below for how to use with FPP v2.3 (Flash Player 10)
Note 2: This tutorial does not cover Papervision or PanoSalado. If you are looking for help with PanoSalado, check out the PanoSalado forums. This tutorial is for those using FPP.
-----
I'll go through the basics of setting up the project and go through the Actionscript code line-by-line. At the end of this post you'll find all the Actionscript in one block for easy copying. Note that I used the "embedPano.fla" which comes with Flash Panorama Player as a starting point, so you can also find that in your FPP download and use it as reference. The code for going fullscreen and back was informed by Denis of FPP fame and others in the forums, and the "go fullscreen" button is from the FPP download.
This tutorial assumes you're using Flash CS3 or newer, Actionscript 3, and have a basic knowledge of creating and placing MovieClips, buttons, graphics, etc. onto the pasteboard in a Flash CS3 doc. Advanced users can pull MovieClips and other items directly from the Library and so on.
Here's a link to a working example, and here's an image of the final presentation:

The first thing to do is lay out your presentation in Flash. This presentation uses:
- An irregularly shaped graphic which will mask the panoramas (MovieClip "theMask")
- A MovieClip "left_sidebar" which contains buttons that load panoramas "on click" ('view1', 'view2', 'view3', etc)
- Buttons to control panning, tilting and zooming ('left', 'right', 'up', 'down', etc)
- A fullscreen button "full_btn"
- Other graphical items as you see fit to include
- A working set of FPP XML, panoramas, and whatever plugins/hotspots you include in the XML
You can use the Property Inspector in Flash to assign a name to each of your Buttons and/or MovieClips.
Here's an image of my Flash project humming along on my Mac; Windows users should see a similar setup:

So, now we've got all our MovieClips, graphics and other layout elements on the pasteboard/stage in our Flash project. Let's get to coding!
Always a good idea to stop the timeline from moving along. It's a habit, and maybe unnecessary. 
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.*;
import flash.net.URLRequest;
import fl.transitions.Tween;
import fl.transitions.*;
import fl.transitions.easing.*;
The above import statements set up Flash so it can deal with things like loading external data, Sprites & Sprite events, and tweening elements. We won't use tweening in this example, but I'm planning ahead... 
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
Let's get our stage to play nice when going to and leaving fullscreen mode.
var panorama
:MovieClip
;
var loader
:Loader
= new Loader
();
loader
.load
(new URLRequest
("base/pano.swf"));
addChild
(loader
);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
var thePanoToLoad = "panos/small/pano_1/_bracketed_1";
var theCurrentPano = "1";
OK, now we're getting to fun stuff. We set up a MovieClip var called panorama: This is where we'll ultimately put the loaded FPP "pano.swf", and what we'll target when we want to make the panorama 'do things'.
loader is the actual Loader Object which handles getting "pano.swf", and we add it to the Stage (Display List) once we get it started loading.
We also give loader an EventListener called loadComplete. So, loader can check the load progress of "pano.swf" and call the loadComplete function when "pano.swf" is done loading.
Lastly we set up two variables to hold information about our various panoramas. thePanoToLoad is our FPP "panoName" equivalent. We'll use theCurrentPano to track which panorama is currently being viewed; this is so we can load the proper high-resolution panorama when in fullscreen.
full_btn
.visible
= false;
left_sidebar
.view1
.alpha
= left_sidebar
.view2
.alpha
= left_sidebar
.view3
.alpha
= left_sidebar
.view4
.alpha
= left_sidebar
.view5
.alpha
= left_sidebar
.view6
.alpha
= 0.5;
//
var theBL
:int
= 0;
var theBT
:int
= 0;
var thePL
:int
= 0;
//
function loadComplete
(e
:Event
) {
swapChildren
(loader
, full_btn
);
panorama
= loader
.content
as MovieClip
;
panorama
.mask
= theMask
;
panorama
.setArea
(150,20,570,380);
panorama.loadPanorama("panoName="+thePanoToLoad+"&xml_file=base/_setup.xml");
left.addEventListener(MouseEvent.MOUSE_DOWN, doLeft);
right.addEventListener(MouseEvent.MOUSE_DOWN, doRight);
up.addEventListener(MouseEvent.MOUSE_DOWN, doUp);
down.addEventListener(MouseEvent.MOUSE_DOWN, doDown);
zoomin.addEventListener(MouseEvent.MOUSE_DOWN, doZoomin);
zoomout.addEventListener(MouseEvent.MOUSE_DOWN, doZoomout);
stage.addEventListener(MouseEvent.MOUSE_UP, reset);
if (stage.hasOwnProperty("displayState")) {// check fullscreen feature is accessible or not
stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullscreenHandler);
full_btn.addEventListener(MouseEvent.CLICK, doFullscreen);
} else {
full_btn.visible=false;
}
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
There's a lot going on above, and in our loadComplete function.
Firstly, we set the alpha of our various buttons to 50 percent, and hide our full screen button. This is to indicate to the user that they can't use the buttons (ie, a panorama hasn't fully loaded). We'll "watch" for a panorama to be loaded fully later on in the code. To that end, we set up theBL, theBT, and thePL to hold values for (respectively) our panorama's bytes loaded, bytes total, and percent loaded.
swapChildren basically tells Flash that we want loader (that is, "pano.swf") to be visually above our Button full_btn. If you had a different graphic element which you wanted to layer behind your pano, this is where you would say so. So, rather than full_btn, you could say something like swapChildren(loader, myCoolBackgroundGraphic);.
The next three lines get our panorama MovieClip ready for its job as a container for our panoramas:
- We tell
panorama to accept what loader has just loaded ("pano.swf")
- We give
panorama our irregularly shaped graphic theMask as a Mask
- We tell
panorama to have a position of 150 pixels from the left, 20 pixels from the top, and be 570 pixels wide by 380 pixels tall
Now that panorama is set up, we can target it as a MovieClip. Targeting panorama is basically targeting "pano.swf". Our first task, using FPP's special loadPanorama function, is to... load our first panorama!
...thePanoToLoad already holds the "panoName" of our first panorama. We plug this in to the loadPanorama function, and add our FPP XML file to the end of the function.
Next we set up "Mouse Down" Event Listeners for each of our pan, tilt and zoom buttons. So, for example, in left.addEventListener(MouseEvent.MOUSE_DOWN, doLeft); we are saying WhichButton.addEventListener(WhatTypeOfEvent, WhatFunctiontoCall);. We also set up a "Mouse Up" Event Listener on the stage; this gets us around setting up a special "Mouse Up" Event Listener on each of our buttons.
And now, our "go fullscreen" Event Listener.
First we check to see if we even have the ability to go fullscreen. If we can't "go fullscreen", then why bother showing the button for going fullscreen? So, we check first if we can change the "Display State"; If so, then add the Event Listener fullscreenHandler to the stage, and the "Mouse Click" Event Listener doFullscreen to our Button full_btn. If not, then we set full_btn's visibility to false (hidden).
Remember, if you set an item's visible to false, it disables any Mouse Events on that item; If you simply set an item's alpha to 0 (zero), it will be hidden from view -- but you can still use your mouse to interact with it.
Lastly, we add an Event Listener to the Stage, which happens once per each frame at whatever the frame rate is for your Flash project. Even though we aren't 'physically' moving down a timeline with multiple frames, this panoLoadWatcher function will fire off once per frame until we tell it to stop. We'll go over the panoLoadWatcher function at the very end, but it will basically tell us how much of the panorama has loaded, and when done loading it will set visibility and alpha of our buttons back to full visibility and alpha.
Make sense? Below, I'll go over the actual functions for each of these Mouse Events.
left_sidebar
.view1
.addEventListener
(MouseEvent
.CLICK
,loadPanoFunction
);
left_sidebar
.view2
.addEventListener
(MouseEvent
.CLICK
,loadPanoFunction
);
left_sidebar
.view3
.addEventListener
(MouseEvent
.CLICK
,loadPanoFunction
);
left_sidebar
.view4
.addEventListener
(MouseEvent
.CLICK
,loadPanoFunction
);
left_sidebar
.view5
.addEventListener
(MouseEvent
.CLICK
,loadPanoFunction
);
left_sidebar
.view6
.addEventListener
(MouseEvent
.CLICK
,loadPanoFunction
);
function loadPanoFunction(event:Event) {
var obj:Object = event.target;
var whichButton = obj.name;
switch (whichButton) {
case "view1" :
thePanoToLoad = "panos/small/pano_1/_bracketed_1";
theCurrentPano = "1";
break;
case "view2" :
thePanoToLoad = "panos/small/pano_2/_bracketed_1a";
theCurrentPano = "2";
break;
case "view3" :
thePanoToLoad = "panos/small/pano_3/bracketed_1-flat";
theCurrentPano = "3";
break;
case "view4" :
thePanoToLoad = "panos/small/pano_4/_bracketed_1";
theCurrentPano = "4";
break;
case "view5" :
thePanoToLoad = "panos/small/pano_5/_bracketed_1a";
theCurrentPano = "5";
break;
case "view6" :
thePanoToLoad = "panos/small/pano_6/_bracketed_1";
theCurrentPano = "6";
break;
default :
thePanoToLoad = "panos/small/pano_1/_bracketed_1";
theCurrentPano = "1";
break;
}
if (thePL == -1) {
if (panorama.externals.hotspots!=null) {
if (panorama.externals.hotspots.panoName == thePanoToLoad) {
} else {
panorama.externals.hotspots.loadPano(["pano.swf?panoName="+thePanoToLoad]);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
} else {
panorama.pano.remove();
panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
}
}
The above block of code does a lot! First, we set up "Mouse Click" Event Listener on each of our buttons inside left_sidebar. Now when our "view1", "view2", "view3", etc, button is clicked it will call on the loadPanoFunction which will (drum roll please) load a new panorama! This loadPanoFunction will need to get the new "panoName" and then tell FPP to load it. loadPanoFunction will also begin tracking which panorama we are currently viewing so that we can switch to a higher resolution of it when we go fullscreen.
loadPanoFunction takes the Mouse Event, finds the target of the Event (that is, which button was clicked), gets the button's name (as set in the Property Inspector) and assigns the name to the whichButton variable.
Using whichButton, we check it against our list inside our switch code block. When we have a match (ie, "view3"), then we assign the new "panoName" to thePanoToLoad, and give our arbitrary number assignment of this particular panorama to theCurrentPano. We'll need this information in just a second...
Next up is where we actually tell FPP to load a new panorama.What this code block is saying then is: if we aren't currently loading a panorama (ie, if thePL isn't somewhere between 0 and 100 percent), then check to see if FPP's hotspots plugin is available*. If the hotspots plugin is available, then use it to load a new panorama; else, remove the current pano object using FPP's internal remove() function (so we don't end up with two panos in there) and load a new panorama into a fresh "pano.swf". In either case, we start the Event Listener function panoLoadWatcher, which monitors the load progress of our panorama.
panorama.pano.remove is important to look at. See the additional piece of targeting in there? pano is FPP's internal Object for the current panorama which we can access, and remove is FPP's hook to its "remove" function. If we just targeted panorama.remove we'd get an error (or nothing). So, we target the "actual" pano and hook onto its remove function.
* Somewhere in an email or a forum post far far away, Denis of FPP fame let us know that it is more efficient to use the hotspots plugin to handle loading, than it is to forcibly remove and reintroduce panoramas.
function doLeft(e:Event) {
panorama.pano.panKey = -1;
}
function doRight(e:Event) {
panorama.pano.panKey = 1;
}
function doUp(e:Event) {
panorama.pano.tiltKey = 1;
}
function doDown(e:Event) {
panorama.pano.tiltKey = -1;
}
function doZoomin(e:Event) {
panorama.pano.zoomKey = 1;
}
function doZoomout(e:Event) {
panorama.pano.zoomKey = -1;
}
function reset(e:Event) {
panorama.pano.panKey = 0;
panorama.pano.tiltKey = 0;
panorama.pano.zoomKey = 0;
}
We're more than halfway done here, really. 
The above block of code should bring back some memories... We've already added Event Listeners to each of our pan, tilt and zoom buttons. These are the functions they call on. Again make note of how we're targeting pano, and using the standard FPP syntax to tell the panorama to move left, right, up, down, in or out a la the functions doLeft, doRight, doUp, etc, and the FPP hooks of panKey, tiltKey, zoomKey.
The reset function is what the stage calls on when the user lifts the mouse ("Mouse Up"), and simply tells FPP to stop panning, tilting or zooming.
function doFullscreen
(e
:Event
) {
if (stage
.hasOwnProperty
("displayState")) {
if (stage
.displayState
== StageDisplayState
.FULL_SCREEN
) {
stage
.displayState
= StageDisplayState
.NORMAL
;
} else {
stage
.displayState
= StageDisplayState
.FULL_SCREEN
;
switch (theCurrentPano
) {
case "1" :
thePanoToLoad
= "panos/large/pano_1/pano_1";
break;
case "2" :
thePanoToLoad
= "panos/large/pano_2/pano_2";
break;
case "3" :
thePanoToLoad
= "panos/large/pano_3/pano_3";
break;
case "4" :
thePanoToLoad
= "panos/large/pano_4/pano_4";
break;
case "5" :
thePanoToLoad
= "panos/large/pano_5/pano_5";
break;
case "6" :
thePanoToLoad
= "panos/large/pano_6/pano_6";
break;
default :
thePanoToLoad
= "panos/large/pano_1/pano_1";
break;
}
if (thePL
== -1) {
if (panorama
.externals
.hotspots
!=null) {
if (panorama
.externals
.hotspots
.panoName
== thePanoToLoad
) {
} else {
panorama.externals.hotspots.loadPano(["pano.swf?panoName="+thePanoToLoad]);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
} else {
panorama.pano.remove();
panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
}
}
}
}
The above code is a meaty function. This is the function which our full_btn calls on. Finally, we can go fullscreen!
The first thing we do is double-check that we can go fullscreen (via "displayState"). If so, and we already are in Full Screen mode, then take us out of Full Screen Mode. Else, if we're not in Full Screen Mode then "go fullscreen".
This is also where we load a higher resolution panorama to show in glorious full screen.
Remember theCurrentPano? We gave it a number which corresponds to the current low-resolution panorama. We check this number, and then set thePanoToLoad with our hi-res panoName.
After getting the panoName of our hi-res image, we make sure we aren't already in the middle of loading a panorama (thePL). We again check that the hotspots plugin is present, and reach an important juncture.
Our tour initially loads using a low resolution panorama. When we first go fullscreen, we load the high resolution version of the current panorama. Since this new hi-res panorama is now loaded into memory, it makes no sense to continue switching between lo- and hi-res versions of it. Sooo...
We take this new "panoName" (thePanoToLoad) and check it against the current panoName which FPP has. If they match, then we tell FPP to not reload the panorama (that is by doing nothing). Else, if thePanoToLoad and FPP's "panoName" (panorama.externals.hotspots.panoName) don't match, then go ahead and load the hi-res panorama.
Got it? 
The second to last little block of code is below. Almost done!
function fullscreenHandler(e:FullScreenEvent) {
if (e.fullScreen) {
theMask.visible = left_sidebar.visible = bottom_bar.visible = left.visible = right.visible = up.visible = down.visible = zoomin.visible = zoomout.visible = false;
panorama.setArea(0,0,stage.stageWidth,stage.stageHeight);
panorama.mask = null;
full_btn.x = stage.stageWidth-22;
full_btn.y = 22;
} else {
left_sidebar.visible = bottom_bar.visible = left.visible = right.visible = up.visible = down.visible = zoomin.visible = zoomout.visible = true;
panorama.setArea(150,20,570,380);
panorama.mask = theMask;
full_btn.x = 672;
full_btn.y = 406;
}
}
Up near the top we added an Event Listener to the stage: stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullscreenHandler);. Every time the user clicks the fullscreen button (or uses the esc key when in Full Screen Mode) and changes us from one Full Screen Mode to another, the stage runs this function.
In my presentation, I wanted to not show the pan, tilt, zoom, and view buttons in Full Screen (notice that when you go fullscreen in my presentation, you see some FPP image hotspots). This fullscreenHandler does the work of showing/hiding the various buttons -- and most importantly it removes and reintroduces theMask. Obviously, "going fullscreen" but keeping the little irregularly shaped "skin" would be counterintuitive. 
Note also that we call on setArea. Since we're using an "embedPano" style setup, we need to let Flash know that it's OK to resize the panorama to fill the screen. Once we leave Full Screen Mode, though, we need to tell Flash to put things back the way they were.
And, the last function, but not the least important one:
function panoLoadWatcher
(e
:Event
=null) {
if (panorama
.externals
.hotspots
!=null) {
if (full_btn.visible == true) {
full_btn.visible = false;
}
if (left_sidebar.view1.alpha > 0.5) {
left_sidebar.view1.alpha = left_sidebar.view2.alpha = left_sidebar.view3.alpha = left_sidebar.view4.alpha = left_sidebar.view5.alpha = left_sidebar.view6.alpha = 0.5;
}
//
theBL = panorama.pano.bytesLoaded;
theBT = panorama.pano.bytesTotal;
thePL = panorama.pano.percentLoaded;
trace("PANO bytesLoaded?: "+theBL);
trace("PANO bytesTotal?: "+theBT);
trace("PANO percentLoaded?: "+thePL);
if (thePL >= 100) {
theBL = -1;
theBT = -1;
thePL = -1;
full_btn.visible = true;
left_sidebar.view1.alpha = left_sidebar.view2.alpha = left_sidebar.view3.alpha = left_sidebar.view4.alpha = left_sidebar.view5.alpha = left_sidebar.view6.alpha = 1.0;
removeEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
}
}
FPP can get a little confused sometimes.
That is, it's possible to try to load a new panorama while we're still loading the first one. This can (when using an Embed Pano setup) lead to weird issues such as having two panoramas overlaying each other in the viewer window.
What panoLoadWatcher does is:
- Check the visibility of the "go fullscreen" button; if it's visible, hide it. Thisis so someone can't take the presentation fullscreen while a lo-res pano is loading (thus trying to load a hi-res panorama).
- Set the alpha of the "view" buttons to 50 percent, visually implying that they're not usable.
- Monitor the percent/bytes loaded of the panorama.
- When the panorama is done loading, change back the alpha of the "view" buttons, make the "go fullscreen" button visible, and reset the percent/bytes loaded variables to "-1" so that other functions know it's OK or not OK to load a new panorama.
- Remove the Event Listener, so we aren't hogging resources.
Whew! I think that does it. I hope this helps! 
Please post errors, comments, questions below. I look forward to reading them!
Cheers,
Patrick
--------
The entire code sans commentary:
stop
();
import flash
.display
.Loader
;
import flash
.display
.LoaderInfo
;
import flash
.display
.Sprite
;
import flash
.events
.*;
import flash
.net
.URLRequest
;
import fl
.transitions
.Tween
;
import fl
.transitions
.*;
import fl
.transitions
.easing
.*;
var panorama:MovieClip;
var loader:Loader = new Loader();
loader.load(new URLRequest("base/pano.swf"));
addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
//
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
//
var thePanoToLoad = "panos/small/pano_1/_bracketed_1";
var theCurrentPano = "1";
//
full_btn.visible = false;
left_sidebar.view1.alpha = left_sidebar.view2.alpha = left_sidebar.view3.alpha = left_sidebar.view4.alpha = left_sidebar.view5.alpha = left_sidebar.view6.alpha = 0.5;
//
var theBL:int = 0;
var theBT:int = 0;
var thePL:int = 0;
//
function loadComplete(e:Event) {
swapChildren(loader, full_btn);
panorama = loader.content as MovieClip;
panorama.mask = theMask;
panorama.setArea(150,20,570,380);
panorama.loadPanorama("panoName="+thePanoToLoad+"&xml_file=base/_setup.xml");
left.addEventListener(MouseEvent.MOUSE_DOWN, doLeft);
right.addEventListener(MouseEvent.MOUSE_DOWN, doRight);
up.addEventListener(MouseEvent.MOUSE_DOWN, doUp);
down.addEventListener(MouseEvent.MOUSE_DOWN, doDown);
zoomin.addEventListener(MouseEvent.MOUSE_DOWN, doZoomin);
zoomout.addEventListener(MouseEvent.MOUSE_DOWN, doZoomout);
stage.addEventListener(MouseEvent.MOUSE_UP, reset);
if (stage.hasOwnProperty("displayState")) {// check fullscreen feature is accessible or not
stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullscreenHandler);
full_btn.addEventListener(MouseEvent.CLICK, doFullscreen);
} else {
full_btn.visible=false;
}
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
//
left_sidebar.view1.addEventListener(MouseEvent.CLICK,loadPanoFunction);
left_sidebar.view2.addEventListener(MouseEvent.CLICK,loadPanoFunction);
left_sidebar.view3.addEventListener(MouseEvent.CLICK,loadPanoFunction);
left_sidebar.view4.addEventListener(MouseEvent.CLICK,loadPanoFunction);
left_sidebar.view5.addEventListener(MouseEvent.CLICK,loadPanoFunction);
left_sidebar.view6.addEventListener(MouseEvent.CLICK,loadPanoFunction);
//
function loadPanoFunction(event:Event) {
var obj:Object = event.target;
var whichButton = obj.name;
switch (whichButton) {
case "view1" :
thePanoToLoad = "panos/small/pano_1/_bracketed_1";
theCurrentPano = "1";
break;
case "view2" :
thePanoToLoad = "panos/small/pano_2/_bracketed_1a";
theCurrentPano = "2";
break;
case "view3" :
thePanoToLoad = "panos/small/pano_3/bracketed_1-flat";
theCurrentPano = "3";
break;
case "view4" :
thePanoToLoad = "panos/small/pano_4/_bracketed_1";
theCurrentPano = "4";
break;
case "view5" :
thePanoToLoad = "panos/small/pano_5/_bracketed_1a";
theCurrentPano = "5";
break;
case "view6" :
thePanoToLoad = "panos/small/pano_6/_bracketed_1";
theCurrentPano = "6";
break;
default :
thePanoToLoad = "panos/small/pano_1/_bracketed_1";
theCurrentPano = "1";
break;
}
/*if (panorama.pano.loadCompleted) {
if (panorama.externals.hotspots!=null) {
//panorama.externals.hotspots.loadPano(["pano.swf?panoName="+thePanoToLoad]);
} else {
panorama.pano.remove();
panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad);
}
}*/
if (thePL == -1) {
if (panorama.externals.hotspots!=null) {
if (panorama.externals.hotspots.panoName == thePanoToLoad) {
} else {
panorama.externals.hotspots.loadPano(["pano.swf?panoName="+thePanoToLoad]);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
} else {
panorama.pano.remove();
panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad);
}
}
}
//
function doLeft(e:Event) {
panorama.pano.panKey = -1;
}
function doRight(e:Event) {
panorama.pano.panKey = 1;
}
function doUp(e:Event) {
panorama.pano.tiltKey = 1;
}
function doDown(e:Event) {
panorama.pano.tiltKey = -1;
}
function doZoomin(e:Event) {
panorama.pano.zoomKey = 1;
}
function doZoomout(e:Event) {
panorama.pano.zoomKey = -1;
}
function reset(e:Event) {
panorama.pano.panKey = 0;
panorama.pano.tiltKey = 0;
panorama.pano.zoomKey = 0;
}
//
function doFullscreen(e:Event) {
if (stage.hasOwnProperty("displayState")) {
if (stage.displayState == StageDisplayState.FULL_SCREEN) {
stage.displayState = StageDisplayState.NORMAL;
} else {
stage.displayState = StageDisplayState.FULL_SCREEN;
switch (theCurrentPano) {
case "1" :
thePanoToLoad = "panos/large/pano_1/pano_1";
break;
case "2" :
thePanoToLoad = "panos/large/pano_2/pano_2";
break;
case "3" :
thePanoToLoad = "panos/large/pano_3/pano_3";
break;
case "4" :
thePanoToLoad = "panos/large/pano_4/pano_4";
break;
case "5" :
thePanoToLoad = "panos/large/pano_5/pano_5";
break;
case "6" :
thePanoToLoad = "panos/large/pano_6/pano_6";
break;
default :
thePanoToLoad = "panos/large/pano_1/pano_1";
break;
}
if (thePL == -1) {
if (panorama.externals.hotspots!=null) {
if (panorama.externals.hotspots.panoName == thePanoToLoad) {
} else {
panorama.externals.hotspots.loadPano(["pano.swf?panoName="+thePanoToLoad]);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
} else {
panorama.pano.remove();
panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
}
}
}
}
function fullscreenHandler(e:FullScreenEvent) {
if (e.fullScreen) {
theMask.visible = left_sidebar.visible = bottom_bar.visible = left.visible = right.visible = up.visible = down.visible = zoomin.visible = zoomout.visible = false;
panorama.setArea(0,0,stage.stageWidth,stage.stageHeight);
panorama.mask = null;
full_btn.x = stage.stageWidth-22;
full_btn.y = 22;
} else {
left_sidebar.visible = bottom_bar.visible = left.visible = right.visible = up.visible = down.visible = zoomin.visible = zoomout.visible = true;
panorama.setArea(150,20,570,380);
panorama.mask = theMask;
full_btn.x = 672;
full_btn.y = 406;
}
}
function panoLoadWatcher(e:Event=null) {
if (panorama.externals.hotspots!=null) {
if (full_btn.visible == true) {
full_btn.visible = false;
}
if (left_sidebar.view1.alpha > 0.5) {
left_sidebar.view1.alpha = left_sidebar.view2.alpha = left_sidebar.view3.alpha = left_sidebar.view4.alpha = left_sidebar.view5.alpha = left_sidebar.view6.alpha = 0.5;
}
//
theBL = panorama.pano.bytesLoaded;
theBT = panorama.pano.bytesTotal;
thePL = panorama.pano.percentLoaded;
trace("PANO bytesLoaded?: "+theBL);
trace("PANO bytesTotal?: "+theBT);
trace("PANO percentLoaded?: "+thePL);
if (thePL >= 100) {
theBL = -1;
theBT = -1;
thePL = -1;
full_btn.visible = true;
left_sidebar.view1.alpha = left_sidebar.view2.alpha = left_sidebar.view3.alpha = left_sidebar.view4.alpha = left_sidebar.view5.alpha = left_sidebar.view6.alpha = 1.0;
removeEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
}
}
Again, I hope this code and project walkthrough is educational! if you're feeling benevolent, you might help support this site by purchasing one of Patrick's cheap-but-useful plugins for FPP (DropDown Menu, Grouped Hotspots, AutoHorizon anyone?). 
About the Embed Pano 101 example
I forgot to mention it!
http://www.wearemanifesto.com/
A co-worker/friend of my wife has recently opened a custom bicycle shop in Oakland. Manifesto is very cool, does great work and sells good things; they both spearhead and are a part of a neat community of artists and general good folk.
I started creating this tour for them gratis, and am not finished with it yet. I'll keep folks posted as to when it goes live.
The main Manifesto graphics and text style are borrowed from their site.
Cheers,
Patrick
Brilliant :)
Brilliant stuff Patrick
My AS3 is a little rusty hehe this is a nice tutorial to get up to speed
Thanks
Updated Embed Pano tutorial
Thanks Paulo (and all the off list responders)!
I've updated the code and project to account for a nasty little "bug", where FPP gets confused and keeps two panoramas visible on the screen. (flashpanos.com user Darkgfx found the bug over in the FPP forums).
Cheers,
Patrick
Hi Patrick, Great
Hi Patrick,
Great tutorial!
Im pretty new to FPP but im seeing advantages all the time.
I have tried to duplicate what you achieved here but end up with an interface that as yet does not show my pano's (New to flash/AS3/FPP/Stress
)...
Could you post the directory structure of this project & the contents of the setup.xml, I'm a little confused as to the naming convention of the pano's in the tutorial too... ie what is the pano name (is it pano_01.jpg/pano_02.jpg etc for example), vs the thumbnails inside each pano, what is the image name and location.
I know you probably have better things to do than answer newcomer questions (like making more great working examples like this) but im sure im not the only person out there itching to be half as creative as you =)
Keep up the good work!!
Cheers,
Rob
re: embed pano 101
Hi Rob:
Good to hear from you, and thanks for the kudos. I received your direct email, but I have been absolutely swamped.
If you go to the example from the tutorial (link), you can view source (or if in Safari, use Activity Viewer) to see what XML file is being loaded in. In this case it's at http://www.cheathamlane.net/tests/manifesto/base/_setup.xml . Feel free to peek!
Most of the work is being done in the Embed Pano Actionscript; the XML is pretty much there to handle the photo thumbnails (when in fullscreen).
I don't have the FLA to hand out, since all the code is right here in the tutorial.
In FPP, the "panoName" is actually the entire path to your panorama(s), minus the extension. I should have noted in the tutorial that I'm using Cube Faces, with a naming convention of "_b.jpg", "_d.jpg", and so on. This is what the following line is all about:
If you have a link to an online example of what you're testing with, or can post code/links, I'm happy to peek -- others might help out too.
Cheers!
Patrick
re: Embed Pano 101: working
Hi again Patrick,
I cant thank you enough for this tutorial, I've just this minute got my "rough" model working, no way near as great as yours, but as a proof of concept it does what it says on the tin.
The problems I encountered were mainly with my working knowledge of Flash CS3 and AS3, (a great example of this is leaving the dynamic txt Garden & Snow [line 104] in the AS3 from Denis's example of embedPanoWithFullscreen, but removing it from the stage in Flash..) this sort of thing is what slowed me down
Well, thanks again...
Keep up the great work,
Best Regards,
Rob
re: embed pano 101 success!
Hey Rob:
Thanks for the thanks, and I hope it all helped.
Yes, my issues always seem to be AS3 based -- generally an errant semicolon or some other thing that's easy to overlook (like removing text from the stage but not deleting a reference to it).
When you get something going, be sure to share a link!
Cheers,
Patrick
Hi again Patrick
Hi again Patrick,
Just "another quick question" if i may
I've placed an swf file with an embeded fla as a spot into my mockup.
My little problem is when I go full screen, so does the video.swf... obviously not intended, any ideas on a quick fix to this..?
I created the swf at 320 x 240 and had intended it to be toggled with a view/hide spot.
Regards,
Rob
Update: I found a fix for this using box instead of spot and the url pointing to flvplayer.swf?file=video.fla
But still I would like to find a way to use swf from spot without the fullscreen "issue"
embed pano 101: showing some items in fullscreen and not others
Hi Rob:
If you're loading your SWF into the container, then you'll need to look at the following function (also in above code block):
if (e.fullScreen) {
theMask.visible = left_sidebar.visible = bottom_bar.visible = left.visible = right.visible = up.visible = down.visible = zoomin.visible = zoomout.visible = false;
panorama.setArea(0,0,stage.stageWidth,stage.stageHeight);
panorama.mask = null;
full_btn.x = stage.stageWidth-22;
full_btn.y = 22;
} else {
left_sidebar.visible = bottom_bar.visible = left.visible = right.visible = up.visible = down.visible = zoomin.visible = zoomout.visible = true;
panorama.setArea(150,20,570,380);
panorama.mask = theMask;
full_btn.x = 672;
full_btn.y = 406;
}
}
You'll want to add it there.
If you're adding your video SWF in the FPP XML, then you'll need to add an FPP "onEnterFullscreen" and "onExitFullscreen" event to the Global area.
Cheers,
Patrick
Hi Patrick, I have the
Hi Patrick,
I have the fullscreen handler in place in my AS3
But the "onEnterFullscreen" and "onExitFullscreen" is something i've not come across thus far in the global node...(The hotspots Global Object Parameters help file only relates to changing the colour of a button, and organising 2 other buttons)
The problem is im not sure what i want the global onEnterFullscreen/onExitFullscreen to do... other than not show my swf file fullscreen, when the whole pano goes fullscreen...
(I find it hard to learn without working examples, and this is why I find your site/tutorials a great asset!)
Regards,
Rob
re: onEnterFullscreen in FPP
Hey Rob:
(I find it hard to learn without working examples, and this is why I find your site/tutorials a great asset!)
Cool, understood, and thanks!... But also right back atcha: A link to a working example (or as working as it gets), or a good code example which you have, could be very helpful to see what it is you're trying to accomplish.
Cheers,
Patrick
patience for a newbie
Hi,
I've actually been using flash for a while, but only in pretty simple circumstances. I'm a little, or maybe a lot, confused, on how to implement this embed tutorial.
I think the big problem for me is the naming of all the various items. Are the names you've listed, view1 view2 etc the instance names I should be using for the various buttons and movie clips?
And more to the point, what should I be naming my pano movies? I'm planning to create a series of qtvr movies that I'd like to load. At the moment I have just one test. (I go live with this project on friday when I have to shoot a panorama on deadline)
Is each movie named pano_1, pano_2? and are these the .mov I generate?
In this line of code for exampe from your tutorial: panorama.loadPanorama("panoName="+thePanoToLoad+"&xml_file=base/_setup.xml");
do I replace panoname with something and if so what?
sorry for the questions if they're stupid...maybe it's me
but if you have time to offer some help or direction I'd be grateful.
many thanks
will
re: embed Pano 101: patience for a newbie
Hi there:
No worries -- No tutorial/documentation is ever perfect, right?
Things like view1, view2, etc are the instance names for the buttons/movieclips.
For the panoNames, if you want to follow the tutorial exactly, the following two scripts from the above tutorial code show you what they are (respectively for the low-res and hi-res panoramas):
var obj:Object = event.target;
var whichButton = obj.name;
switch (whichButton) {
case "view1" :
thePanoToLoad = "panos/small/pano_1/_bracketed_1";
theCurrentPano = "1";
break;
case "view2" :
thePanoToLoad = "panos/small/pano_2/_bracketed_1a";
theCurrentPano = "2";
break;
case "view3" :
thePanoToLoad = "panos/small/pano_3/bracketed_1-flat";
theCurrentPano = "3";
break;
case "view4" :
thePanoToLoad = "panos/small/pano_4/_bracketed_1";
theCurrentPano = "4";
break;
case "view5" :
thePanoToLoad = "panos/small/pano_5/_bracketed_1a";
theCurrentPano = "5";
break;
case "view6" :
thePanoToLoad = "panos/small/pano_6/_bracketed_1";
theCurrentPano = "6";
break;
default :
thePanoToLoad = "panos/small/pano_1/_bracketed_1";
theCurrentPano = "1";
break;
}
//truncated the code block for readability
}
In FPP, the panoName is not just the filename of your panorama (whether a .mov, or a set of cube face files) -- it is the full path to your panorama file plus the filename-minus-extension. Example:
panos/small/pano_1/_bracketed_1You can see where I'm setting the
thePanoToLoadvariable with thepanoNameabove for low-resolution images; At the same time I settheCurrentPanowith a number which corresponds below for hi-resolution:if (stage.hasOwnProperty("displayState")) {
if (stage.displayState == StageDisplayState.FULL_SCREEN) {
stage.displayState = StageDisplayState.NORMAL;
} else {
stage.displayState = StageDisplayState.FULL_SCREEN;
switch (theCurrentPano) {
case "1" :
thePanoToLoad = "panos/large/pano_1/pano_1";
break;
case "2" :
thePanoToLoad = "panos/large/pano_2/pano_2";
break;
case "3" :
thePanoToLoad = "panos/large/pano_3/pano_3";
break;
case "4" :
thePanoToLoad = "panos/large/pano_4/pano_4";
break;
case "5" :
thePanoToLoad = "panos/large/pano_5/pano_5";
break;
case "6" :
thePanoToLoad = "panos/large/pano_6/pano_6";
break;
default :
thePanoToLoad = "panos/large/pano_1/pano_1";
break;
}
//truncated code for readability
One thing you'll notice is the actual filenames of the lo/hi-resolution images is different. See the comment above with a screenshot of my file structure. So, if I were using .mov files: For view2 I'd have a low-resolution QTVR named _bracketed_1a .mov and a hi-resolution QTVR named pano_2.mov.
Up at the very top of the Actionscript, see the line:
This is what sets up our tour with the first panorama's name and path.
thePanoToLoadis given the full path-to-pano, which is then used by:Does that help?
thanks
thank you it helped a lot. I had simplified things a bit, for several reasons. I'm just loading a single pano at this point. I still have a few bugs I'm trying to solve.
The pano loads fine on my site as a test:
http://willyurman.com/_FlashTest/RoundRochester.html
But on my newspaper site which has their own CSM, i get 'failed to load'. I'm assuming it's a path issue, but I can't figure out where - I've changed the path in the xml and in the .fla...nothing seems to work.
Smaller problems.
What would be the instance name of a button to stop the panorama from moving/reset it? I see those buttons in your test, but not sure what they are called.
Full screen. I actually have a full screen button on the .fla, but I'm not seeing it. somehow it is staying hidden after the pano loads...any idea what I've done wrong there?
I really appreciate your help.
thanks
will
so close....
Hi Patrick,
sorry - I keep bombarding you and other forums with questions. I've modified/simplified your embed tutorial:
willyurman.com/_NewAttempt/RoundRochesternew.html
I've gotten most of what I need to work at the moment. But I'm stuck on fullscreen.
if you click the button, you'll see it sort of goes full screen, but seems to stay contrained by the Flash shell around it.
any idea what I'm doing wrong? Below is the actionscript I've got in place - basically a butchered version of your code.
thanks for any help you can offer.
best,
will
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.events.*;
import flash.net.URLRequest;
import fl.transitions.Tween;
import fl.transitions.*;
import fl.transitions.easing.*;
var panorama:MovieClip;
var loader:Loader = new Loader();
loader.load(new URLRequest("pano.swf"));
addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
function loadComplete(e:Event) {
swapChildren(loader, border);
panorama = loader.content;
panorama.setArea(1,40,900,500);
panorama.loadPanorama("xml_file=pano.xml");
//Variants:
//panorama.loadPanorama("pano.swf?panoName=images/snow"); //load images/snow pano, old syntax
//panorama.loadPanorama("panoName=images/snow&segments=10&pan=100"); //load images/snow with custom params
//panorama.loadPanorama("panoName=images/snow&xml_file=&"); //load images/snow without myPano.xml file
//panorama.loadPanorama("panoName=images/snow&xml_file=my.xml"); //load images/snow with custom xml file
//panorama.loadPanorama("xml_file=my.xml"); //load xml file (panoname within)
//panorama.loadPanorama("panoName=images/snow&layer_1=files/menuFullscreen.swf"); //load menuFullscreen plugin
//panorama.loadPanorama("xml_text="+xml_1); //load with predefined XML data
left_btn.addEventListener(MouseEvent.MOUSE_DOWN, doLeft);
right_btn.addEventListener(MouseEvent.MOUSE_DOWN, doRight);
up_btn.addEventListener(MouseEvent.MOUSE_DOWN, doUp);
down_btn.addEventListener(MouseEvent.MOUSE_DOWN, doDown);
zoomin.addEventListener(MouseEvent.MOUSE_DOWN, doZoomin);
zoomout.addEventListener(MouseEvent.MOUSE_DOWN, doZoomout);
stage.addEventListener(MouseEvent.MOUSE_UP, reset);
if (stage.hasOwnProperty("displayState")) {// check fullscreen feature is accessible or not
stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullscreenHandler);
full_btn.addEventListener(MouseEvent.CLICK, doFullscreen);
} else {
full_btn.visible=false;
}
}
function doLeft(e:Event) {
panorama.pano.panKey = -1;
}
function doRight(e:Event) {
panorama.pano.panKey = 1;
}
function doUp(e:Event) {
panorama.pano.tiltKey = 1;
}
function doDown(e:Event) {
panorama.pano.tiltKey = -1;
}
function doZoomin(e:Event) {
panorama.pano.zoomKey = 1;
}
function doZoomout(e:Event) {
panorama.pano.zoomKey = -1;
}
function reset(e:Event) {
panorama.pano.panKey = 0;
panorama.pano.tiltKey = 0;
panorama.pano.zoomKey = 0;
}
function doFullscreen(e:Event) {
if (stage.hasOwnProperty("displayState")) {
if (stage.displayState == StageDisplayState.FULL_SCREEN) {
stage.displayState = StageDisplayState.NORMAL;
} else {
stage.displayState = StageDisplayState.FULL_SCREEN;
switch (theCurrentPano) {
case "1" :
thePanoToLoad = "large/panoMidtown";
break;
default :
thePanoToLoad = "large/panoMidtown";
break;
}
if (thePL == -1) {
if (panorama.externals.hotspots!=null) {
if (panorama.externals.hotspots.panoName == thePanoToLoad) {
} else {
panorama.externals.hotspots.loadPano(["pano.swf?panoName="+thePanoToLoad]);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
} else {
panorama.pano.remove();
panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
}
}
}
}
function fullscreenHandler(e:FullScreenEvent) {
if (e.fullScreen) {
theMask.visible = left_sidebar.visible = bottom_bar.visible = left.visible = right.visible = up.visible = down.visible = zoomin.visible = zoomout.visible = false;
panorama.setArea(0,0,stage.stageWidth,stage.stageHeight);
panorama.mask = null;
full_btn.x = stage.stageWidth-22;
full_btn.y = 22;
} else {
left_sidebar.visible = bottom_bar.visible = left.visible = right.visible = up.visible = down.visible = zoomin.visible = zoomout.visible = true;
panorama.setArea(1,40,900,500);
panorama.mask = border;
full_btn.x = 672;
full_btn.y = 406;
}
}
success!!
With huge help from Patrick I've gotten full screen working. For those who are curious, he cleaned up some errant code - and pointed me in the right direction on a few other areas. I really appreciate the help.
The results should be posted in the next day or so at:
http://www.democratandchronicle.com/apps/pbcs.dll/article?AID=/20080726/...
click on the multimedia link on the right.
Thanks again Patrick !!
-will
re: success!!
Hi Will:
Glad I could help -- and it's looking good!
Cheers,
Patrick
great job!
Hi,
I'm pretty new to FPP (and, to be honest, anything Flash) and I'm amazed by what you can do with it!
Excellent tutorial, the irregular outline idea rocks! I wonder though if it's possible to create the skin using XML only, creating the irregular container outline as static images on top of the panorama. Four pieces - each for every side, and sized so that they will fill the larger monitor you expect potential visitors to have - would allow the creation of fullscreen layouts.
Eduard Popescu
www.revolvingpicture.com
re: adding border to full screen FPP presentation
Hi Eduard:
Thanks for the kudos!
Sure, absolutely -- you could use spot elements in an FPP XML to create a border around your panorama... This is your homework!
Extra credit is for making it work in both "normal" size and at full screen.
Cheers,
Patrick
"thinks out loud in a
"thinks out loud in a drunken stuper" 9-slice scaleing...
Just got in from a festival,
sorry for the spam
Regards,
Rob
multiple xml files
Hi Patrick,
Is it possible to use multiple xml files? Some of my panos require different xml settings, such as tilt, and zoom, audio...
I thought something like this might work:
var obj:Object = event.target;
var whichButton = obj.name;
var xmlToLoad = "1.xml";
switch (whichButton) {
case "view1" :
thePanoToLoad = "1_strip_thumb";
xmlToLoad = "1.xml";
theCurrentPano = "1";
break;
case "view2" :
thePanoToLoad = "2_strip_thumb";
xmlToLoad = "2.xml";
theCurrentPano = "2";
break;
case "view3" :
thePanoToLoad = "3_strip_thumb";
xmlToLoad = "3.xml";
theCurrentPano = "3";
break;
}
if (thePL == -1) {
if (panorama.externals.hotspots!=null) {
if (panorama.externals.hotspots.panoName == thePanoToLoad) {
} else {
panorama.externals.hotspots.loadPano(["pano.swf?panoName="+thePanoToLoad]);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
} else {
panorama.pano.remove();
//panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad);
panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad + "&xml_file=" + xmlToLoad);
}
}
}
But it didn't....
If it's not possible to load separate xml files for each pano, would it be possible to combine all the different settings into one xml file?
Thanks for your help,
Mark
re: multiple xml files
Hey Mark:
It should totally work -- One thing I see is you might want to put the full call into each part of the if/else block:
var obj:Object = event.target;
var whichButton = obj.name;
var xmlToLoad = "1.xml";
switch (whichButton) {
case "view1" :
thePanoToLoad = "1_strip_thumb";
xmlToLoad = "1.xml";
theCurrentPano = "1";
break;
case "view2" :
thePanoToLoad = "2_strip_thumb";
xmlToLoad = "2.xml";
theCurrentPano = "2";
break;
case "view3" :
thePanoToLoad = "3_strip_thumb";
xmlToLoad = "3.xml";
theCurrentPano = "3";
break;
}
if (thePL == -1) {
if (panorama.externals.hotspots!=null) {
if (panorama.externals.hotspots.panoName == thePanoToLoad) {
} else {
panorama.externals.hotspots.loadPano(["pano.swf?panoName="+thePanoToLoad+"&xml_file="+xmlToLoad]);
addEventListener(Event.ENTER_FRAME, panoLoadWatcher);
}
} else {
panorama.pano.remove();
//panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad);
panorama.loadPanorama("pano.swf?panoName="+thePanoToLoad + "&xml_file=" + xmlToLoad);
}
}
}
?
excellent tutorial
Thank you very much Patrick.
With this tutorial, we see the possibility to fully integrate FPP to a site web ! That's great !
Embedded XML into AS3
One area that this tutorial doesn't address is the possibility of embedding all of the XML directly into the AS3 code...
Per the embedPano.fla file from Denis, you can embed XML directly like this:
<panorama>
<parameters>
panoName=images/snow
layer_1=files/fps.swf
panHome=100
</parameters>
</panorama>
and then call that code like this:
Now for my question...
Alot of XML files can get pretty complicated with alot of hotspots, plugins, etc... and the simplistic XML data described above isn't very realistic.
When I try to embed a much large, more complicated "working" XML file into my AS3, it no longer works. The pano loads but hangs on the call to the XML section...
Any ideas on what might need to change in the formatting of the XML code to make the parser within FPP happy? I'm not sure what it doesn't like... I'm going to try to trim out alot of stuff and see if a simplistic version will work at all. That way I can ensure that paths are correct... but I don't think that's the problem...
Ideas?
Embedded XML into AS3... Update
OK - so I've narrowed the problem down to a command like this:
I'm not sure what the conflict is between AS3 and the way FPP parses the XML data - but something in this line is killing it.
I've tried question marks before various characters like the "/" or "(" or ")", but that doesn't seem to help.
I'll search on XML parsing anomalies in general, but any guidance would be appreciated.
Thanks!
re: using XML in AS3 with FPP: :)
Yeah, you'll probably need to escape your XML string inside AS3 to make it 100% compiler friendly. One big thing I've noted with using AS3 & "inline" XML like Denis suggests with his example, is to make sure you end your XML block with a semicolon. The syntax can get pretty touchy.
You might also want to check the reference for the doctype and maybe even return your XML as a full string (
toXMLString()) -- Denis's example is pretty incomplete.See:
http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/index.html?fla...
(what, are you off panosalado?
)
Well - I've found that the
Well - I've found that the problem is with the loadPano command such as this:
loadPano(?panoName=images/name&pan=0&tilt=0&zoom=1&zoomMin=1&qualityStatic=best,500,fade)
The ampersand is a reserved character for XML docs and I don't think it's passing validation...
I've tried replacing it with a '~' but that isn't working wither...
I'll check the link you provided above and see what I can get worked out...
I have an urgent project that took me away from PS - but I definitely plan to go back. It is certainly my preference for sure going forward...
Thanks for the help and if you have any other ideas on an & sign workaround, I'd sure love to hear it!
OK - here's the
OK - here's the deal...
Bottomline - when AS3 brings in text as XML data, it automatically replaces all instances of
&with&.I tried using the replace() method to replace all of the
&instances back to&, but the problem is that I have to convert the XML data to a string first and as soon as I try to then stuff that "string" variable back into an XML variable, it undoes everything I just did with the replace() method.Unfortunately, there doesn't appear to be a XMLreplace() method that would allow me to replace characters at that level - only XML data elements...
This is really annoying.
I might just have to create methods within my parent SWF to complete the loadPano tasks (along with all of its variables separated by the ampersands)... uugh.
Man I can't wait to switch over to PS.
re: using XML in AS3 with FPP
Ah, OK -- makes sense. Since these are attributes, you can't use a CDATA either.
What if you use
&from the outset? That might work (unless Flash gets cute and changes your&to&amp;).?
[edit]
http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=15&...
Found that at Adobe forums. Not quite the same problem, but the solution may be implementable. Basically use a short, quick combo of toString() and RegExp to hack out that ampersand.
?
Well...
Well - I tried that already and it just keeps it as is...
I was hoping that replacing the
&with a?would have worked, but it only picks up the first parameter after the loadPano image file declaration...Uuugh!!
Could have converted to PS by now probably.
re: using XML in AS3 with FPP (also, using & or ? in code)
Hey there:
ARGH! Sounds like some RegExp is in your future.
One note: I think you may have just inadvertently helped me figure out a problem I've been having with the code-highlighting and search modules for Drupal. It seems that when wrapped in <code> tags, both & and ? can cause the Drupal install to choke.
If you wrap any of your code you want highlighted like so: <% <myElement attr="blah.htm?&somevar" /> %> , things will work fine, resulting in:
<myElement attr="blah.htm?&somevar" />.re: using XML in AS3 with FPP
If you're going to be setting up your XML in AS3 anyway -- you might look into building the XML programmatically. See "TEXT_NODE" and other entries at the adobe/flash documentation.
...Which you can use in conjunction with a snippet like the one at:
http://www.razorberry.com/blog/archives/2007/11/02/converting-html-entit...
re: XML and AS3
Funny... I had been messing with the razorberry stuff earlier today as well... Didn't help me - although I may not have been addressing the node of interest properly...
The first link you posted doesn't appear to work.
On the code snippets... - I was using a different set of tags using code and LT, GT symbols. It was crashing things everytime I tried to post - so that must have been the problem. Thanks for setting me straight.
Thanks for the help and I'll let you know once I get things figured out.
embedding rev128 ?
I went through the tutorial and I have it loading, but I don't see a "pano.swf" file in the example.zip I downloaded. I've got rev 128 (blog says 129... but file says 128?) and it loads, but I get an error traced saying:
xml: assets/Clipper Map/Court/PanoSalado.xml
px: 125
py: 85
pw: 700
ph: 480
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at ClippersTraining/pano_load_complete()
ModuleLoader: XML file undefined not found
Here's my loading code:
{
panoviewer.visible = true;
new Tween( panoviewer, "alpha", Regular.easeIn, 0, 1, 0.25, true );
// create a loader and load in the navigation.html file
// based on the button name
panoconfig.path = assetdir+"/"+e.target.name.substring(1);
viewer.xml = panoconfig.path+"/PanoSalado.xml";
trace("swf: "+viewer.swf);
trace("xml: "+viewer.xml);
var req:URLRequest = new URLRequest( viewer.swf );
// load in the pano swf
loader = new Loader();
loader.contentLoaderInfo.addEventListener( Event.COMPLETE, pano_load_complete );
loader.load(req);
panoviewer.addChild(loader);
}
public function pano_load_complete( e:Event ):void
{
// work with our loader object
panorama = loader.content as MovieClip;
trace("px: "+panoconfig.x);
trace("py: "+panoconfig.y);
trace("pw: "+panoconfig.width);
trace("ph: "+panoconfig.height);
panorama.setArea( panoconfig.x, panoconfig.y, panoconfig.width, panoconfig.height );
trace("xml: "+viewer.xml);
panorama.loadPanorama( "panoName="+panoconfig.path+"&xml_file=../"+viewer.xml );
// add a watcher event listener to the stage
addEventListener( Event.ENTER_FRAME, pano_load_watcher );
}
I think the "null property" error is because when I load the ModuleLoader.swf it can't find my XML file. Could this be a directory structure issue?
If I copy the the 4 swf files into my assets/..../Court dir and run the ModuleLoader.swf from there, it works great. The problem only exists when I try to load it into my main movie.
Help?
re: embedding rev128 ?
I went through the tutorial and I have it loading, but I don't see a "pano.swf" file in the example.zip I downloaded. I've got rev 128 (blog says 129... but file says 128?) and it loads, but I get an error traced saying:
xml: assets/Clipper Map/Court/PanoSalado.xml
px: 125
py: 85
pw: 700
ph: 480
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at ClippersTraining/pano_load_complete()
ModuleLoader: XML file undefined not found
Hey there:
Hmmm.... The first part of your post is referencing PanoSalado, and the code you show looks like code for embedding FPP. PanoSalado and FPP are very different animals...
?
If your question is fully a PanoSalado question, you might post it over in the PanoSalado forum:
http://flashpanos.com/forums/using-flash-deliver-panoramas/papervision-3...
Cheers,
Patrick
Failure after updating to FPP 2.3 (pano.swf)
Hey Guys!
I've beein using this "Embedding FPP panoramas in another Flash container (Embed Pano 101)"
Everything perfect, but when I moved to the new FPP version 2.3 (pano.swf) for FlashPlayer 10 I got this "error".
The pano doesn't work anymore, this is the flash OUTPUT
CubePanorama v2.3 loaded.
Load XML: vrs/champagne.xml
Load layer 1: files/hotspots.swf
Load layer 5: files/glassMeter.swf
Load layer 10: files/autorotator.swf
ReferenceError: Error #1065: Variable ContextMenuClipboardItems is not defined.
at flash.ui::ContextMenu/initLinkAndClipboardProperties()
at flash.ui::ContextMenu()
at PanoController/createContextMenu()
at PanoController/initHandler()
at PanoController/initFlash10()
Autorotator v2.2 successfully loaded.
Hotspots v2.2 successfully loaded.
GlassMeter v1.1 successfully loaded.
Load 0: vrs/champagne/champagne_f.jpg
Load 1: vrs/champagne/champagne_r.jpg
Load 2: vrs/champagne/champagne_b.jpg
Load 3: vrs/champagne/champagne_l.jpg
Load 4: vrs/champagne/champagne_u.jpg
Load 5: vrs/champagne/champagne_d.jpg
TypeError: Error #1006: value is not a function.
at CubePanorama/redraw()
at CubePanorama/loadImages()
at PanoController/loadImages()
at PanoController/loadComplete()
PANO bytesLoaded?: 1413418
PANO bytesTotal?: 1413418
PANO percentLoaded?: 100
TypeError: Error #1006: value is not a function.
at CubePanorama/redraw()
at CubePanorama/loadContent()
at CubePanorama/loadComplete()
TypeError: Error #1006: value is not a function.
at CubePanorama/redraw()
at CubePanorama/loadContent()
at CubePanorama/loadComplete()
TypeError: Error #1006: value is not a function.
at CubePanorama/redraw()
at CubePanorama/loadContent()
at CubePanorama/loadComplete()
TypeError: Error #1006: value is not a function.
at CubePanorama/redraw()
at CubePanorama/loadContent()
at CubePanorama/loadComplete()
TypeError: Error #1006: value is not a function.
at CubePanorama/redraw()
at CubePanorama/loadContent()
at CubePanorama/loadComplete()
TypeError: Error #1006: value is not a function.
at CubePanorama/redraw()
at CubePanorama/loadContent()
at CubePanorama/loadComplete()
ANY IDEA what am I doing, or what is happening here??
FPP v2.3 and EmbedPano
Hey there:
Roger's question got figured out:
Below is the info from this post:
hi,
According to Denis, you need two things to make embeded v2.3 working:
- flash cs4
- give more time to fpp to initialize.
His original post from his google group:
You can avoid these problems using 2 tricks.
Add additional pause before panorama calls (the player needs more time
for initialization in Flash 10):
loadComplete);
function loadComplete (e:Event) {
var t:Timer = new Timer(500,1);
t.addEventListener(TimerEvent.TIMER, initComplete);
t.start()
}
function initComplete (e:Event) {
...
}
And set Flash setting to "Flash Player 10" (you need Flash CS4).
New embedPano.fla uploaded to "Files".
If I will find the way how to use embedded player 2.3 in Flash CS3, I
will publish it.
Thanks,
Denis.
As I have no plan to upgrade to cs4 in the near future, I'm using a regx editor to change the version on the player manually.
Mostly, it works.
Yet, I'm still having a lot of mistakes in the debugger, from time to time. It doesn't prevent the pano from playing correctly, though.
It would be interesting to have the feedback from someone using flash cs4.
cu
Embed SWF should listen to Hotspots
Hey,
first of all, i would like to thank Patrick for the Embed Pano 101 - this really saved a lot of my time
I also modified your EmbedPano a bit so it fits my clients demands: new Design, multilevel-navi with thumbscroller ...
Then i added some hotspots (with the Hotspots-Plugin) to my tour - these work as well.
But the thing i don't get is:
When i navigate with the hotspots, how can i catch (or listen to) the current Panorama loaded, in my EmbedPano.swf? What I found out is to get the "panoName" with this code:
But how do i get the "id" or other attributes placed in the xml?
I would be happy bout a tip or a link to further information to my "problem".
thx,
rocco
re: fpp and accessing hotspots from embed pano
var myHotspotsObject:Object = loaderInfo.loader.hotspots;
For Embed Pano, you'll need to get a reference to the hotspots object, via panorama I think. Once you do that, then you can do things like:
var someOtherVar = someSpot.rotation;
Post back with the proper syntax for Embed Pano!
HTH,
Patrick
controlling pano tween function
Thanks Patrick! - your explanations "embed pano" are very helpful for me to startup in what i wanna do in future: Not to use easypanos tourweaver any more...
But i cant figure out how to control the loaded pano from within flash i.e. to move to a given pan-position.
I want to replace the xml-directive of a spot(button)
>... OnClick="pano.pan=-85,2000,strong;" <
by code in flash but could not find how to adress this!
Maybe i get a little help here?
Thank you!
Strange problem
Hey Patrick, I'm trying to use the code from the example file from the nadir rotation:
var hotspots:Object = loaderInfo.loader.hotspots;and put it into one of my own flash files. Obviously it works fine in the example but when I copy the code to my file and publish it, I get
1119: Access of possibly undefined property hotspots through a reference with static type flash.display:Loader.The code for my file is exactly the same as the example, but I must be missing something somehow, can you help me out here?
Also it seems weird in the example file that there is a sTimer = new Timer(50); but its never declared as a var? I dont get errors with that in the example, but in my file I have to add var to it or I get an error with sTimer as well. Anyway thanks in advance!
re: re: fpp and accessing hotspots from embed pano
Hey Patrick - thx for your answer.
You are right, i need the reference. But the thing (my problem
) is the following:
- my fullscreenbutton and some buttons which link directly to some panos are in the container
- the hotspots-plugin is loaded via xml
When you navigate with the hotspot-Buttons and then go fullscreen, the container doesnt know, which is the current Pano. I can use this code and listen to the attributes:
function spotWatcher(e:Event=null){
//this is tracing the value of id (it is "aussenaufnahme")
trace(panorama.externals.hotspots.getSpot("aussenaufnahme").getParam("id"));
//this is tracing the value of alt
trace(panorama.externals.hotspots.getSpot("aussenaufnahme").getParam("alt"));
}
this.addEventListener(Event.ENTER_FRAME, spotWatcher);
But how does the container get to know which is the current id?
I would be happy bout some advice! Thx,
rocco
re: accessing hotspots from embed pano
Hey Patrick, I'm trying to use the code from the example file from the nadir rotation:
var hotspots:Object = loaderInfo.loader.hotspots;and put it into one of my own flash files. Obviously it works fine in the example but when I copy the code to my file and publish it, I get
1119: Access of possibly undefined property hotspots through a reference with static type flash.display:Loader.The code for my file is exactly the same as the example, but I must be missing something somehow, can you help me out here?
Also it seems weird in the example file that there is a sTimer = new Timer(50); but its never declared as a var? I dont get errors with that in the example, but in my file I have to add var to it or I get an error with sTimer as well. Anyway thanks in advance!
Are you using that code in the embed pano setup? You'll probably need to use something slightly different to access the hotspots object. I haven't had a chance to go through and test it all out.
Check rocco's post which came in directly after yours -- he seems to be accessing spots and their infos.
re: fpp and accessing hotspots from embed pano
Hey Patrick - thx for your answer.
You are right, i need the reference. But the thing (my problem
) is the following:
- my fullscreenbutton and some buttons which link directly to some panos are in the container
- the hotspots-plugin is loaded via xml
When you navigate with the hotspot-Buttons and then go fullscreen, the container doesnt know, which is the current Pano. I can use this code and listen to the attributes:
function spotWatcher(e:Event=null){
//this is tracing the value of id (it is "aussenaufnahme")
trace(panorama.externals.hotspots.getSpot("aussenaufnahme").getParam("id"));
//this is tracing the value of alt
trace(panorama.externals.hotspots.getSpot("aussenaufnahme").getParam("alt"));
}
this.addEventListener(Event.ENTER_FRAME, spotWatcher);
But how does the container get to know which is the current id?
I would be happy bout some advice! Thx,
rocco
In the example above, I use
panorama.externals.hotspots.panoNameto get the current panorama's name. Is this what you're looking for? (seefunction doFullscreen ...above)re: controlling pano tween function
Thanks Patrick! - your explanations "embed pano" are very helpful for me to startup in what i wanna do in future: Not to use easypanos tourweaver any more...
But i cant figure out how to control the loaded pano from within flash i.e. to move to a given pan-position.
I want to replace the xml-directive of a spot(button)
>... OnClick="pano.pan=-85,2000,strong;" <
by code in flash but could not find how to adress this!
Using this Embed Pano 101 example, I think you'd want to say something like
panorama.pano.pan="blah"?
No, not exactly. This
No, not exactly. This project is kind of BIG
We have about 200 panoramas. On the website (where it is embed) you should be able to access the panorama, at the point that you are just reading about. For example you are on the site "Wellness", you should get the "Wellness-Panorama", on the site "Dining" you should get the "Dining-Panorama" and so on ... BUT ... you should shurely get your hotspots from every site you are accessing.
What we thought about was giving the SWF (the container) an ID, so it knows, which pano to load (with SWF Object 2):
var flashvars = {
rgID: "Dining"
};
Instead of the id we could also send the panoName, but this is not that "readable" because there are 6 subolders ---> you get long strings ... and we have about 200 panoramas (in different subfolders)
Also in the container i could much easier check, which is the current panorama by using the "switch ... case" in AS3 with the short strings.
I think, i need something like:
panorama.externals.hotspots.id;
to get the value of the current panorama (the panorama just showing).
I also need the current panorama again when going fullscreen.
I hope i could describe my situation (sorry for my english
)
Do you think there is a way?
re: using FlashVars with embed pano
Ah, OK... I think you have answered your own questions...
Where I have way up at the top):
var thePanoToLoad = "panos/small/pano_1/_bracketed_1";
var theCurrentPano = "1";
You should be able to get your FlashVars using something like:
var thePanoToLoad = myFlashVars.rgID;
var theCurrentPano = "1";
Of course,
var theCurrentPano = "1", was just my way to track panoramas by number for this example. You could also add a FlashVar for, say,pathToSubFolder, and so on.?
re: using FlashVars with embed pano
Patrick, i think you are right
i should split my flashVars for lets say "folderPath" and "rgID" an build it together in AS3.
maybe i wouldnt have thought that complicated if my path would not have been that long ... DOH
thank you so much for helping me. i'll send you a link, when the pano-tour is finished!
rocco
Patrick, thanks for
Patrick, thanks for answering!
In my application i want to use your doRight- and doLeft-functions for panning the panorama to given places around the 360 degrees. There are 5 persons in an office and clicking the left or right - button shoul pan the pano to the next right/left person.
I know the persons (hotspot-) pan-values and will have to adress them later on.
First of alls i tried to replace
function doRight(e:Event) { panorama.pano.panKey = 1; }
by
function doRight(e:Event) { panorama.pano.pan="-100,2000,elastic"; }
or
function doRight(e:Event) { panorama.pano.pan="-100"; }
leading to - "nothing happens" after clicking the button, no error either...
So what is wrong here?
thanks!
re: accessing hotspots from embed pano
Are you using that code in the embed pano setup? You'll probably need to use something slightly different to access the hotspots object. I haven't had a chance to go through and test it all out.
Check rocco's post which came in directly after yours -- he seems to be accessing spots and their infos.
Whoops I meant to post in the nadir rotation page. I am using the embed pano setup, but the nadir example works fine with it. I changed the code slightly in nadir.fla to access PAN instead of rotation and that worked fine. I made a new FLA and copied the same code from the nadir.fla and its not working.
Specifically, I get the error
1119: Access of possibly undefined property hotspots through a reference with static type flash.display:Loader.from this
hotspots = loaderInfo.loader.hotspots;
So my reference doesnt seem to be working for some reason. Works fine in the example but not a new file?