views:

2445

answers:

3

I have a MovieClip with and image inside that I can drag, resize and rotate.

I'm creating a little thumbview, so the user can se how it will look. This is essentially a small version of the main MovieClip.

How can I clone the MovieClip into a smaller one, so that when I drag, rotate or resize the image in the main MovieClip the small one will be updated with the changes.

I have tried BitmapData draw(), but it is too slow.

Any other solution?

Update
Here's the code I'm currently using:

import flash.display.Bitmap;
import flash.display.BitmapData;

function createThumbnail() {
 var bmd:BitmapData = new BitmapData(mcBig.width, mcBig.height, false, 0xFFBC1C); 
 bmd.draw(mcBig);
 var b:Bitmap = new Bitmap(bmd);
 b.smoothing = true;
 b.scaleX = 0.2;
 b.scaleY = b.scaleX;
 mcSmall.addChild(b);
}

the createThumbnail function is called on every drag,resize,rotate.

If someone has a better/faster way, let me know ;)

+1  A: 

My first solution was going to be BitmapData.draw() but you said that is too slow. The only other route I think is to propagate its appearance to another movie clip, e.g. have event listeners for when you rotate it, and set the rotation on the thumnail to match, depending on how much you can change this may take a lot of work. So BitmapData.draw might be your best option. I have used BitmapData.draw before and it never seemed to perform slow to me.

John Isaacks
A: 

If your MovieClip can be created with only a constructor, you might try:

//(stolen from http://www.dannyburbol.com/2009/01/movieclip-clone-flash-as3/)
public function duplicateDisplayObject(
                                source:DisplayObject,
                                autoAdd:Boolean = false
                                ):DisplayObject
{
    // create duplicate
    var sourceClass:Class = Object(source).constructor;
    var duplicate:DisplayObject = new sourceClass();

    // duplicate properties
    duplicate.transform = source.transform;
    duplicate.filters = source.filters;
    duplicate.cacheAsBitmap = source.cacheAsBitmap;
    duplicate.opaqueBackground = source.opaqueBackground;
    if (source.scale9Grid) {
        var rect:Rectangle = source.scale9Grid;
        // WAS Flash 9 bug where returned scale9Grid is 20x larger than assigned
        // rect.x /= 20, rect.y /= 20, rect.width /= 20, rect.height /= 20;
        duplicate.scale9Grid = rect;
    }

    // add to source parent’s display list
    // if autoAdd was provided as true
    if (autoAdd && source.parent) {
        source.parent.addChild(duplicate);
    }
    return duplicate;
}

It is not perfect (if your constructor needs arguments, or if the clip has been modified), but it is the best solution I have seen.

There is no explicit way in flash to clone a MC. :-(

PiPeep
+2  A: 

BitmapData drawing is extremely fast. You should try to modify your createThumbnail to reuse the bitmap and just redraw into it. Object instantiation is a big hit, so if you're creating a new BitmapData and Bitmap on every frame, that is probably the source of your problem.

import flash.display.Bitmap;
import flash.display.BitmapData;

private var _myThumb:Bitmap;            // you'll probably want to have one of these for each mcSmall instance, instead of a class-level variable - this is just here for sample reference
private var _myThumbData:BitmapData;

function createThumb() {
    _myThumbData = new BitmapData(mcBig.width, mcBig.height, false, 0xFFBC1C);
    _myThumb = new Bitmap(_myThumbData);
    _myThumb.smoothing = true;
    _myThumb.scaleX = _myThumb.scaleY = 0.2
    mySmall.addChild(_myThumb);
}

createThumb();    // call this just once per thumbnail

function createThumbnail() {    //call this every draw frame
        _myThumbData.draw(mcBig);
}
RickDT
Yes, but this only makes a bitmap copy of it, if it were, for example, an animation, or something with code, this would not work. This does however work in this situation, so +1 anyways.
PiPeep