pv3d可以做出很多不错的交互效果,尽管他更新脚步已经放缓,在这一年max 大会当中也没有出现大会面前,但是不得不说,pv3d 的易用性和交互效果依旧可以做出很多让人满意的作品。今晚无聊玩了一下这些图片墙,这种图片叫平面墙,利用图片组成一堵墙用于显示和交互。这种平面墙难度指数很低,而今晚当中,更加喜欢记录摄影机的缓冲效果。摄影机的缓冲效果可以让交互的时候产生更多让人酷的应用。要实现这种缓冲,则需要利用缓冲公式来实现。同时,使用摄影机的时候,对摄影机的平移可以改变视角的效果,看起来会呈现不同的视角变化。你所看到的因为摄影机平移而产生不同的变化。
主要需要看的是:摄影机运动 对视角产生变化
缓冲公式 , 产生缓冲效果,让效果过渡更加酷
这里主要是摄影机的缓冲效果。利用摄影机的运动对图片产生视角变化。
//缓冲镜头 camera.x += (distX - camera.x*0.5 ) * 0.3; camera.y += (distY -camera.y *0.5) * 0.3; contain.x += (distX - contain.x * 0.5) * 0.3; contain.z+= (distY- contain.z*0.8)*0.3;
package { import org.papervision3d.core.utils.Mouse3D; import org.papervision3d.events.InteractiveScene3DEvent; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.view.BasicView; import org.papervision3d.objects.primitives.Plane; import org.papervision3d.materials.ColorMaterial; import org.papervision3d.scenes.Scene3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.materials.*; import org.papervision3d.view.Viewport3D; import org.papervision3d.core.effects.view.ReflectionView; import org.papervision3d.core.render.filter.BasicRenderFilter; import org.papervision3d.core.utils.virtualmouse.*; import flash.filters.*; import flash.events.*; import flash.display.Sprite; import flash.utils.Dictionary; import flash.display.Bitmap; import flash.display.Loader; import flash.net.URLRequest; import flash.display.*; import com.greensock.TweenMax; import Plane2D; import ImageEx; [SWF(width="640", height="480", frameRate="30", backgroundColor="0x333333")] public class Main extends Sprite { private var pc:Plane = new Plane(); private var camera:Camera3D=new Camera3D();//摄影机 private var scene:Scene3D=new Scene3D();//场景 private var engine:BasicRenderEngine = new BasicRenderEngine();//渲染引擎 private var view:Viewport3D = new Viewport3D(640, 480, false, true);//视窗口 private var angle:Number = 0; private var h:int = 50; private var myImage:ImageEx = new ImageEx(); private var contain:DisplayObject3D; public function Main() { init3D(); } //初始化图片位置和设置 private function init3D():void { contain = new DisplayObject3D();//容器 for (var i:int=0; i<40; i++) { var cm:BitmapFileMaterial = new BitmapFileMaterial("wallimages/thumbs/"+(i+1)+".jpg"); var p:Plane2D = new Plane2D(cm, 100, 100); cm.interactive = true; cm.oneSide = false; p.x =(i%10)*100-stage.stageWidth/2-100; p.y =int(i/10)*100-stage.stageHeight/2+100; p.url = "wallimages/" + (i + 1) + ".jpg";//大图片路径 //p.rotationY = ( -i * perAngle) * (180 / Math.PI) + 270;//计算的偏移值 p.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, onMouseOverHandler); p.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, onMouseOutHandler); p.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, onMouseClickHandler); contain.addChild(p); } scene.addChild(contain); camera .z = 600; camera.target = pc; addChild(view); view.buttonMode = true; myImage.container.x = myImage.container.y = 0; addChild(myImage.container); addEventListener(Event.ENTER_FRAME,render); } private function onMouseOverHandler(event:InteractiveScene3DEvent):void { } private function onMouseOutHandler(event:InteractiveScene3DEvent):void { } private function onMouseClickHandler(event:InteractiveScene3DEvent):void { //判断这张图片是否第一次加载 if(myImage.getImage(event.currentTarget.url)==null) { myImage.loadImage(event.currentTarget.url); } else { myImage.showImage(event.currentTarget.url); } } private function render(event:Event):void { //距离检测 var distX:Number = (stage.mouseX) - stage.stageWidth * 0.5; var distY:Number = (stage.mouseY) - stage.height * 0.5; //平移镜头 // camera.x = distX*2; //camera.y = -distY * 2; //缓冲镜头 camera.x += (distX - camera.x*0.5 ) * 0.3; camera.y += (distY -camera.y *0.5) * 0.3; contain.x += (distX - contain.x * 0.5) * 0.3; contain.z+= (distY- contain.z*0.8)*0.3; engine.renderScene(scene, camera, view); } } }
package { import org.papervision3d.objects.primitives.Plane; import org.papervision3d.core.proto.MaterialObject3D; public class Plane2D extends Plane { //继承plane类,增加一个url 属性 public var url:String; public function Plane2D( material:MaterialObject3D=null, width:Number=0, height:Number=0, segmentsW:Number=0, segmentsH:Number=0 ) { super(material, width, height, segmentsW, segmentsH); } } }
package { import flash.events.EventDispatcher; import flash.utils.Dictionary; import flash.display.Sprite; import flash.display.Loader; import flash.display.Bitmap; import flash.events.*; import flash.net.*; import flash.filters.*; import com.greensock.TweenMax; public class ImageEx { private var tempURL:String; private var data:Dictionary = new Dictionary(true);//保存已经加载的图片 public var container:Sprite = new Sprite(); public function ImageEx() { } //添加图片 public function addImage(id:String,obj:*):void { data[id] = obj; } //获取图片 public function getImage(id:String):* { return data[id]; } //加载图片 public function loadImage(url:String):void { var loader:Loader = new Loader(); tempURL = url; loader.load(new URLRequest(url)) loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadImageComplete); loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onErrorHandler); } //加载图片-- 删除监听 private function onLoadImageComplete(event:Event):void { event.currentTarget.removeEventListener(Event.COMPLETE, onLoadImageComplete); event.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, onErrorHandler); var bmp:Bitmap = Bitmap(event.currentTarget.content); bmp.x = -bmp.width / 2; bmp.y = -bmp.height / 2; var contain:Sprite = drawBase(bmp, bmp.width, bmp.height); contain.addEventListener(MouseEvent.CLICK, onBackHandler); contain.addChild(bmp); container.addChild(contain); contain.x = container.stage.stageWidth / 2; contain.y = container.stage.stageHeight / 2; contain.scaleX = contain.scaleY = 0; contain.alpha = 0; TweenMax.to(contain, 0.5, { scaleX:1, scaleY:1, alpha:1 } ); addImage(tempURL, contain); } private function onErrorHandler(event:IOErrorEvent):void { throw new Error("wrong!"); } //显示图片 public function showImage(url:String):void { var contain:Sprite = getImage(url); container.addChild(contain); contain.x = container.stage.stageWidth / 2; contain.y = container.stage.stageHeight / 2; contain.scaleX = contain.scaleY = 0; contain.alpha = 0; TweenMax.to(contain, 0.5, { scaleX:1, scaleY:1,alpha:1 }); } private function onBackHandler(event:MouseEvent):void { var mc:*= event.currentTarget; TweenMax.to(mc, 0.5, { scaleX:0, scaleY:0, alpha:0, onComplete:removeContain } ); function removeContain():void { if(container.contains(mc)) container.removeChild(mc); } } //绘制底图背景 public function drawBase(bitmap:*, w:Number, h:Number, color:uint = 0xffffff):Sprite { var filter:DropShadowFilter=new DropShadowFilter(); filter.strength=0.3; var shape:Sprite = new Sprite(); shape.addChild(bitmap); shape.graphics.lineStyle(0,0,0); shape.graphics.beginFill(color); shape.graphics.drawRect(bitmap.x-w/60,bitmap.y-h/60,w+w/30,h+h/30); shape.graphics.endFill(); shape.filters = [filter]; return shape; } } }