最近在用FLEX做拓扑图的放大缩小功能时发现,采用放大缩小画布的方法,但是默认的是以原点(0,0),而不是以中心点放大缩小。后来参考了BirdEye(http://birdeye.googlecode.com/svn/trunk/ravis/RaVisExamples/example-binaries/RaVisExplorer.html)的原代码,采用整体移动画布上所有对象到中心点的方法来实现居中放大缩小。
目前有些产品采用原点放大缩小,如Twaver。
参考部分源代码:
public class VisualGraph extends Canvas implements IVisualGraph {
/**
* @inheritDoc
* */
public function get scale():Number {
return _scale;
}
/**
* @inheritDoc
* */
public override function get scaleY():Number
{
var curScale:Number;
curScale = super.scaleY;
var parentComp:DisplayObject = this.parent;
while(parentComp && !(parentComp is VisualGraph))
{
curScale *= parentComp.scaleY;
parentComp = parentComp.parent;
}
return curScale;
}
/**
* @inheritDoc
* */
public override function get scaleX():Number
{
var curScale:Number;
curScale = super.scaleX;
var parentComp:DisplayObject = this.parent;
while(parentComp && !(parentComp is VisualGraph))
{
curScale *= parentComp.scaleX;
parentComp = parentComp.parent;
}
return curScale;
}
/**设置画布缩放比例
* @private
* */
public function set scale(s:Number):void {
/* get the current value */
const s0:Number = _canvas.scaleX;
/* set the new value */
/* Fix Scaling problem (Scrollbar shouldn't scale with graph)*/
//scaleX = s;
//scaleY = s;
_canvas.scaleX = s;
_canvas.scaleY = s;
/* scroll to the center */
scroll(center.x * (1 - s / s0) / s, center.y * (1 - s / s0) / s,false); //实现居中方法
/* redraw the edges */
refresh();
/* remember the set value, this is probably unnecesary
* since the getter could just return the value of scaleX
* but anyway */
_scale = s;
}
/**
* @inheritDoc
* */
public function scroll(deltaX:Number, deltaY:Number, reset:Boolean):void {
var i:uint;
var children:Array;
var view:UIComponent;
children = _canvas.getChildren();
/* we walk through all children of the canvas, which
* are not the drawing surface and which are UIComponents
* (they should be all node views) and move them according
* to the scroll offset */
for each(view in children) {
if(view != _drawingSurface) {
//LogUtil.debug(_LOG, "scrolling view of:"+(view as IDataRenderer).data.id);
view.x += deltaX;
view.y += deltaY;
}
}
if(reset) {
_origin = new Point(0,0);
}
/* adjust the current origin of the canvas
* (not 100% sure if this is a good idea but seems
* to work) XXX */
_origin.offset(deltaX,deltaY);
/* we have to force the edges to redraw so they match the nodes*/
_forceUpdateEdges = true;
invalidateDisplayList();
//LogUtil.debug(_LOG, "Setting new origin to:"+_origin.toString());
}
}