views:

197

answers:

2

Hi, I'm using a class which applies a visual reflection-effect to defined movieclips. I use a reflection-class from here: link to source. It works like a charm except when I apply a rotation to the movieclip. In my case the reflection is still visible but only a part of it. What am I doing wrong? How could I pass/include the rotation to the Reflection-Class ? Thanks in advance!

This is how you apply the Reflection Class to your movieclip:

var ref_mc:MovieClip = new MoviClip(); 
addChild(ref_mc);
var r1:Reflect = new Reflect({mc:ref_mc, alpha:50, ratio:50,distance:0, updateTime:0,reflectionDropoff:1});

Now I apply a rotation to my movieclip:

ref_mc.rotationY = 30;

And Here the Reflect-Class:

package com.pixelfumes.reflect{
import flash.display.MovieClip;
import flash.display.DisplayObject;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.utils.setInterval;
import flash.utils.clearInterval;

public class Reflect extends MovieClip{
    //Created By Ben Pritchard of Pixelfumes 2007
    //Thanks to Mim, Jasper, Jason Merrill and all the others who 
    //have contributed to the improvement of this class

    //static var for the version of this class
    private static var VERSION:String = "4.0";
    //reference to the movie clip we are reflecting
    private var mc:MovieClip;
    //the BitmapData object that will hold a visual copy of the mc
    private var mcBMP:BitmapData;
    //the BitmapData object that will hold the reflected image
    private var reflectionBMP:Bitmap;
    //the clip that will act as out gradient mask
    private var gradientMask_mc:MovieClip;
    //how often the reflection should update (if it is video or animated)
    private var updateInt:Number;
    //the size the reflection is allowed to reflect within
    private var bounds:Object;
    //the distance the reflection is vertically from the mc
    private var distance:Number = 0;


    function Reflect(args:Object){
        /*the args object passes in the following variables
        /we set the values of our internal vars to math the args*/
        //the clip being reflected
        mc = args.mc;
        //the alpha level of the reflection clip
        var alpha:Number = args.alpha/100;
        //the ratio opaque color used in the gradient mask
        var ratio:Number = args.ratio;
        //update time interval
        var updateTime:Number = args.updateTime;
        //the distance at which the reflection visually drops off at
        var reflectionDropoff:Number = args.reflectionDropoff;
        //the distance the reflection starts from the bottom of the mc
        var distance:Number = args.distance;

        //store width and height of the clip
        var mcHeight = mc.height;
        var mcWidth = mc.width;

        //store the bounds of the reflection
        bounds = new Object();
        bounds.width = mcWidth;
        bounds.height = mcHeight;

        //create the BitmapData that will hold a snapshot of the movie clip
        mcBMP = new BitmapData(bounds.width, bounds.height, true, 0xFFFFFF);
        mcBMP.draw(mc);

        //create the BitmapData the will hold the reflection
        reflectionBMP = new Bitmap(mcBMP);
        //flip the reflection upside down
        reflectionBMP.scaleY = -1;
        //move the reflection to the bottom of the movie clip
        reflectionBMP.y = (bounds.height*2) + distance;

        //add the reflection to the movie clip's Display Stack
        var reflectionBMPRef:DisplayObject = mc.addChild(reflectionBMP);
        reflectionBMPRef.name = "reflectionBMP";

        //add a blank movie clip to hold our gradient mask
        var gradientMaskRef:DisplayObject = mc.addChild(new MovieClip());
        gradientMaskRef.name = "gradientMask_mc";

        //get a reference to the movie clip - cast the DisplayObject that is returned as a MovieClip
        gradientMask_mc = mc.getChildByName("gradientMask_mc") as MovieClip;
        //set the values for the gradient fill
        var fillType:String = GradientType.LINEAR;
        var colors:Array = [0xFFFFFF, 0xFFFFFF];
        var alphas:Array = [alpha, 0];
        var ratios:Array = [0, ratio];
        var spreadMethod:String = SpreadMethod.PAD;
        //create the Matrix and create the gradient box
        var matr:Matrix = new Matrix();
        //set the height of the Matrix used for the gradient mask
        var matrixHeight:Number;
        if (reflectionDropoff<=0) {
            matrixHeight = bounds.height;
        } else {
            matrixHeight = bounds.height/reflectionDropoff;
        }
        matr.createGradientBox(bounds.width, matrixHeight, (90/180)*Math.PI, 0, 0);
        //create the gradient fill
        gradientMask_mc.graphics.beginGradientFill(fillType, colors, alphas, ratios, matr, spreadMethod);  
        gradientMask_mc.graphics.drawRect(0,0,bounds.width,bounds.height);
        //position the mask over the reflection clip            
        gradientMask_mc.y = mc.getChildByName("reflectionBMP").y - mc.getChildByName("reflectionBMP").height;
        //cache clip as a bitmap so that the gradient mask will function
        gradientMask_mc.cacheAsBitmap = true;
        mc.getChildByName("reflectionBMP").cacheAsBitmap = true;
        //set the mask for the reflection as the gradient mask
        mc.getChildByName("reflectionBMP").mask = gradientMask_mc;

        //if we are updating the reflection for a video or animation do so here
        if(updateTime > -1){
            updateInt = setInterval(update, updateTime, mc);
        }
    }


    public function setBounds(w:Number,h:Number):void{
        //allows the user to set the area that the reflection is allowed
        //this is useful for clips that move within themselves
        bounds.width = w;
        bounds.height = h;
        gradientMask_mc.width = bounds.width;
        redrawBMP(mc);
    }
    public function redrawBMP(mc:MovieClip):void {
        // redraws the bitmap reflection - Mim Gamiet [2006]
        mcBMP.dispose();
        mcBMP = new BitmapData(bounds.width, bounds.height, true, 0xFFFFFF);
        mcBMP.draw(mc);
    }
    private function update(mc):void {
        //updates the reflection to visually match the movie clip
        mcBMP = new BitmapData(bounds.width, bounds.height, true, 0xFFFFFF);
        mcBMP.draw(mc);
        reflectionBMP.bitmapData = mcBMP;
    }
    public function destroy():void{
        //provides a method to remove the reflection
        mc.removeChild(mc.getChildByName("reflectionBMP"));
        reflectionBMP = null;
        mcBMP.dispose();
        clearInterval(updateInt);
        mc.removeChild(mc.getChildByName("gradientMask_mc"));
    }
}

}

A: 

I got it, I have to reset the bounds of the reflect Class: myReflectClass.setBounds(newWidth,newHeight);

algro
A: 

If you have set the height and the width of your bitmapData to the same width and height of the movieclip your reflecting, you will get 'cut off'

When you rotate your movieclip, it does effectively become wider... and taller - of course at this point you've already made the bitmapData canvas area at a set width -

What you need to do it collect the real width and height of the rotating movieclip and when you redraw the bitmapData, use the new values.

I cheated when I made the same thing and just made my bitmapData 1.5 (bounds.width * 1.5) times the size of the movieclip. But thats a hack and I' a bad person for doing it.

Glycerine