拡大縮小、ドラッグ&スローできるパネル。
マウス座標を中心に拡大縮小、ステージを中心に拡大縮小、慣性付きでドラッグ&スローできるパネルを制作する。
ダブルクリックでマウス座標を中心に拡大縮小、マウスホイールでステージを中心に拡大縮小します。
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;
}
}
}