A Flash Developer Resource Site

Results 1 to 7 of 7

Thread: Flipping a rectangle in 3D

  1. #1
    Member
    Join Date
    Apr 2002
    Location
    Finland
    Posts
    32

    Flipping a rectangle in 3D

    I'm doing a portfolio. When the user clicks another work open, the black background flips and the new work appears on top of it.
    See the transition sample.

    I want to do this in actionscript, because the works are of different sizes. I want the transition to be smooth with easing and all.

    So, I guess I need to draw a rectangle with lineTo commands and use the cos or sin (?) to get the perspective right...

    Anyone got any pre-made codes, so that I could just give the starting corner points & duration and then it would flip it?

    thanks,
    matti

  2. #2
    Member
    Join Date
    Apr 2002
    Location
    Finland
    Posts
    32
    Now I've managed to do the rotation with x coords:
    rotating rectangle

    The code looks like this:
    Code:
    origin = new Object();
    origin.x = 300;
    origin.y = 200;
    
    UpperRightStartX = 100;
    LowerRightStartX = 100;
    LowerLeftStartX = -100;
    UpperLeftStartX = -100;
    
    UpperRightStartY = -100;
    LowerRightStartY = 100;
    LowerLeftStartY = 100;
    UpperLeftStartY = -100;
    
    UpperRightY = UpperRightStartY+origin.y;
    LowerRightY = LowerRightStartY+origin.y;
    LowerLeftY = LowerLeftStartY+origin.y;
    UpperLeftY = UpperLeftStartY+origin.y;
    
    DrawRectangle = function () {
    	if (angle<360) {
    		angle = angle+10;
    		radians = angle*Math.PI/180;
    		UpperRightX = origin.x+Math.cos(radians)*UpperRightStartX;
    		LowerRightX = origin.x+Math.cos(radians)*LowerRightStartX;
    		UpperLeftX = origin.x-Math.cos(radians+3)*UpperLeftStartX;
    		LowerLeftX = origin.x-Math.cos(radians+3)*LowerLeftStartX;
    	} else {
    		angle = 0;
    	}
    	rectangle.clear();
    	rectangle.beginFill(0x000000, 100);
    	rectangle.lineStyle(1, 0x000000, 100);
    	rectangle.moveTo(UpperRightX, UpperRightY);
    	rectangle.lineTo(LowerRightX, LowerRightY);
    	rectangle.lineTo(LowerLeftX, LowerLeftY);
    	rectangle.lineTo(UpperLeftX, UpperLeftY);
    	rectangle.lineTo(UpperRightX, UpperRightY);
    	rectangle.endFill();
    };
    
    this.createEmptyMovieClip("rectangle", 1);
    rectangle.onEnterFrame = DrawRectangle;
    Next step is to calculate the y coords. I made a scheme to try to understand the behaviour of the y coords. When the rectangle's edge is in front, the y coords are at their highest. And lowest when in the back.

    I guess it is possible to calculate this extra height (and the minus in the back) to the y coords. But how?

    It would also be nice to be able to set the focal length to adjust the perspective...

  3. #3
    Member
    Join Date
    Apr 2002
    Location
    Finland
    Posts
    32
    JESHH, I managed to do a perspective effect to it!:
    flip2

    Code looks like this:

    Code:
    originX = 300;
    originY = 200;
    perspectiveFactor = 20;
    angleSteps=5;
    angleEnd=0;
    angle=-90;
    FlipDirection=1;
    
    UpperRightStartX = 100;
    LowerRightStartX = 100;
    LowerLeftStartX = -100;
    UpperLeftStartX = -100;
    
    UpperRightStartY = -100;
    LowerRightStartY = 100;
    LowerLeftStartY = 100;
    UpperLeftStartY = -100;
    
    DrawRectangle = function () {
    	if (angle<angleEnd) {
    		angle = angle+angleSteps;
    		radians = angle*Math.PI/180;
    		UpperRightX = originX+(FlipDirection*Math.cos(radians))*UpperRightStartX;
    		LowerRightX = originX+(FlipDirection*Math.cos(radians))*LowerRightStartX;
    		LowerLeftX = originX-(FlipDirection*Math.cos(radians+Math.PI))*LowerLeftStartX;
    		UpperLeftX = originX-(FlipDirection*Math.cos(radians+Math.PI))*UpperLeftStartX;
    				
    		UpperRightY = (UpperRightStartY+originY)+Math.sin(radians)*perspectiveFactor;
    		LowerRightY = (LowerRightStartY+originY)-Math.sin(radians)*perspectiveFactor;
    		LowerLeftY = (LowerLeftStartY+originY)-Math.sin(radians+Math.PI)*perspectiveFactor;
    		UpperLeftY = (UpperLeftStartY+originY)+Math.sin(radians+Math.PI)*perspectiveFactor;
    	}
    	
    	rectangle.clear();
    	rectangle.beginFill(0x000000, 85);
    	rectangle.lineStyle(2, 0x000000, 100);
    	rectangle.moveTo(UpperRightX, UpperRightY);
    	rectangle.lineTo(LowerRightX, LowerRightY);
    	rectangle.lineTo(LowerLeftX, LowerLeftY);
    	rectangle.lineTo(UpperLeftX, UpperLeftY);
    	rectangle.lineTo(UpperRightX, UpperRightY);
    	rectangle.endFill();
    	
    };
    
    if(this.rectangle==undefined){
    	this.createEmptyMovieClip("rectangle", 1);
    }
    rectangle.onEnterFrame = DrawRectangle;
    But how can I add some EASING effect to it?
    And I also want a back effect there (the animation is extended a little over the end point but comes back). How to do that?!

    Please heeelp!

  4. #4
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    using a tweening class/ function you can ease the motion/ progress.

    Anyway I´ve done something similar before as well- from my expierence it´s best to change the function DrawRectangle() in a way so that it can recieve a variable like percentage or simply "p" wich goes from 0 to 1 (0.5 thus 1/2 complete transition).

    When you then apply a tween function or class all you do is tween a single variable from 0-1 and using that variable each time on your rectangle function. That way you could easily add a button for tweening back or use the setInterval to tween back after the first tween has passed (time wise).

    If you never used or played with tween functions or classes a easy start might be the built in flash 7+ tween class- wich is pretty good explained here:
    http://www.kirupa.com/developer/actionscript/tween.htm

  5. #5
    Member
    Join Date
    Apr 2002
    Location
    Finland
    Posts
    32

    Done!

    I made it!
    Check it out: flip3

    Now I'm tweening the angle (when looked straight above the rectangle) and it works great. When the rectangle is flat the angle is 90 and when seen full, angle is 180:
    Code:
    Tween(_root, "angle", Back.easeOut, 90, 180, 2, true);
    Now I have three functions: flipIn, flipOut and flipOutIn. FlipIn and FlipOutIn needs rectangle width and height. FlipOut uses existing rectangle size.

    To get more elastic movement I made two separate tweens for upper and lower corner points. The upper-point-tween is a bit slower.

    Here's the code, I guess it could be more compact, but, I'm no pro.

    Code:
    //Import the tween classes
    import mx.transitions.Tween;
    import mx.transitions.easing.*;
    
    //Set the center point for the rectangle
    originX = 300; 
    originY = 200;
    
    //Set the perpective (0 none, 80 heavy)
    perspectiveFactor = 20;
    
    //Flip animation direction (1 or -1)
    FlipDirection=1;
    
    //Function for calculating the points 
    //according to the angle (looked from above the rectangle)
    //and drawing rectangle
    DrawRectangle = function () {
    	radians = angle*Math.PI/180;
    	radians2 = angle2*Math.PI/180;
    	UpperRightX = originX+(FlipDirection*Math.cos(radians2))*UpperRightStartX;
    	LowerRightX = originX+(FlipDirection*Math.cos(radians))*LowerRightStartX;
    	LowerLeftX = originX-(FlipDirection*Math.cos(radians+Math.PI))*LowerLeftStartX;
    	UpperLeftX = originX-(FlipDirection*Math.cos(radians2+Math.PI))*UpperLeftStartX;
    	UpperRightY = (UpperRightStartY+originY)+Math.sin(radians2)*perspectiveFactor;
    	LowerRightY = (LowerRightStartY+originY)-Math.sin(radians)*perspectiveFactor;
    	LowerLeftY = (LowerLeftStartY+originY)-Math.sin(radians+Math.PI)*perspectiveFactor;
    	UpperLeftY = (UpperLeftStartY+originY)+Math.sin(radians2+Math.PI)*perspectiveFactor;
    		
    	rectangle.clear();
    	rectangle.beginFill(0x000000, 85);
    	rectangle.lineStyle(2, 0x000000, 100);
    	rectangle.moveTo(UpperRightX, UpperRightY);
    	rectangle.lineTo(LowerRightX, LowerRightY);
    	rectangle.lineTo(LowerLeftX, LowerLeftY);
    	rectangle.lineTo(UpperLeftX, UpperLeftY);
    	rectangle.lineTo(UpperRightX, UpperRightY);
    	rectangle.endFill();
    };
    
    //Function for flipping IN (appearing) animation 
    flipIn = function(rectangleWidth, rectangleHeight) {
    	//Creates the rectangle if not existing
    	if(rectangle==undefined){
    		createEmptyMovieClip("rectangle", 1);
    		}
    	//Creates start corner points for rectangle
    	UpperRightStartX = rectangleWidth/2;
    	LowerRightStartX = rectangleWidth/2;
    	LowerLeftStartX = rectangleWidth/-2;
    	UpperLeftStartX = rectangleWidth/-2;
    	UpperRightStartY = rectangleHeight/-2;
    	LowerRightStartY = rectangleHeight/2;
    	LowerLeftStartY = rectangleHeight/2;
    	UpperLeftStartY = rectangleHeight/-2;
    	
    	//Start tweening the angle (looked above the rectangle)
    	var tweenAngleIn:Tween = new Tween(_root, "angle", Back.easeOut, 90, 180, 2, true);
    	var tweenAngleIn2:Tween = new Tween(_root, "angle2", Back.easeOut, 90, 180, 2.5, true);
    
    	//Draw the rectangle while angle changes according to the tween
    	tweenAngleIn2.onMotionChanged = function() {
    		rectangle.onEnterFrame = DrawRectangle; 
    		}
    };
    
    //Function for flipping OUT (disappearing) animation 
    flipOut = function() {
    	//Creates the rectangle if not existing
    	if(rectangle==undefined){
    		createEmptyMovieClip("rectangle", 1);
    		}
    
    	//Start tweening the angle (looked above the rectangle)
    	var tweenAngleOut:Tween = new Tween(_root, "angle", Back.easeIn, 180, 270, 2, true);
    	var tweenAngleOut2:Tween = new Tween(_root, "angle2", Back.easeIn, 180, 270, 2.1, true);
    	
    	//Draw the rectangle while angle changes according to the tween
    	tweenAngleOut2.onMotionChanged = function() {
    		rectangle.onEnterFrame = DrawRectangle; 
    		}
    };
    
    //Function for flipping OUT and IN (disappearing and appearing) animation 
    flipOutIn = function(rectangleWidth, rectangleHeight) {
    	//Creates the rectangle if not existing
    	if(rectangle==undefined){
    		createEmptyMovieClip("rectangle", 1);
    		}
    	//Start tweening the angle (looked above the rectangle)
    	var tweenAngleOut:Tween = new Tween(_root, "angle", Back.easeIn, 180, 270, 2, true);
    	var tweenAngleOut2:Tween = new Tween(_root, "angle2", Back.easeIn, 180, 270, 2, true);
    	
    	//Draw the rectangle while angle changes according to the tween
    	tweenAngleOut2.onMotionChanged = function() {
    		rectangle.onEnterFrame = DrawRectangle; 
    		}
    	
    	tweenAngleOut2.onMotionFinished = function() {
    		//Creates start corner points for rectangle
    		UpperRightStartX = rectangleWidth/2;
    		LowerRightStartX = rectangleWidth/2;
    		LowerLeftStartX = rectangleWidth/-2;
    		UpperLeftStartX = rectangleWidth/-2;
    		UpperRightStartY = rectangleHeight/-2;
    		LowerRightStartY = rectangleHeight/2;
    		LowerLeftStartY = rectangleHeight/2;
    		UpperLeftStartY = rectangleHeight/-2;
    		
    		//Start tweening the angle (looked above the rectangle)
    		var tweenAngleIn:Tween = new Tween(_root, "angle", Back.easeOut, 90, 180, 2, true);
    		var tweenAngleIn2:Tween = new Tween(_root, "angle2", Back.easeOut, 90, 180, 2.2, true);
    		
    		//Draw the rectangle while angle changes according to the tween
    		tweenAngleIn2.onMotionChanged = function() {
    			rectangle.onEnterFrame = DrawRectangle; 
    			}
    		}
    };
    
    //buttons
    button1.onRelease = function(){
    	flipIn(200,200);
    	}
    button2.onRelease = function(){
    	flipOut();
    	}
    button3.onRelease = function(){
    	flipOutIn(400,200);
    	}
    Nothing is enough : Do you think that there's a way to do this with a movieclip?
    Let's say I have a vector drawing I want to flip. Is there a way to distort movieclip some how?
    -

  6. #6
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    if you want to distort them in perspective you need to devide the surface into triangles (2 triangles at least,- the more the clearer the result)

  7. #7
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    I browsed on some backUp disc´s of mine for some things you might find usefull for your project right now:


    my attempt about a year ago,- for a memory game without perspective distortion- but with an interesting control mechanic ich reached by flipping the card on a certain mirror axis wich is aligned to the mouse direction while dragging:

    swf:
    http://www.renderhjs.net/bbs/flashki...rd_flip011.swf
    fla:
    http://www.renderhjs.net/bbs/flashki...rd_flip011.fla

    simple 3d box with 2 triangles on each face:

    swf:
    http://www.renderhjs.net/bbs/flashki.../cube_test.swf
    fla:
    http://www.renderhjs.net/bbs/flashki.../cube_test.fla

    hope those are usefull to you

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center