ActionScript Learning 110622

6.22.2011

拡大縮小、ドラッグ&スローできるパネル。

マウス座標を中心に拡大縮小、ステージを中心に拡大縮小、慣性付きでドラッグ&スローできるパネルを制作する。

ダブルクリックでマウス座標を中心に拡大縮小、マウスホイールでステージを中心に拡大縮小します。

SAMPLE VIEW CODE


package {
	
	import flash.display.*;
	import flash.text.*;
	import flash.geom.*;
	import flash.events.*;
	import flash.ui.*;
	import flash.utils.*;
	
	import frocessing.color.*;
	

	public class NMain extends MovieClip {
		
		//-------------------------------------------------------------------------------- Properties

		private var _this:*;
		private var _stage:Stage;
		
		
		//-------------------------------------------------------------------------------- Constractor
		
		public function NMain() {
			
			_this = this;
			_stage = stage;
			
			_stage.quality = "low";
			
			_stage.scaleMode = StageScaleMode.NO_SCALE;
			_stage.align = StageAlign.TOP_LEFT;
			
			Init();
		}
		
		
		//-------------------------------------------------------------------------------- Function
		 
		/**
		 * initialize
		 */
		public function Init():void {

			setup();
		}
		
		/**
		 * setup
		 */
		private function setup():void {
			
			setup_main();
			
			setup_panel();
			
			setup_actions();
			
			stage_resize();
			_stage.addEventListener(Event.RESIZE, stage_resize);
		}
		//
		private function stage_resize(eo:* = null):void {
			
			_main.x = Math.round(_stage.stageWidth / 2);
			_main.y = Math.round(_stage.stageHeight / 2);
			
			panelresizeaction();
		}
		
		/**
		 * actions
		 */
		private function setup_actions():void {
			
			uptimer = 0;
			
			_stage.addEventListener(MouseEvent.MOUSE_DOWN, action_mousedown);
			_stage.addEventListener(MouseEvent.MOUSE_WHEEL, action_mousewheel);
		}
		//
		private function action_mousedown(eo:* = null):void {
			
			Mouse.cursor = "hand";
			
			_stage.removeEventListener(MouseEvent.MOUSE_DOWN, action_mousedown);
			_stage.addEventListener(MouseEvent.MOUSE_UP, action_mouseup);
			
			panelmove_start();
		}
		//
		private var uptimer:Number;
		
		private function action_mouseup(eo:* = null):void {
			
			Mouse.cursor = "auto";
			
			_stage.addEventListener(MouseEvent.MOUSE_DOWN, action_mousedown);
			_stage.removeEventListener(MouseEvent.MOUSE_UP, action_mouseup);
			
			panelmove_stop();
			
			if(getTimer() - uptimer < 300) action_doubleclick();
			
			uptimer = getTimer();
		}
		//
		private function action_mousewheel(eo:* = null):void {
			
			if(eo.delta > 0) zoomin();
			else zoomout();
		}
		//
		private function action_doubleclick(eo:* = null):void {
			
			zoommousecenter();
		}
		
		/**
		 * main
		 */
		private var _main:MovieClip;
		
		private function setup_main():void {
			
			_main = new MovieClip();
			
			_this.addChild(_main);
		}
		
		/**
		 * panel
		 */
		private var _panel:MovieClip;
		private var piecewid:Number;
		private var piecehei:Number;
		private var paneldefwid:Number;
		private var paneldefhei:Number;
		private var panelpiecelength:int;
		
		private function setup_panel():void {
			
			piecewid = 100;
			piecehei = 100;
			
			_panel = new MovieClip();
			
			var piecelength = 20;
			panelpiecelength = piecelength * piecelength;

			for(var i = 0; i < panelpiecelength; i ++) {
				
				var _piece = piece(i + 1);
				
				_piece.x = (i % piecelength) * piecewid - (piecelength * piecewid / 2);
				_piece.y = Math.floor(i / piecelength) * piecehei - (piecelength * piecehei / 2);
				
				_panel.addChild(_piece);
			}
			
			_main.addChild(_panel);
			
			paneldefwid = _panel.width;
			paneldefhei = _panel.height;
			
			stopmposx = 0;
			stopmposy = 0;
			
			downposx = 0;
			downposy = 0;
			
			zoomval = 1;
			
			zoommousecnt = 1;
		}
		/** */
		private var downposx:Number;
		private var downposy:Number;
		
		private function panelmove_start():void {
			
			downposx = _panel.mouseX;
			downposy = _panel.mouseY;
			
			actiontype = "drag";
			
			_panel.addEventListener(Event.ENTER_FRAME, panelaction);
		}
		/** */
		private var stopmposx:Number;
		private var stopmposy:Number;
		
		private function panelmove_stop():void {
			
			stopmposx = _main.mouseX;
			stopmposy = _main.mouseY;
			
			actiontype = "throw";
		}
		/** */
		private var actiontype:String;
		
		private function panelaction(eo:* = null):void {
			
			//trace("panelaction");
			
			var posx:Number;
			var posy:Number;
			var dposx = downposx * _panel.scaleX;
			var dposy = downposy * _panel.scaleY;
			var es:Number;
			
			if(actiontype == "drag") {
				
				es = .2;				
				posx = _main.mouseX - dposx;
				posy = _main.mouseY - dposy;
			}
			else if(actiontype == "throw") {
				
				es = .1;				
				posx = stopmposx - dposx;
				posy = stopmposy - dposy;
			}
			else if(actiontype == "resize") {
				
				es = .2;				
				posx = resizeposx;
				posy = resizeposy;
			}
			else if(actiontype == "zoom") {
				
				es = .4;
				posx = zoomposx;
				posy = zoomposy;
			}
			
			var limitposx = paneldefwid * zoomval / 2 - _stage.stageWidth / 2;// + piecewid * _panel.scaleX;
			var limitposy = paneldefhei * zoomval / 2 - _stage.stageHeight / 2;// + piecehei * _panel.scaleY;
			
				
			if(posx >= limitposx) posx = limitposx;
			else if(posx <= -limitposx) posx = -limitposx;
			
			if(posy >= limitposy) posy = limitposy;
			else if(posy <= -limitposy) posy = -limitposy;
			
			if(paneldefwid * zoomval <= _stage.stageWidth) posx = 0;			
			if(paneldefhei * zoomval <= _stage.stageHeight) posy = 0;

			_panel.x += (posx - _panel.x) * es;
			_panel.y += (posy - _panel.y) * es;
			
			_panel.scaleX += (zoomval - _panel.scaleX) * es;
			_panel.scaleY += (zoomval - _panel.scaleY) * es;
			

			if(actiontype == "throw" || actiontype == "resize" || actiontype == "zoom") {
				
				if(Math.abs(posx - _panel.x) < 1 && Math.abs(posy - _panel.y) < 1 && Math.abs(zoomval - _panel.scaleX) < .01 && Math.abs(zoomval - _panel.scaleY) < .01) {
					
					_panel.x = posx;
					_panel.y = posy;
					_panel.scaleX = zoomval;
					_panel.scaleY = zoomval;
					
					_panel.removeEventListener(Event.ENTER_FRAME, panelaction);
				}
			}
			
			for(var i = 0; i < panelpiecelength; i ++) {
				
				var _piece = _panel.getChildAt(i);
				
				var gpoint = _panel.localToGlobal(new Point(_piece.x, _piece.y));
				var hidelimit = 100 * _panel.scaleX;
				
				if(gpoint.x < -hidelimit || gpoint.x > _stage.stageWidth + hidelimit || gpoint.y < -hidelimit || gpoint.y > _stage.stageHeight + hidelimit) _piece.visible = false;
				else _piece.visible = true;
			}
			
		}
		/** */
		private var resizeposx:Number;
		private var resizeposy:Number;
		
		private function panelresizeaction():void {
			
			actiontype = "resize";
			
			resizeposx = _panel.x;
			resizeposy = _panel.y;
			
			_panel.addEventListener(Event.ENTER_FRAME, panelaction);
		}
		/** */
		private var zoomval:Number;
		private var zoomposx:Number;
		private var zoomposy:Number;
		//
		private function zoomin():void {
			
			if(zoomval >= 2) return;
			
			zoomval *= 1.2;
			
			if(zoomval > 2) zoomval = 2;
			
			zoomaction("stagecenter");
		}
		//
		private function zoomout():void {
			
			if(zoomval <= .2) return;
			
			zoomval *= .8;
			
			if(zoomval < .2) zoomval = .2;
			
			zoomaction("stagecenter");
		}
		//
		private var zoommousecnt:int;
		
		private function zoommousecenter():void {
			
			zoommousecnt ++;
			
			if(zoommousecnt == 1) zoomval = 1;
			else if(zoommousecnt == 2) zoomval = 1.5;
			else if(zoommousecnt == 3) {
				
				zoomval = 2;
				zoommousecnt = 0;
			}
			
			zoomaction("mouse");
		}
		/** */
		private function zoomaction(type:String):void {
			
			var oldscale = _panel.scaleX;
			var newscale = zoomval;
			
			var posx:Number;
			var posy:Number;
			
			if(type == "mouse") {
				
				posx = _panel.mouseX;
				posy = _panel.mouseY;
			}
			else if(type == "stagecenter") {
				
				if(zoomval <= 1) zoommousecnt = 0;
				else if(zoomval <= 1.5)zoommousecnt = 1;
				else if(zoomval <= 2) zoommousecnt = 2;
				else zoommousecnt = 3;
				
				var scenter = new Point(_stage.stageWidth / 2, _stage.stageHeight / 2);
				var pcenter = _panel.globalToLocal(scenter);
				
				posx = pcenter.x;
				posy = pcenter.y;
			}
			
			zoomposx = _panel.x - (posx * newscale - posx * oldscale);
			zoomposy = _panel.y - (posy * newscale - posy * oldscale);
			
			//if(paneldefwid * zoomval <= _stage.stageWidth) zoomposx = 0;			
			//if(paneldefhei * zoomval <= _stage.stageHeight) zoomposy = 0;
			
			actiontype = "zoom";
			
			_panel.addEventListener(Event.ENTER_FRAME, panelaction);
		}
		/** */
		private function zoomreset():void {
			
			zoomposx = 0;
			zoomposy = 0;
			
			zoomval = 1;
			
			actiontype = "zoom";
			
			_panel.addEventListener(Event.ENTER_FRAME, panelaction);
			
			trace(zoomval);
		}
		/** */
		private function piece(textnum:int):MovieClip {
			
			var colorhsl = new ColorHSL();
			colorhsl.s = .8;
			colorhsl.l = .8;
			
			colorhsl.h = textnum * 12;			
			
			var _piece:MovieClip = new MovieClip();
			_piece.cacheAsBitmap = true;
			
			var g = _piece.graphics;
			g.lineStyle(1, 0xEFEFEF, 1, false, "none");
			g.beginFill(0xFFFFFF, 1);
			g.drawRect(0, 0, piecewid, piecehei);
			g.endFill();
			
			//g.lineStyle(1, 0x222222, 1, false, "none");
			g.beginFill(colorhsl.value, 1);
			g.drawRect(10, 10, piecewid - 20, piecehei - 20);
			g.endFill();
			
			
			var _textmc = new textmc();			
			_piece.addChild(_textmc);
			
			var t = _textmc.getChildByName("t");
			
			t.width = 0;
			t.height = 0;
			t.autoSize = "left";
			t.multiline = false;
			t.wordWrap = false;
			//t.border = true;
			
			var f:TextFormat = new TextFormat();
			f.size = 1000;
			f.color = 0xFFFFFF;
			f.letterSpacing = -10;
			f.indent = 0;
			f.rightMargin = -new Number(f.letterSpacing);
			
			t.defaultTextFormat = f;			
			t.text = new String(textnum);
			
			_textmc.alpha = .9;
			_textmc.width = piecewid / 2;
			_textmc.scaleY = _textmc.scaleX;

			if(_textmc.height > piecehei / 4) {
				
				_textmc.height = piecehei / 4;
				_textmc.scaleX = _textmc.scaleY;
			}
			
			_textmc.x = Math.round((piecewid - _textmc.width) / 2);
			_textmc.y = Math.round((piecehei - _textmc.height) / 2);
			
			return _piece;
		}
	
	}
}


category : ActionScript / BetweenAS3 / Frocessing

Demonstrations

Feature Samples

Author

虹村 マキオウ (nizimura makiou)

猫と太極拳を愛する横浜在住のフリーランスクリエイターです。

logo

Demo and Sample

Category