import { bbox, rbox } from '../types/Box.js' import { ctm, screenCTM } from '../types/Matrix.js' import { extend, getClass, makeInstance, register, root } from '../utils/adopter.js' import { globals } from '../utils/window.js' import { point } from '../types/Point.js' import { proportionalSize } from '../utils/utils.js' import { reference } from '../modules/core/regex.js' import Dom from './Dom.js' import List from '../types/List.js' import SVGNumber from '../types/SVGNumber.js' const Svg = getClass( root ) export default class Element extends Dom { constructor ( node, attrs ) { super( node, attrs ) // initialize data object this.dom = {} // create circular reference this.node.instance = this if ( node.hasAttribute( 'svgjs:data' ) ) { // pull svgjs data from the dom (getAttributeNS doesn't work in html5) this.setData( JSON.parse( node.getAttribute( 'svgjs:data' ) ) || {} ) } } // Move element by its center center ( x, y ) { return this.cx( x ).cy( y ) } // Move by center over x-axis cx ( x ) { return x == null ? this.x() + this.width() / 2 : this.x( x - this.width() / 2 ) } // Move by center over y-axis cy ( y ) { return y == null ? this.y() + this.height() / 2 : this.y( y - this.height() / 2 ) } // Get defs defs () { return this.root().defs() } // Get parent document root () { let p = this.parent( Svg ) return p && p.root() } getEventHolder () { return this } // Set height of element height ( height ) { return this.attr( 'height', height ) } // Checks whether the given point inside the bounding box of the element inside ( x, y ) { let box = this.bbox() return x > box.x && y > box.y && x < box.x + box.width && y < box.y + box.height } // Move element to given x and y values move ( x, y ) { return this.x( x ).y( y ) } // return array of all ancestors of given type up to the root svg parents ( until = globals.document ) { until = makeInstance( until ) let parents = new List() let parent = this while ( ( parent = parent.parent() ) && parent.node !== until.node && parent.node !== globals.document ) { parents.push( parent ) } return parents } // Get referenced element form attribute value reference ( attr ) { attr = this.attr( attr ) if ( !attr ) return null const m = attr.match( reference ) return m ? makeInstance( m[1] ) : null } // set given data to the elements data property setData ( o ) { this.dom = o return this } // Set element size to given width and height size ( width, height ) { let p = proportionalSize( this, width, height ) return this .width( new SVGNumber( p.width ) ) .height( new SVGNumber( p.height ) ) } // Set width of element width ( width ) { return this.attr( 'width', width ) } // write svgjs data to the dom writeDataToDom () { // remove previously set data this.node.removeAttribute( 'svgjs:data' ) if ( Object.keys( this.dom ).length ) { this.node.setAttribute( 'svgjs:data', JSON.stringify( this.dom ) ) // see #428 } return super.writeDataToDom() } // Move over x-axis x ( x ) { return this.attr( 'x', x ) } // Move over y-axis y ( y ) { return this.attr( 'y', y ) } } extend( Element, { bbox, rbox, point, ctm, screenCTM } ) register( Element )