Create A Slideshow Of Images
From Frontal Wiki
Frontal supports a few unique tags that do not have HTML equivalents, including the "manager" tag and the "transitioner" tag. With these tags, it's possible to group items for sequential display -- like in a slide show. (In this example, we're using the terms 'slideshow' and 'slide' because of their familiarity, but these tags are not specific to slide shows, and may be used to achieve many effects.) Let's start by defining a style sheet:
<style><![CDATA[ .slideshow { layout: stack; } manager { auto-play: true; hold-time: 90; hide-unselected: true; tween-container-init: true; } ]]></style>
Here we are defining a style class named '.slideshow', just as we would with CSS. And we've added the style 'layout: stack;' to stack the children elements one on top of the other, as opposed to flowed in a column the way HTML block elements would be. This will come in handy soon.
Next, we're setting some styles for all 'manager' tags. In the context of a slide show, these styles will cause the manager to automatically move through the slides ('auto-play: true;'), to hold 3 seconds on each slide ('hold-time: 90;' assuming 30 frames/sec), to hide any slides that aren't currently selected ('hide-unselected: true;') and to initialize any transition properties (like "alpha") on the slides ('tween-container-init: true;').
Now we're ready to create our slideshow. Here it is:
<div class="slideshow"> <manager> <transitioner custom="com.frontalcode.transitions.TweenTransition" target="current" property="alpha" start="1" finish="0" duration="15" /> <transitioner custom="com.frontalcode.transitions.TweenTransition" target="next" property="alpha" start="0" finish="1" duration="15" delay="15" /> </manager> <img src="http://www.frontalcode.com/assets/images/image_1.jpg" /> <img src="http://www.frontalcode.com/assets/images/image_2.jpg" /> <img src="http://www.frontalcode.com/assets/images/image_3.jpg" /> </div>
The first 'div' tag is used to group our slides together into a slide show. Then the 'manager' tag creates the slide show behaviors. In this case, it indicates that all of the visual elements should be treated as slides, in the same way. So, we have three image slides.
Inside of the 'manager' tag are two 'transitioner' tags. These tags indicate the effects that should be applied when moving from one slide to the next. In this example, we're simply fading out the current slide and then fading in the next slide. There may be as many transitioners as you like to handle complex transitions that affect multiple properties (like scaling, rotating, and translation all at the same time). There are also ways to limit transitioners to only affect specific document elements like, say, having the first and third slides rotate in while having the second slide scale in. See the section on the 'transitioner' tag for more details.
Here's how the code looks all together (click the run button below it to see how it works):
<style><![CDATA[ .slideshow { layout: stack; } manager { auto-play: true; hold-time: 90; hide-unselected: true; tween-container-init: true; } ]]></style> <div class="slideshow"> <manager> <transitioner custom="com.frontalcode.transitions.TweenTransition" target="current" property="alpha" start="1" finish="0" duration="15" /> <transitioner custom="com.frontalcode.transitions.TweenTransition" target="next" property="alpha" start="0" finish="1" duration="15" delay="15" /> </manager> <img src="http://www.frontalcode.com/assets/images/image_1.jpg" /> <img src="http://www.frontalcode.com/assets/images/image_2.jpg" /> <img src="http://www.frontalcode.com/assets/images/image_3.jpg" /> </div>
And here is a more advanced example that fills the stage, has controls and can go full screen. The code is highly commented to make it more understandable.
<!-- This Frontal document creates an image slideshow that fills the stage and has full screen capability. There are controls to move backwards and forwards in the slide show and to pause and resume it. There is also a control to put the movie in full screen mode and to take it out. First, load a font. We'll use it for the pause/resume button. --> <include rel="assets" blocking="true" src="http://www.frontalcode.com/assets.swf" fontClasses="SwiftLTStd, SwiftLTStdBold, SwiftLTStdItalic" /> <script><![CDATA[ // Here we are registering a custom style called custom-arrow-color. We'll // use this style to specify the color for our next and previous buttons and // our full screen button. We only need to register the custom style that we // want Frontal to process. In this case, when the custom-arrow-color // changes we want the value to be tweened and any affected elements to have // their backgrounds re-rendered so we register it. // document.stylesManager.registerStyle ( "custom-arrow-color", com.frontalcode.Util.colorVal, 0, { categories: [ 'backgroundFormat' ], isColor: true, processor: com.frontalcode.StylesManager.handleColorName } ); // This is a helper function to draw the previous and next button arrows. // function drawArrow ( elem, color, x, y, w, h, direction ) { elem.movie.graphics.lineStyle ( 0, color, 0 ); elem.movie.graphics.beginFill ( color ); elem.movie.graphics.moveTo ( x, y ); switch ( direction ) { case "right": elem.movie.graphics.lineTo ( x, y + h ); elem.movie.graphics.lineTo ( x + w, y + h / 2 ); break; case "left": elem.movie.graphics.lineTo ( x - w, y + h / 2 ); elem.movie.graphics.lineTo ( x, y + h ); break; } elem.movie.graphics.lineTo ( x, y ); elem.movie.graphics.endFill ( ); } ]]></script> <style><![CDATA[ document { // This will cause all the top-level elements to be placed at the // top left corner of the stage. // layout: stack; // This is the easing function used by our transitioner tags. // tween-container-ease: fl.transitions.easing.Regular.easeOut; // This is the easing function and duration to use when tweening a // style from one value to another. Simply by specifying these // styles, we have enabled style tweening. This is why, for example, // the button colors change smoothly on roll over. // style-tween-ease: fl.transitions.easing.Regular.easeOut; style-tween-duration: 10; } .slideshowContainer { // This causes all the images inside the slideshow to be absolutely // positioned relative to the top left corner of their parent. // layout: stack; } .slideshowContainer > manager { // With this style, when an image is unselected, it will be removed // from the display list. The exception is that during a transition // both the current and the next image are dispalyed. // hide-unselected: true; // This style says that when a transition starts, whatever property // the transitioner is tweening on the image should be set to the // value of the start attribute on the transitioner tag. The // alternative would be to tween from the image's current value. // tween-container-init: true; // These styles turn on auto play for the slide show. // auto-play: true; hold-time: 180; // This style says that if the slideshow is asked to pause in the // middle of a transition that it will first complete the transition // before acting on the request. // pause-at-transition-end: true; } // Here we're styling the div that contains all of the slideshow controls. // .slideshowControls { width: 109px; layout: stack; mouse-children: true; margin: 20px; z-index: 10; background-color: white; background-alpha: 0.8; padding: 8px; shadow-distance: 4; shadow-strength: 0.5; shadow-quality: 3; } // Here we're applying a drop shadow to each of the controls. // .slideshowControls > * { shadow-distance: 1; shadow-strength: 0.5; shadow-quality: 3; } // These next two rulesets make the controls inside the container change to // black on roll over. // .slideshowControls > div:hover { custom-arrow-color: black; } .slideshowControls > text:hover { background-color: black; } // This class draws the slideshow's previous button. It uses a lot of custom // styles mainly for reusability. Note that this doesn't add any // functionality. That will be done by applying the frButtonPrev style class // to the button. // .prevSlideArrow { custom-arrow-offset-x: 7; custom-arrow-offset-y: 5; custom-arrow-width: 6; custom-arrow-height: 7; custom-arrow-color: #f05300; background-color: pink; background-alpha: 0; width: 12px; height: 17px; @onRenderBackground { // With this interaction, we can draw a custom background // for this element. Here we do so only if needed and after // the system has drawn the default background requested by // our styles (a pink transparent rectangle). // if ( state == "afterRender" && bgNeedsRender ) drawArrow ( this, gS ( "custom-arrow-color" ), gS ( "custom-arrow-offset-x" ), gS ( "custom-arrow-offset-y" ), gS ( "custom-arrow-width" ), gS ( "custom-arrow-height" ), "left" ); } } // The next slide button is implemented similarly to the previous slide // button. // .nextSlideArrow { custom-arrow-offset-x: -7; custom-arrow-offset-y: 5; custom-arrow-width: 6; custom-arrow-height: 7; custom-arrow-color: #f05300; background-color: pink; background-alpha: 0; width: 12px; height: 17px; left: 72px; @onRenderBackground { if ( state == "afterRender" && bgNeedsRender ) drawArrow ( this, gS ( "custom-arrow-color" ), contentWidth + gS ( "custom-arrow-offset-x" ), gS ( "custom-arrow-offset-y" ), gS ( "custom-arrow-width" ), gS ( "custom-arrow-height" ), "right" ); } } // Here we style the pause/resume button. // .pauseButton { // This tells Frontal that this element is marking a manager tag. // Which manager will be determined by the element's mgrId // attribute. When marking a manager we will get notified on certain // events occurring. In this case we're interested in notifications // about the manager pausing and resuming. // is-marker: true; font-family: Swift LT Std; flash-text-anti-alias-type: advanced; font-size: 10px; height: 16px; padding-top: 1px; width: 52px; left: 16px; color: white; background-color: #f05300; text-align: center; @onPause { // When the manager pauses, we change our text to say // RESUME. // text = "RESUME"; } @onResume { // When the manager resumes, we change our text to say // PAUSE. // text = "PAUSE"; } @onClick { // Here we implement the pause and resume functionality. // This interaction is called when the element is clicked. // Then we resume the manager if it is paused and pause it // if it is not. // var mgr = gE ( gA ( "mgrId" ) ); if ( mgr.paused ) { mgr.resume ( ); } else { mgr.pause ( ); } } } // Here we implement the full screen button. // .fullScreenButton { height: 17px; width: 17px; left: 92px; background-color: white; background-alpha: 0; custom-arrow-color: #f05300; @onClick { // This interaction is called when the element is clicked. // It will put the movie into full screen mode or take it // out as appropriate. // document.movie.stage.displayState = document.movie.stage.displayState == "fullScreen" ? "normal" : "fullScreen"; } @onRenderBackground { // Here we draw the four little arrows that make up the full // screen button. // if ( state == "afterRender" && bgNeedsRender ) { for ( var x = 0; x <= 1; x++ ) { for ( var y = 0; y <= 1; y++ ) { var w = 11; var a = 4; var o = new flash.geom.Point ( 3, 3 ); movie.graphics.beginFill ( gS ( "custom-arrow-color" ) ); var pt = new flash.geom.Point ( x * w, y * w ); movie.graphics.moveTo ( o.x + pt.x, o.y + pt.y ); movie.graphics.lineTo ( o.x + pt.x + ( x == 0 ? a : -a ), o.y + pt.y ); movie.graphics.lineTo ( o.x + pt.x, o.y + pt.y + ( y == 0 ? a : -a ) ); movie.graphics.endFill ( ); } } } } } // Looking down at the transitioners for our slideshow we see this: // // <transitioner class="forwardTransition percentageTransition" custom="com.frontalcode.transitions.TweenTransition" target="current" property="left" start="0" finish="-100" duration="30" delay="0" /> // <transitioner class="forwardTransition percentageTransition" custom="com.frontalcode.transitions.TweenTransition" target="next" property="left" start="100" finish="0" duration="30" delay="0" /> // <transitioner class="backwardTransition percentageTransition" custom="com.frontalcode.transitions.TweenTransition" target="current" property="left" start="0" finish="100" duration="30" delay="0" /> // <transitioner class="backwardTransition percentageTransition" custom="com.frontalcode.transitions.TweenTransition" target="next" property="left" start="-100" finish="0" duration="30" delay="0" /> // // Note that they seemingly conflict. That is, both the first and third // transitioners are targeting the current image and tweening its "left" // style. The key is that only one will actually operate for any given // transition and which is determined by the forwardTransition and // backwardTransition style classes defined next. // // The forwardTransition style class defined here is saying that the // transitioner it is applied to will participate in the transition if the // current image comes before the next image or if we're looping from the // last to the first image. // .forwardTransition { // This interaction is called on every transitioner by the manager // to see if it will participate in the current transition. // @willHandleJump { return ( from == null || from.childIndex <= to.childIndex || ( from.childIndex == from.parent.containers.length - 1 && to.childIndex == 0 ) ) && ( to.childIndex != to.parent.containers.length - 1 || ( from != null && from.childIndex != 0 ) ); } } // The backwardTransition style class is very similar to forwardTransition // but indicates that the transitioner it is applied to will participate in // the transition if the current image comes after the next image or if // we're looping from the first to the last image. // .backwardTransition { @willHandleJump { return ( from != null && from.childIndex > to.childIndex && ( from.childIndex != from.parent.containers.length - 1 || to.childIndex != 0 ) ) || ( to.childIndex == to.parent.containers.length - 1 && ( from == null || from.childIndex == 0 ) ); } } // Since we don't know the dimensions of the stage, we want to specify the // start and end values of the transitions in percentages rather than fixed // numbers. This style class applied to a transitioner tag allows that. // .percentageTransition { // This interaction is called whenever a new value is needed from a // transitioner. If it is not defined then Frontal will simply // calculate the value from the numerical values of the start and // end attributes. That wouldn't work here though because the start // and end values aren't numbers - they have percent signs in them. // That's why we define this interaction. // @getStyleValue { var startValue = new Number ( getAttribute ( "start" ) ); var result = ( startValue + ( new Number ( getAttribute ( "finish" ) ) - startValue ) * progress ) + "%"; return result; } } // This will just cause are slideshow to fill the browser or the screen when // put in full screen mode. // .fullStageSlideshow { width: 100%; height: 100%; } // This ruleset will match all of our slideshow images. // .fullStageSlideshow img { // These styles will cause the images to fill the slideshow // container which itself is filling the stage. // width: 100%; height: 100%; // These styles are telling Frontal to scale the loaded image up // just large enough to fill this element's width and height and to // do so from the image's center. // resize-scale: showmost; resize-scale-origin: center middle; // We need to mask the images as they are potentially larger than // the element and so likely overlapping the other images. This // would make for ugly transitions without the mask. // overflow: hidden; // This makes the scaled image look nice. // allow-smoothing: true; @onFirstRender { // If an image is currently loading, the set our alphs to 0. // We'll fade in the image when it does load. // if ( loadingImage != null ) sS ( "alpha", 0 ); } @onLoaded { // The image has now loaded so fade it in. // prepStyleTween ( ); sS ( "alpha", 1 ); tweenStyles ( 10 ); } } ]]></style> <!-- This div holds all of our slideshow controls. --> <div class="slideshowControls"> <div class="frButtonPrev prevSlideArrow" mgrId="myMgr" /> <text class="pauseButton" mgrId="myMgr"><![CDATA[PAUSE]]></text> <div class="frButtonNext nextSlideArrow" mgrId="myMgr" /> <div class="fullScreenButton" /> </div> <!-- This div contains the slideshow of images. --> <div class="fullStageSlideshow slideshowContainer"> <!-- The manager tag turns its siblings (the img tags below) into a slideshow. --> <manager id="myMgr"> <!-- These transitioner tags say how to move from one image to another. In our case we move the images left to right or right to left. --> <transitioner class="forwardTransition percentageTransition" custom="com.frontalcode.transitions.TweenTransition" target="current" property="left" start="0" finish="-100" duration="30" delay="0" /> <transitioner class="forwardTransition percentageTransition" custom="com.frontalcode.transitions.TweenTransition" target="next" property="left" start="100" finish="0" duration="30" delay="0" /> <transitioner class="backwardTransition percentageTransition" custom="com.frontalcode.transitions.TweenTransition" target="current" property="left" start="0" finish="100" duration="30" delay="0" /> <transitioner class="backwardTransition percentageTransition" custom="com.frontalcode.transitions.TweenTransition" target="next" property="left" start="-100" finish="0" duration="30" delay="0" /> </manager> <img src="assets/images/image_8.jpg" /> <img src="assets/images/image_9.jpg" /> <img src="assets/images/image_10.jpg" /> <img src="assets/images/image_11.jpg" /> <img src="assets/images/image_12.jpg" /> </div>