|
import define from '../../define'; |
|
import * as is from '../../is'; |
|
import * as math from '../../math'; |
|
import * as util from '../../util'; |
|
|
|
let fn, elesfn; |
|
|
|
let beforePositionSet = function( eles, newPos, silent ){ |
|
for( let i = 0; i < eles.length; i++ ){ |
|
let ele = eles[i]; |
|
|
|
if( !ele.locked() ){ |
|
let oldPos = ele._private.position; |
|
|
|
let delta = { |
|
x: newPos.x != null ? newPos.x - oldPos.x : 0, |
|
y: newPos.y != null ? newPos.y - oldPos.y : 0 |
|
}; |
|
|
|
if( ele.isParent() && !(delta.x === 0 && delta.y === 0) ){ |
|
ele.children().shift( delta, silent ); |
|
} |
|
|
|
ele.dirtyBoundingBoxCache(); |
|
} |
|
} |
|
}; |
|
|
|
let positionDef = { |
|
field: 'position', |
|
bindingEvent: 'position', |
|
allowBinding: true, |
|
allowSetting: true, |
|
settingEvent: 'position', |
|
settingTriggersEvent: true, |
|
triggerFnName: 'emitAndNotify', |
|
allowGetting: true, |
|
validKeys: [ 'x', 'y' ], |
|
beforeGet: function( ele ){ |
|
ele.updateCompoundBounds(); |
|
}, |
|
beforeSet: function( eles, newPos ){ |
|
beforePositionSet( eles, newPos, false ); |
|
}, |
|
onSet: function( eles ){ |
|
eles.dirtyCompoundBoundsCache(); |
|
}, |
|
canSet: function( ele ){ |
|
return !ele.locked(); |
|
} |
|
}; |
|
|
|
fn = elesfn = ({ |
|
|
|
position: define.data( positionDef ), |
|
|
|
|
|
silentPosition: define.data( util.assign( {}, positionDef, { |
|
allowBinding: false, |
|
allowSetting: true, |
|
settingTriggersEvent: false, |
|
allowGetting: false, |
|
beforeSet: function( eles, newPos ){ |
|
beforePositionSet( eles, newPos, true ); |
|
}, |
|
onSet: function( eles ){ |
|
eles.dirtyCompoundBoundsCache(); |
|
} |
|
} ) ), |
|
|
|
positions: function( pos, silent ){ |
|
if( is.plainObject( pos ) ){ |
|
if( silent ){ |
|
this.silentPosition( pos ); |
|
} else { |
|
this.position( pos ); |
|
} |
|
|
|
} else if( is.fn( pos ) ){ |
|
let fn = pos; |
|
let cy = this.cy(); |
|
|
|
cy.startBatch(); |
|
|
|
for( let i = 0; i < this.length; i++ ){ |
|
let ele = this[ i ]; |
|
let pos; |
|
|
|
if( ( pos = fn(ele, i) ) ){ |
|
if( silent ){ |
|
ele.silentPosition( pos ); |
|
} else { |
|
ele.position( pos ); |
|
} |
|
} |
|
} |
|
|
|
cy.endBatch(); |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
silentPositions: function( pos ){ |
|
return this.positions( pos, true ); |
|
}, |
|
|
|
shift: function( dim, val, silent ){ |
|
let delta; |
|
|
|
if( is.plainObject( dim ) ){ |
|
delta = { |
|
x: is.number(dim.x) ? dim.x : 0, |
|
y: is.number(dim.y) ? dim.y : 0 |
|
}; |
|
|
|
silent = val; |
|
} else if( is.string( dim ) && is.number( val ) ){ |
|
delta = { x: 0, y: 0 }; |
|
|
|
delta[ dim ] = val; |
|
} |
|
|
|
if( delta != null ){ |
|
let cy = this.cy(); |
|
|
|
cy.startBatch(); |
|
|
|
for( let i = 0; i < this.length; i++ ){ |
|
let ele = this[i]; |
|
|
|
|
|
if (cy.hasCompoundNodes() && ele.isChild() && ele.ancestors().anySame(this)) { |
|
continue; |
|
} |
|
|
|
let pos = ele.position(); |
|
let newPos = { |
|
x: pos.x + delta.x, |
|
y: pos.y + delta.y |
|
}; |
|
|
|
if( silent ){ |
|
ele.silentPosition( newPos ); |
|
} else { |
|
ele.position( newPos ); |
|
} |
|
} |
|
|
|
cy.endBatch(); |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
silentShift: function( dim, val ){ |
|
if( is.plainObject( dim ) ){ |
|
this.shift( dim, true ); |
|
} else if( is.string( dim ) && is.number( val ) ){ |
|
this.shift( dim, val, true ); |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
|
|
renderedPosition: function( dim, val ){ |
|
let ele = this[0]; |
|
let cy = this.cy(); |
|
let zoom = cy.zoom(); |
|
let pan = cy.pan(); |
|
let rpos = is.plainObject( dim ) ? dim : undefined; |
|
let setting = rpos !== undefined || ( val !== undefined && is.string( dim ) ); |
|
|
|
if( ele && ele.isNode() ){ |
|
if( setting ){ |
|
for( let i = 0; i < this.length; i++ ){ |
|
let ele = this[ i ]; |
|
|
|
if( val !== undefined ){ |
|
ele.position( dim, ( val - pan[ dim ] ) / zoom ); |
|
} else if( rpos !== undefined ){ |
|
ele.position( math.renderedToModelPosition( rpos, zoom, pan ) ); |
|
} |
|
} |
|
} else { |
|
let pos = ele.position(); |
|
rpos = math.modelToRenderedPosition( pos, zoom, pan ); |
|
|
|
if( dim === undefined ){ |
|
return rpos; |
|
} else { |
|
return rpos[ dim ]; |
|
} |
|
} |
|
} else if( !setting ){ |
|
return undefined; |
|
} |
|
|
|
return this; |
|
}, |
|
|
|
|
|
relativePosition: function( dim, val ){ |
|
let ele = this[0]; |
|
let cy = this.cy(); |
|
let ppos = is.plainObject( dim ) ? dim : undefined; |
|
let setting = ppos !== undefined || ( val !== undefined && is.string( dim ) ); |
|
let hasCompoundNodes = cy.hasCompoundNodes(); |
|
|
|
if( ele && ele.isNode() ){ |
|
if( setting ){ |
|
for( let i = 0; i < this.length; i++ ){ |
|
let ele = this[ i ]; |
|
let parent = hasCompoundNodes ? ele.parent() : null; |
|
let hasParent = parent && parent.length > 0; |
|
let relativeToParent = hasParent; |
|
|
|
if( hasParent ){ |
|
parent = parent[0]; |
|
} |
|
|
|
let origin = relativeToParent ? parent.position() : { x: 0, y: 0 }; |
|
|
|
if( val !== undefined ){ |
|
ele.position( dim, val + origin[ dim ] ); |
|
} else if( ppos !== undefined ){ |
|
ele.position({ |
|
x: ppos.x + origin.x, |
|
y: ppos.y + origin.y |
|
}); |
|
} |
|
} |
|
|
|
} else { |
|
let pos = ele.position(); |
|
let parent = hasCompoundNodes ? ele.parent() : null; |
|
let hasParent = parent && parent.length > 0; |
|
let relativeToParent = hasParent; |
|
|
|
if( hasParent ){ |
|
parent = parent[0]; |
|
} |
|
|
|
let origin = relativeToParent ? parent.position() : { x: 0, y: 0 }; |
|
|
|
ppos = { |
|
x: pos.x - origin.x, |
|
y: pos.y - origin.y |
|
}; |
|
|
|
if( dim === undefined ){ |
|
return ppos; |
|
} else { |
|
return ppos[ dim ]; |
|
} |
|
} |
|
} else if( !setting ){ |
|
return undefined; |
|
} |
|
|
|
return this; |
|
} |
|
}); |
|
|
|
|
|
fn.modelPosition = fn.point = fn.position; |
|
fn.modelPositions = fn.points = fn.positions; |
|
fn.renderedPoint = fn.renderedPosition; |
|
fn.relativePoint = fn.relativePosition; |
|
|
|
export default elesfn; |
|
|