Current File : //home/tradevaly/www/node_modules/svg.js/src/boxes.js |
SVG.Box = SVG.invent({
create: function(x, y, width, height) {
if (typeof x == 'object' && !(x instanceof SVG.Element)) {
// chromes getBoundingClientRect has no x and y property
return SVG.Box.call(this, x.left != null ? x.left : x.x , x.top != null ? x.top : x.y, x.width, x.height)
} else if (arguments.length == 4) {
this.x = x
this.y = y
this.width = width
this.height = height
}
// add center, right, bottom...
fullBox(this)
}
, extend: {
// Merge rect box with another, return a new instance
merge: function(box) {
var b = new this.constructor()
// merge boxes
b.x = Math.min(this.x, box.x)
b.y = Math.min(this.y, box.y)
b.width = Math.max(this.x + this.width, box.x + box.width) - b.x
b.height = Math.max(this.y + this.height, box.y + box.height) - b.y
return fullBox(b)
}
, transform: function(m) {
var xMin = Infinity, xMax = -Infinity, yMin = Infinity, yMax = -Infinity, p, bbox
var pts = [
new SVG.Point(this.x, this.y),
new SVG.Point(this.x2, this.y),
new SVG.Point(this.x, this.y2),
new SVG.Point(this.x2, this.y2)
]
pts.forEach(function(p) {
p = p.transform(m)
xMin = Math.min(xMin,p.x)
xMax = Math.max(xMax,p.x)
yMin = Math.min(yMin,p.y)
yMax = Math.max(yMax,p.y)
})
bbox = new this.constructor()
bbox.x = xMin
bbox.width = xMax-xMin
bbox.y = yMin
bbox.height = yMax-yMin
fullBox(bbox)
return bbox
}
}
})
SVG.BBox = SVG.invent({
// Initialize
create: function(element) {
SVG.Box.apply(this, [].slice.call(arguments))
// get values if element is given
if (element instanceof SVG.Element) {
var box
// yes this is ugly, but Firefox can be a pain when it comes to elements that are not yet rendered
try {
if (!document.documentElement.contains){
// This is IE - it does not support contains() for top-level SVGs
var topParent = element.node
while (topParent.parentNode){
topParent = topParent.parentNode
}
if (topParent != document) throw new Exception('Element not in the dom')
} else {
// the element is NOT in the dom, throw error
if(!document.documentElement.contains(element.node)) throw new Exception('Element not in the dom')
}
// find native bbox
box = element.node.getBBox()
} catch(e) {
if(element instanceof SVG.Shape){
var clone = element.clone(SVG.parser.draw.instance).show()
box = clone.node.getBBox()
clone.remove()
}else{
box = {
x: element.node.clientLeft
, y: element.node.clientTop
, width: element.node.clientWidth
, height: element.node.clientHeight
}
}
}
SVG.Box.call(this, box)
}
}
// Define ancestor
, inherit: SVG.Box
// Define Parent
, parent: SVG.Element
// Constructor
, construct: {
// Get bounding box
bbox: function() {
return new SVG.BBox(this)
}
}
})
SVG.BBox.prototype.constructor = SVG.BBox
SVG.extend(SVG.Element, {
tbox: function(){
console.warn('Use of TBox is deprecated and mapped to RBox. Use .rbox() instead.')
return this.rbox(this.doc())
}
})
SVG.RBox = SVG.invent({
// Initialize
create: function(element) {
SVG.Box.apply(this, [].slice.call(arguments))
if (element instanceof SVG.Element) {
SVG.Box.call(this, element.node.getBoundingClientRect())
}
}
, inherit: SVG.Box
// define Parent
, parent: SVG.Element
, extend: {
addOffset: function() {
// offset by window scroll position, because getBoundingClientRect changes when window is scrolled
this.x += window.pageXOffset
this.y += window.pageYOffset
return this
}
}
// Constructor
, construct: {
// Get rect box
rbox: function(el) {
if (el) return new SVG.RBox(this).transform(el.screenCTM().inverse())
return new SVG.RBox(this).addOffset()
}
}
})
SVG.RBox.prototype.constructor = SVG.RBox