• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 636
  • Last Modified:

AS3: Zooming in on an individual object in pv3d carousel

This is the question that was previously closed...

Okay now that I am able to target individual objects within this pv3d carousel, how do I go about creating a zoom effect to each individual objects without having to zoom in on the entire DisplayObject3D?

For example as the objects rotate, I want to be able to roll over/ and or click on the individual images and bring them closer while the other objects remain at their original distance.  I have been able to add an alpha tween to individual objects but not a scale, unless I am targeting the wrong object.

I am very close with the:
plane.moveForward(-200);
plane.moveForward(200);

...but it is very choppy, not smooth at all

As always all help is greatly appreciated, so Thanks!
package {
	import flash.events.Event;
	import br.com.stimuli.loading.BulkLoader;
	import br.com.stimuli.loading.BulkProgressEvent;
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
	import flash.filters.GlowFilter;
	import flash.display.MovieClip;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormatAlign;
	import flash.text.AntiAliasType;

	import gs.easing.Quint;
	import gs.TweenLite;
	import org.papervision3d.events.InteractiveScene3DEvent;
	import org.papervision3d.materials.BitmapMaterial;
	import org.papervision3d.objects.DisplayObject3D;
	import org.papervision3d.objects.primitives.Plane;
	import org.papervision3d.view.BasicView;
	import org.papervision3d.view.Viewport3D;
	import org.papervision3d.core.effects.view.ReflectionView;
	import org.papervision3d.materials.MovieMaterial;

	public class Main extends BasicView {
		protected var planes:Array=[];
		protected var images:Array=[];
		protected var numItems:Number;
		protected var currentItem:Number=3;
		protected var angle:Number=25;
		protected var rightBtn:Sprite;
		protected var leftBtn:Sprite;
		protected var xmlPath:String="xml/imageXML.xml";
		protected var bulkInstance:BulkLoader;
		private var carousel:DisplayObject3D=new DisplayObject3D  ;
		private var bitmapViewport:Viewport3D=new Viewport3D(940,300);

		private var view:ReflectionView;

		public function Main():void {
			super(940,300,true,true);

			addChild(bitmapViewport);
			bitmapViewport.interactive=true;
			loadXML();
		}

		//First load our XML
		protected function loadXML():void {
			bulkInstance=new BulkLoader("bulkInstance");
			bulkInstance.add(xmlPath);
			bulkInstance.addEventListener(BulkProgressEvent.COMPLETE,onXMLReady);
			bulkInstance.start();
		}

		//When our xml is ready parse and load our images
		protected function onXMLReady(evt:BulkProgressEvent):void {
			bulkInstance.removeEventListener(BulkProgressEvent.COMPLETE,onXMLReady);
			bulkInstance.addEventListener(BulkProgressEvent.COMPLETE,onImagesReady);

			var xml:XML=bulkInstance.getXML(xmlPath);
			var xmlList:XMLList=xml.image;

			for (var i:int=0; i<xmlList.length(); i++) {
				var imagePath:String=String(xmlList[i]);
				bulkInstance.add(imagePath);
				images.push(imagePath);
			}
			numItems=images.length;
		}
		protected function onImagesReady(evt:BulkProgressEvent):void {
			init();
		}
		protected function init():void {
			createChildren();
			startRendering();
		}
		protected function createChildren():void {
			for (var i:int=0; i<numItems; i++) {
				var mat:BitmapMaterial=new BitmapMaterial(bulkInstance.getBitmapData(images[i]));
				mat.interactive=true;
				mat.smooth=true;
				var plane:Plane=new Plane(mat,360,280);
				carousel.addChild(plane);
				plane.rotationY=360/numItems*i;
				plane.moveForward(900);
				planes.push(plane);

				//reflection should be implimented here///////////////////////////
				view=new ReflectionView(940,300,true,true);
				addChild(view);
				view.singleRender();


				var textMC:MovieClip=new MovieClip  ;
				var textField:TextField=new TextField  ;
				textField.wordWrap=true;
				textField.width=360;
				textField.height=280;
				textField.multiline=true;
				textField.text="Default Text Is the Default for the Text";
				textField.autoSize=TextFieldAutoSize.LEFT;
				textField.antiAliasType=AntiAliasType.ADVANCED;


				var textFormat:TextFormat=new TextFormat("Arial");
				textFormat.size=34;
				textFormat.color=0x000000;
				textFormat.bold=false;
				textField.setTextFormat(textFormat);
				//Create a rect the size of the MovieClip with an opacity of 0
				//This lets the TextField render properly
				textMC.graphics.beginFill(0x00ff00,0);
				textMC.graphics.drawRect(0,-400,360,280);
				textMC.graphics.endFill();
				textMC.addChild(textField);

				var tfMaterial:MovieMaterial=new MovieMaterial(textMC,true,false,true);
				tfMaterial.interactive=true;
				tfMaterial.smooth=true;
				tfMaterial.tiled=true;
				var tmpPlane:Plane=new Plane(tfMaterial,360,480);
				plane.addChild(tmpPlane);


				plane.id=i;
				plane.addEventListener(InteractiveScene3DEvent.OBJECT_OVER,onPlaneOver);
				plane.addEventListener(InteractiveScene3DEvent.OBJECT_OUT,onPlaneOut);
				plane.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS,onPlaneClick);
				scene.addChild(carousel);
				startRendering();
			}
			camera.zoom=80;
		}


		protected function onPlaneOver(evt:InteractiveScene3DEvent):void {
			var plane:Plane=evt.target as Plane;
			plane.moveForward(-200);
			trace("over");
		}
		protected function onPlaneOut(evt:InteractiveScene3DEvent):void {
			var plane:Plane=evt.target as Plane;
			plane.moveForward(200);
			trace("onPlaneOut");
		}
		protected function onPlaneClick(evt:InteractiveScene3DEvent):void {
			var plane:Plane=evt.target as Plane;
			trace("onPlaneClick");
		}

		override protected function onRenderTick(event:Event=null):void {
			carousel.rotationY-=viewport.containerSprite.mouseX/100;
			renderer.renderScene(scene,camera,bitmapViewport);
		}
	}
}

Open in new window

0
cubical38
Asked:
cubical38
  • 4
  • 2
1 Solution
 
TanLiHaoCommented:
If you want a tween-like effect, you should consider using a tween already. For example, you might be using TweenLite.

Anyway you should use moveBackward instead of using a negative number.

So to tween the moveBackward and forward, you can either use a shortcut, look at the .as file for DisplayObject3D and copy the function or simply use your understanding. Here I have did a step further, by showing you an example, just replace your functions with mine, but you have to use TweenLite.

You have to do these two imports first:
import org.papervision3d.core.math.Matrix3D;
import org.papervision3d.core.math.Number3D;

Replace your function onPlaneOver and onPlaneOut with the code below.

protected function onPlaneOver(evt:InteractiveScene3DEvent):void {
            var plane:Plane=evt.target as Plane;
           
            var distance:Number = 200;
            var BACKWARD:Number3D = new Number3D(0, 0, -1);
 
            Matrix3D.rotateAxis(plane.transform, BACKWARD);
 
            var target:Number3D = new Number3D();
            target.x = distance * BACKWARD.x + plane.x;
            target.y = distance * BACKWARD.y + plane.y;
            target.z = distance * BACKWARD.z + plane.z;            

            TweenLite.to(plane, 1, {x:target.x, y:target.y, z:target.z});
            trace("over");
        }
        protected function onPlaneOut(evt:InteractiveScene3DEvent):void {
            var plane:Plane=evt.target as Plane;
           
            var distance:Number = 200;
            var FORWARD:Number3D = new Number3D(0, 0, 1);
 
            Matrix3D.rotateAxis(plane.transform, FORWARD);
 
            var target:Number3D = new Number3D();
            target.x = distance * FORWARD.x + plane.x;
            target.y = distance * FORWARD.y + plane.y;
            target.z = distance * FORWARD.z + plane.z;            

            TweenLite.to(plane, 1, {x:target.x, y:target.y, z:target.z});    
            trace("onPlaneOut");
        }
0
 
cubical38Author Commented:
This works great except that the tween are miss firing at times.  Meaning: as you pass over a plane it sometimes zooms and then doesnt return to the original zoom, or it doesnt zoom then fades further back.  It there a way to keep the zoom and unzoom const?

Thanks again for all the work you have put in!

Its much appreciated...
0
 
TanLiHaoCommented:
Oh, that is because the tween have not completed and another tween is attempted to be fired. Thus, you need to instantly complete the tweens first or wait for the tween to complete. The more usual and better way is to kill the tween before the next tween is executed.

Therefore, this is the two new functions you should use:

protected function onPlaneOver(evt:InteractiveScene3DEvent):void {
            var plane:Plane=evt.target as Plane;
           
            var distance:Number = 200;
            var BACKWARD:Number3D = new Number3D(0, 0, -1);
 
            Matrix3D.rotateAxis(plane.transform, BACKWARD);
 
            var target:Number3D = new Number3D();
            target.x = distance * BACKWARD.x + plane.x;
            target.y = distance * BACKWARD.y + plane.y;
            target.z = distance * BACKWARD.z + plane.z;

           TweenLite.killTweensOf(plane);

            TweenLite.to(plane, 1, {x:target.x, y:target.y, z:target.z});
            trace("over");
  }
  protected function onPlaneOut(evt:InteractiveScene3DEvent):void {
            var plane:Plane=evt.target as Plane;
           
            var distance:Number = 200;
            var FORWARD:Number3D = new Number3D(0, 0, 1);
 
            Matrix3D.rotateAxis(plane.transform, FORWARD);
 
            var target:Number3D = new Number3D();
            target.x = distance * FORWARD.x + plane.x;
            target.y = distance * FORWARD.y + plane.y;
            target.z = distance * FORWARD.z + plane.z;
   
           TweenLite.killTweensOf(plane);

            TweenLite.to(plane, 1, {x:target.x, y:target.y, z:target.z});    
            trace("onPlaneOut");
}

0
Upgrade your Question Security!

Your question, your audience. Choose who sees your identity—and your question—with question security.

 
TanLiHaoCommented:
Sorry forgot something, change TweenLite.killTweensOf(plane); to TweenLite.killTweensOf(plane, true); in both the functions. That will force the tween to complete.
0
 
cubical38Author Commented:
This is working, but I am still having a little trouble when the mouse is not moving yet then moves off of a plane that the onPlaneOut still fires causing the plane to move further back the the rest.  This may be something that is inevitable.  Thanks for all the hard work!
0
 
TanLiHaoCommented:
It may be a bug with PaperVision3D or possibly not. I am not very familiar with how the internals of PaperVision3D works because I don't have time to take a look at everything.

However, there's a trick you can do. Define a boolean for each of the planes, give it a name like hasRolledOver. Set the value of it to false. When the OVER event fires, set the boolean to true. Then on the plane out event, check if the boolean is true before tweening. If the boolean is not true, simply do nothing or you might want to trace something for future reference so that you know there is a problem with this.
0

Featured Post

Learn to develop an Android App

Want to increase your earning potential in 2018? Pad your resume with app building experience. Learn how with this hands-on course.

  • 4
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now