views:

746

answers:

4

Hi I used some code that I found, I think even from you guys the scale an external swf being loaded onto a background movie clip. Works great with the exception that it clips some text and creates some funny diagonal lines and some poor picture quality. I have a feeling that this is down to a slight difference in sizing some where along the line. The stage size is 2560 x 1440 being scaled down to any size, but as I mentioned I don't think the height and width are quite in sync for the widescreen format. Please help it is doing my head in.

Please have a look, I am not really a hand at AS3.

www.sirwin.co.uk

// perform initial size check

checkStageSize();

// register to re-check when stage size changes stage.addEventListener( Event.RESIZE, onResize, false, 0, true );

function onResize( e:Event ) {

checkStageSize();

}

// do the scaling here

function checkStageSize():void {

var wid:Number = stage.stageWidth;

var hi:Number = stage.stageHeight;

var needToScaleDown:Boolean = (wid < 0); // or some other test

if ( needToScaleDown ) {

    var scale:Number = wid/0;

    backgroundRectangle.scaleX = backgroundRectangle.scaleY = scale;

} else {

    backgroundRectangle.scaleX = backgroundRectangle.scaleY = 1;
}

}

stop(); var portRequest:URLRequest = new URLRequest("main.swf");

var portLoader:Loader = new Loader();

portLoader.load(portRequest); backgroundRectangle.addChild(portLoader);

A: 

I have got a bit nearer to fine tuning but not quite there I am using the following now they are clearer but not fully:

// perform initial size check

checkStageSize();

// register to re-check when stage size changes

stage.addEventListener( Event.RESIZE, onResize, false, 0, true );

function onResize( e:Event ) {

checkStageSize();

}

// do the scaling here

function checkStageSize():void {

var wid:Number=100 /backgroundRectangle.stage.stageWidth;
var hi:Number=100 / backgroundRectangle.stage.stageHeight;
this.backgroundRectangle.scaleX=this.backgroundRectangle.scaleY;
this.backgroundRectangle.scaleX=this.backgroundRectangle.scaleY;

this.backgroundRectangle.x = (100 - this.backgroundRectangle.width) * 0;
this.backgroundRectangle.x = (100 - this.backgroundRectangle.height) * 0;

}

Images are own website www.sirwin.co.uk goto personal work and then the second along titled unseen as they have the most problems

Scott
A: 

Hey Scott - Welcome.

There seem to be a couple of issues at play with your code. One is technical, the other is fundamental. Lets look at the fundamental side first

I had to decompile your file to see what exactly all of your code looked like (in this case - http://www.sirwin.co.uk/two.swf) This file is 1.9 mb, which is EXTREMELY large for a flash file containing some photos. A better approach would be to have these images in an external folder and load them up as needed dynamically. There are many advantages for this :

  • ease of update - no need to recompile a flash file
  • xml or php driven (for those that don't like to use xml, you could even generate the structure based off the folder structure in your directory using php)
  • when you get a little more adventurous in the code/oop department you could even look at hydrotiks queue loader class for loading in zip folders - http://blog.hydrotik.com/2008/10/29/queueloader-rev-31-major-update-usage/
  • you could even use a the flickr flash api to request sets from your flickr account and load in dynamically (i love this approach as it allows you to use flickr as a content management system of sorts)

I am not sure of your skill level, so lets tackle the technical issue first. Ignoring that your images are so big - you will need to make sure that smoothing is turned on, either via the library or via some code. The easiest, but labor intensive method is to double clikc on the image in the library and check "allow smoothing" to be turned on. Although with images this big there is likely going to be some jaggedness even with that turned on.

The second approach would involve writing a script to extract the bitmap data from the movieclip on the change of frame, deleting its contents, and drawing it back into the container with smoothing attribute set to true.

As for the code to do this, it would vary greatly for the method you use to generate the array of photos for each section - but the core of the code can be found here:

http://www.kaourantin.net/2005/12/dynamically-loading-bitmaps-with.html

But really, if you are going down this path you may as well just go the whole 9 yards.

In for a penny, in for a pound Hope this helps!

Beans
I tried the smoothing option and that made no difference, will look into extracting bitmap data so thank you will look into that. I will also re-think the gallery, but the main point is having large images,as the site is designed to good quality all the way (and down) up-to 27".Once again thank you
Scott
Oh and code wise (I am pants)
Scott
haha, we all started somewhere. I can help you out with some more examples of bitmap data and so on.I understand that you want your site to look good up to 27" monitor - and also that you are a photographer. Images are your trade. However, the people that are likely to hire you - how many have 27 inch monitors?My point being is that in catering for the minority (top end) you are hurting the people on the other end of the scale. One thing to look at would be having 2 folders, one for good quality (24 inch screens and down) and a higher res (for these lucky lucky sods with 27inch screens)
Beans
on a 24 inch screen your images in that section are only 435x650 yet you are storing them in a file at 667 x 1000!At the start of loading a section you can determine the stage dimensions and dynamic load based on the screen size. this was you are serving up great images, its easy to optimise, and you can achieve your bitmap smoothing with less hassle.
Beans
True about catering for top end and for those less fortunate.... I suppose I was maybe planning to far ahead for when I doing front covers of Vogue etc. (LOL) I will look into the stage dimension and dynamic load based on screen size.I suppose I am not doing that badly in designing the site from scratch and grabbing codes from here there and every where.And more importantly thank you, thank you, you are a GOD amongst men,
Scott
A: 

Thanks Beans I will look further into better ways for gallery, the main reason that I wanted the images within the SWF was when I have finished the design and changing any problems than I can lock and password protect so there is less chance of theft of imagery.

I have however got a greater improvement on the images although the clipping on the text (Mostly buttons) is annoying me know more than ever.

The code I changed to is:

stage.addEventListener(Event.RESIZE, resizeListener); stage.scaleMode=StageScaleMode.SHOW_ALL; stage.align=StageAlign.TOP_LEFT;

function resizeListener(e:Event):void { trace("stageWidth: " + stage.stageWidth + " stageHeight: " + stage.stageHeight);

// do the scaling here

var wid:Number=100/this.stage.stageWidth;
var hi:Number=100/this.stage.stageHeight;
this.stage.scaleX=this.stage.scaleY;
this.stage.scaleX=this.stage.scaleY;

this.stage.x = (100 - this.stage.width) * 0;
this.stage.x = (100 - this.stage.height) * 0;

}

Scott
A: 

Hi Again,

Using an .SWF to package your files isn't ideal for many reason, but i hadn't thought about the security aspect. Although of course - if its on the net, its not secure...

I whipped up a little demo for you this morning that can be found here:

demo: http://www.digital.leskiwis.com/sirwin/

download: http://www.digital.leskiwis.com/sirwin/sirwin.zip

Let me explain a few features:

  • it makes use of hydrotik's queueLoader class. It makes loading and monitoring a breeze
  • all assets are in compiled SWF's. One of the great features of the queue loading is drawing a SWF's frames as bitmap data (great for getting that smoothing down)
  • it uses a resizing event to make sure the image is resized to scale
  • All of the images in the swf are 720p sized (1024 x 720) so you get a good idea of how a big image scales smaller (and bigger on a 24 - 27 inch screen)

Resize listeners:

            stage.scaleMode = StageScaleMode.NO_SCALE;      // the standard top left align, add some no scaling and throw in the event listener
            stage.align = StageAlign.TOP_LEFT;
            stage.addEventListener(Event.RESIZE, resizePhoto, false, 0, true);   

Resize function: (we store the photoWidth and photoHeight variables once when the image is loaded so we dont have to check every frame)

        function resizePhoto(e:Event){

            var targetWidth = stage.stageWidth - buffer - photo.x       
            // this gives us the target width we want the photo. we can figure out what percent the image would need to be to make this, and use that as a scale mutiplication..

            var targetHeight = stage.stageHeight - buffer - photo.y     
            // this gives us the target height we want the photo. we can figure out what percent the image would need to be to make this, and use that as a scale mutiplication..               

            //note: add in some smart sizing on this - this means the photo resize stops when it hits a height or width limit..                             
            var wMult:Number = (targetWidth / photoWidth)   
            var hMult:Number = (targetHeight / photoHeight)

            if(wMult < hMult){
                photo.width =  photoWidth * wMult   
                photo.height = photoHeight * wMult
            }else{
                photo.width =  photoWidth * hMult   
                photo.height = photoHeight * hMult
            }
        }

While some of this is far from best practice, it has enough improvements for you to work with - while keeping some you in a comfort zone based on the code i saw in your files. If you need any clarification just yell. Here is the full code - you can download everything here: http://www.digital.leskiwis.com/sirwin/sirwin.zip

Enjoy!

package{

    import flash.ui.*;
    import flash.display.*;
    import flash.events.*;  
    import flash.text.*;
    import flash.geom.*;
    import flash.net.*; 
    import flash.utils.*;
    import flash.media.*

    import fl.controls.Button;

    import com.hydrotik.queueloader.QueueLoader;
    import com.hydrotik.queueloader.QueueLoaderEvent;
    import com.hydrotik.queueloader.QLManager;  


    public class Sirwin extends MovieClip { 

        var sec_PERSONAL:Array = ['Animals', 'Macro'];  // all of the topic sections... Note, the swf files need to match these names!          
        var sec_LENGTH:uint = 0;    // the length of the loaded array
        var sec_CUR:uint = 0;       // the length of the loaded array
        var bmp_ARRAY:Array = [];   // the container for the loaded section
        var buffer:uint = 10;       // buffer in pixels for button placement

        var _oLoader:QueueLoader = new QueueLoader();
        var photo:Sprite = new Sprite();        // holder for the photo to load into

        var nextBut:Button = new Button();      // attach the next button from the library
        var prevBut:Button = new Button();      // attach the prev button from the library

        var photoWidth:Number   // we store these as variables to improve performance, check once - not each time
        var photoHeight:Number  // we store these as variables to improve performance, check once - not each time


        public function Sirwin(){
            trace("initialising Document...");
            addEventListener(Event.ADDED_TO_STAGE, popStageVars);   // once the movie has been added to the stage, we can set up some more vars 
        }

        private function popStageVars(e:Event){
            trace("popping stage vars...")  
            removeEventListener(Event.ADDED_TO_STAGE, popStageVars);

            stage.scaleMode = StageScaleMode.NO_SCALE;      // the standard top left align, add some no scaling and throw in the event listener
            stage.align = StageAlign.TOP_LEFT;
            stage.addEventListener(Event.RESIZE, resizePhoto, false, 0, true);   

            _oLoader.addEventListener(QueueLoaderEvent.ITEM_COMPLETE, onItemComplete,false, 0, true);
            _oLoader.addEventListener(QueueLoaderEvent.ITEM_PROGRESS, onQueueProgress, false, 0, true);
            _oLoader.addEventListener(QueueLoaderEvent.QUEUE_COMPLETE, onQueueComplete,false, 0, true);                 

            photo.x = 180
            photo.y = buffer
            addChild(photo)

            setSections();
            setNav();
            toggleNav();                
        }


        function resizePhoto(e:Event){

            // set photo dimensions to match stage;
            photo.width = stage.stageWidth - buffer;
            photo.height = stage.stageHeight - buffer;

            // choose the larger scale property and match the other to it;
            ( photo.scaleX < photo.scaleY ) ? photo.scaleY = photo.scaleX : photo.scaleX = photo.scaleY;




        }


        public function setSections(){  // this function places the section buttons on the stage... not so neccesary if you make your own buttons

            for(var i:uint = 0; i < sec_PERSONAL.length; i++){  
                var but:Button = new Button();  // attach the button from the library
                but.label = sec_PERSONAL[i]     // give the button a label from the array of names
                but.x = buffer
                but.y = buffer*5 + (i * (buffer + but.height));                 
                but.addEventListener(MouseEvent.CLICK, loadSection, false, 0, true);    // weak handler for better garbage collection
                addChild(but)
            }
        }

        public function setNav(){   // this function places the nav buttons on the stage... better practice would be having their own class and dispatching mouse events to be listened for. Baby steps..
            nextBut.label = "Next >"
            nextBut.x = buffer
            nextBut.y = 350
            nextBut.addEventListener(MouseEvent.CLICK, navForward, false, 0, true);
            addChild(nextBut)               

            prevBut.label = "Previous <"
            prevBut.x = buffer
            prevBut.y = 400
            prevBut.addEventListener(MouseEvent.CLICK, navBack, false, 0, true);
            addChild(prevBut)
        }


        public function loadSection(e:MouseEvent){
            bmp_ARRAY = []; // reset the array to nothing
            var swf:String = convertFolderName(e.target.label, '_') + ".swf";   
            _oLoader.addItem("assets/"+swf, null, {title:"SWF Images", drawFrames:true});
            _oLoader.execute();                         
        }       

        public function loadPhoto(){
            while(photo.numChildren){
                    photo.removeChildAt(0);     // get rid of any existing photo
            }

            var bmp:Bitmap = new Bitmap(bmp_ARRAY[sec_CUR]);        // this gets the bitmap data from the array that has been loaded from the zip file
            bmp.smoothing = true;   // this should solve your smoothing issues
            photo.addChild(bmp);

            photoWidth = photo.width;   // update the photos height and width for easy ref              
            photoHeight = photo.height;
            resizePhoto(null);      // pass through a null event to avoid any compiler errors
        }


        public function convertFolderName(s:String, replacement:String):String{ // this function returns an underscore instead of a space                           
            var trimmedValue:String = s.replace(" ", replacement)
            return trimmedValue;
        }   


        public function updateCur(n:Number){                        
            sec_CUR += n;       // add a +1, or -1 to the current pointer
            displaying.text = "Displaying: " + (sec_CUR + 1) + "/" + sec_LENGTH;        // this updates the 'number of/how many' text. you need plus one to adjust for arrays starting at 0
        }

        public function navForward(e:MouseEvent){
            updateCur(1)
            toggleNav();
            loadPhoto();
        }

        public function navBack(e:MouseEvent){
            updateCur(-1)
            toggleNav();
            loadPhoto() 
        }


        public function toggleNav():void{   //this function decides if the next or back should be shown
            trace(sec_CUR + " - " + sec_LENGTH)
            nextBut.visible = (sec_CUR >= sec_LENGTH-1) ? false : true
            prevBut.visible = (sec_CUR <= 0) ? false : true

            if(sec_CUR < 0){
                sec_CUR = 0;    
            }

            if(sec_CUR >= sec_LENGTH-1){
                sec_CUR = sec_LENGTH-1; 
            }
        }

        // ----------------------------------------------------- queue loading event handlers


        public function onQueueProgress(event:QueueLoaderEvent):void {  // cheap preloading...
            trace("\t>>onQueueProgress: "+event.queuepercentage);
            displaying.text = "Loading: " + event.queuepercentage + "%";
        }

        public function onItemComplete(event:QueueLoaderEvent):void {
            trace("\t>> "+event.type, "item title: "+event.title + " type: " + event.fileType);
            if (event.title == "SWF Images") {
                bmp_ARRAY = [];
                for (var i:int = 0; i<event.bmArray.length; i++) {
                    var bm:BitmapData = event.bmArray[i]                
                    bmp_ARRAY.push(bm)
                }
            }
        }

        public function onQueueComplete(event:QueueLoaderEvent):void {
            trace("** "+event.type);

            sec_LENGTH = bmp_ARRAY.length
            sec_CUR = 0;

            updateCur(0)
            toggleNav();
            loadPhoto();                                            
        }               


    }       
}
Beans
Cheers for that I will have a go later.
Scott
in case anyone else finds this - as an update to my resize function, the code can be reduced to 3 lines (courtesy of http://labs.findsubstance.com/2008/07/07/as3-scaling-techniques/)New code has been updated.
Beans