/***************************************************************************** DragDirector class - Copyright 2003 Gavin Kistner, gavin@refinery.com - Reuse and modification permitted provided the previous line is included - v1.0 20031016 Initial Release Description Creating a new DragDirector object will cause an element to move within its parent objects space as the mouse is moved. You can specify a custom function to be called during the drag, and another for when the drag stops. This class requires the svglib_common.js to be included (See http://phrogz.net/tmp/svg/libraries/) DragDirector constructor ========================================= Parameters el The SVG element to drag. moveConstraint One of the DragDirector.moveConstraints constants moveMethod One of the DragDirector.moveMethods constants boundingRect An SVGRect object (properties: x,y,width,height) or a custom object with properties x1,y1,x2,y2 All values should be in the coordinate space of the elements parent object. Set any property to null will ignore that constraint. This parameter may be null. startDragFnc The functions to call when the element starts getting whileDragFnc dragged, is being dragged, and stops being dragged. stopDragFnc The functions will be passed: the event object the element being dragged the start location of the element (an SVG Point) the current location of the element (an SVG Point) Each parameter may be null. DragDirector.enableDrag(), .disableDrag() ========================================= Use these methods on a dragDirector instance to start and stop drag handling for the element associated with the director. Dragging is enabled by default when creating a new instance; there is no need to explicitly call enableDrag() unless youve previously disabled it. *****************************************************************************/ DragDirector.moveConstraints={ none:0, //the element may be dragged in any direction horizontalOnly:1, //the element may only move in the x direction (in object space) verticalOnly:2 //the element may only move in the y direction (in object space) }; DragDirector.moveMethods={ useXYProperties:0, //the element can be moved by setting its x or y attributes useTranslateTransform:1 //the element will be moved by adjusting a translate transform }; function DragDirector(el,moveConstraint,moveMethod,boundingRect,startDragFnc,whileDragFnc,stopDragFnc){ DragDirector.all.push(this); this.el=el; this.constrain=moveConstraint!=null?moveConstraint:DragDirector.moveConstraints.none; this.useXY=(moveMethod==DragDirector.moveMethods.useXYProperties); this.startFnc=startDragFnc?startDragFnc:null; this.moveFnc=whileDragFnc?whileDragFnc:null; this.stopFnc=stopDragFnc?stopDragFnc:null; if (boundingRect){ this.bounds=new Rect(); this.bounds.x1 = boundingRect.x!=null?boundingRect.x:boundingRect.x1!=null?boundingRect.x1:null; this.bounds.y1 = boundingRect.y!=null?boundingRect.y:boundingRect.y1!=null?boundingRect.y1:null; this.bounds.x2 = boundingRect.x2!=null?boundingRect.x2:this.bounds.x1!=null && boundingRect.width!=null?this.bounds.x1+boundingRect.width:null; this.bounds.y2 = boundingRect.y2!=null?boundingRect.y2:this.bounds.y1!=null && boundingRect.height!=null?this.bounds.y1+boundingRect.height:null; } this.enableDrag(); if (window.top){ if (top.detachEvent!=null) top.detachEvent('onunload',DragDirector.cleanup); if (top.attachEvent!=null) top.attachEvent('onunload',DragDirector.cleanup); } } DragDirector.prototype.enableDrag=function(){ this.el.addEventListener('mousedown',this,false) } DragDirector.prototype.disableDrag=function(){ this.el.removeEventListener('mousedown',this,false) } DragDirector.prototype.handleEvent=function(evt){ switch(evt.type){ case 'mousedown': this.startDrag(evt); break; case 'mousemove': this.trackDrag(evt); break; case 'mouseup': this.stopDrag(evt); break; } } DragDirector.prototype.startDrag=function(evt){ if (this.dontDrag) return; this.curLoc = svgRoot.createSVGPoint(); if (this.useXY){ this.curLoc.x=this.el.getAttribute('x')*1; this.curLoc.y=this.el.getAttribute('y')*1; }else{ if (trannyRE.test(this.el.getAttribute('transform'))){ this.curLoc.x = RegExp.$1*1; this.curLoc.y = RegExp.$2*1; } } this.startLoc=svgRoot.createSVGPoint(); this.startLoc.x=this.curLoc.x; this.startLoc.y=this.curLoc.y; this.offset=new Point(this.curLoc); var mouseClick = ObjectCoordsFromMouse(this.el.parentNode,evt); this.offset.x-=mouseClick.x; this.offset.y-=mouseClick.y; svgRoot.addEventListener('mousemove',this,false); svgRoot.addEventListener('mouseup',this,false); if (typeof(this.startFnc)=='function') this.startFnc(evt,this.el,this.startLoc,this.curLoc); evt.preventDefault(); return false; } DragDirector.prototype.trackDrag=function(evt){ var mouseClick = ObjectCoordsFromMouse(this.el.parentNode,evt); var x=this.offset.x+mouseClick.x; var y=this.offset.y+mouseClick.y; if (this.constrain!=DragDirector.moveConstraints.verticalOnly){ if (this.bounds) x=Math.max(Math.min(x,this.bounds.x2!=null?this.bounds.x2:Number.MAX_VALUE),this.bounds.x1!=null?this.bounds.x1:Number.MIN_VALUE); this.curLoc.x=x; } if (this.constrain!=DragDirector.moveConstraints.horizontalOnly){ if (this.bounds) y=Math.max(Math.min(y,this.bounds.y2!=null?this.bounds.y2:Number.MAX_VALUE),this.bounds.y1!=null?this.bounds.y1:Number.MIN_VALUE); this.curLoc.y=y; } if (this.useXY){ this.el.setAttribute('x',this.curLoc.x); this.el.setAttribute('y',this.curLoc.y); }else{ var oldT=this.el.getAttribute('transform').replace(/^translate\([^)]+\) ?/,''); var newT='translate('+this.curLoc.x+','+this.curLoc.y+')'; this.el.setAttribute('transform',newT+(oldT.length?(' '+oldT):'')); } if (typeof(this.moveFnc)=='function') this.moveFnc(evt,this.el,this.startLoc,this.curLoc); evt.preventDefault(); return false; } DragDirector.prototype.stopDrag=function(evt){ svgRoot.removeEventListener('mousemove',this,false); svgRoot.removeEventListener('mouseup',this,false); if (typeof(this.stopFnc)=='function') this.stopFnc(evt,this.el,this.startLoc,this.curLoc); evt.preventDefault(); return false; } DragDirector.all=[]; DragDirector.cleanup=function(){ var all=DragDirector.all; for (var i=0,len=all.length;i