/** * @constructor */ hui.ui.Drawing = function(options) { this.options = hui.override({width:200,height:200},options); this.element = hui.get(options.element); hui.log({width:options.width,height:options.height}); this.svg = hui.ui.Drawing._build({tag:'svg',parent:this.element,attributes:{width:options.width,height:options.height}}); this.element.appendChild(this.svg); this.name = options.name; hui.ui.extend(this); }; hui.ui.Drawing.create = function(options) { options = options || {}; var e = options.element = hui.build('div',{'class':'hui_drawing',style:'position: relative; overflow: hidden;'}); if (options.height) { e.style.height = options.height+'px'; } if (options.width) { e.style.width = options.width+'px'; } if (options.parent) { hui.get(options.parent).appendChild(e); } return new hui.ui.Drawing(options); }; hui.ui.Drawing.prototype = { setSize : function(width,height) { this.svg.setAttribute('width',width); this.svg.setAttribute('height',height); this.svg.style.width = width+'px'; this.svg.style.height = height+'px'; this.element.style.width = width+'px'; this.element.style.height = height+'px'; }, clear : function() { hui.dom.clear(this.svg); }, addLine : function(options) { options.parent = this.svg; return hui.ui.Drawing.Line.create(options); }, addRect : function(options) { options.parent = this.svg; return hui.ui.Drawing.Rect.create(options); }, addCircle : function(options) { options.parent = this.svg; return hui.ui.Drawing.Circle.create(options); }, addArc : function(options) { options.parent = this.svg; return hui.ui.Drawing.Arc.create(options); }, addElement : function(options) { var node = hui.build('div',{style:'position:absolute;left:0;top:0;',parent:this.element,html:options.html}), element = new hui.ui.Drawing.Element(node); if (options.movable) { hui.drag.register({ element : node, onBeforeMove : function(e) { this.fire('shapeWillMove',{shape:element,event:e}); }.bind(this), onMove : function(e) { node.style.left = e.getLeft()+'px'; node.style.top = e.getTop()+'px'; this.fire('shapeMoved',{shape:element,event:e}); }.bind(this), onAfterMove : function(e) { this.fire('shapeWasMoved',{shape:element,event:e}); }.bind(this) }); } return element; } }; hui.ui.Drawing._build = function(options) { var node = document.createElementNS('http://www.w3.org/2000/svg',options.tag); if (options.attributes) { for (var att in options.attributes) { node.setAttribute(att,options.attributes[att]); } } if (options.parent) { options.parent.appendChild(node); } return node; }; // Line hui.ui.Drawing.Line = function(options) { this.node = options.node; this.endNode = options.endNode; this.from = options.from; this.to = options.to; this._updateEnds(); }; hui.ui.Drawing.Line.create = function(options) { if (!options.from) { options.from = {x:options.x1,y:options.y1}; } if (!options.to) { options.to = {x:options.x2,y:options.y2}; } var attributes = { x1 : options.from.x.toFixed(10), y1 : options.from.y.toFixed(10), x2 : options.to.x.toFixed(10), y2 : options.to.y.toFixed(10), style : 'stroke:'+(options.color || '#000')+';stroke-width:'+(options.width || 1) }; options.node = hui.ui.Drawing._build({ tag : 'line', parent : options.parent, attributes : attributes }); if (options.end) { options.endNode = hui.ui.Drawing._build({ tag : 'path', parent : options.parent, attributes : {d:'M 0 -1 L 5 10 L -5 10',fill:options.color || '#000'} }); } return new hui.ui.Drawing.Line(options); }; hui.ui.Drawing.Line.prototype = { setFrom : function(point) { this.from = point; this.node.setAttribute('x1',point.x.toFixed(10)); this.node.setAttribute('y1',point.y.toFixed(10)); this._updateEnds(); }, getFrom : function() { return this.from; }, setTo : function(point) { this.to = point; this.node.setAttribute('x2',point.x.toFixed(10)); this.node.setAttribute('y2',point.y.toFixed(10)); this._updateEnds(); }, getTo : function() { return this.to; }, _updateEnds : function() { //var deg = Math.atan((this.from.y-this.to.y) / (this.from.x-this.to.x)) * 180/Math.PI; if (this.endNode) { var deg = -90 + Math.atan2(this.from.y - this.to.y, this.from.x - this.to.x) * 180 / Math.PI; this.endNode.setAttribute('transform','translate('+ ( this.to.x.toFixed(10)) + ',' + ( this.to.y.toFixed(10) ) + ') rotate(' + (deg) + ')'); } }, getDegree : function() { return Math.atan((this.from.y - this.to.y) / (this.from.x - this.to.x)) * 180 / Math.PI; } }; // Circle hui.ui.Drawing.Circle = function(options) { this.node = options.node; this.properties = {}; }; hui.ui.Drawing.Circle.create = function(options) { var css = []; if (options.stroke) { if (options.stroke.color) { css.push('stroke:' + options.stroke.color); } if (options.stroke.width) { css.push('stroke-width:' + options.stroke.width); } } if (options.fill) { css.push('fill:' + options.fill); } options.node = hui.ui.Drawing._build({ tag : 'circle', parent : options.parent, attributes : { cx : options.cx, cy : options.cy, r : options.r, style : css.join(';') } }); return new hui.ui.Drawing.Circle(options); }; hui.ui.Drawing.Circle.prototype = { setRadius : function(radius) { this.node.setAttribute("r", radius); }, setCenter : function(point) { this.node.setAttribute('cx', point.x); this.node.setAttribute('cy', point.y); } }; // Rect hui.ui.Drawing.Rect = function(options) { this.node = options.node; }; hui.ui.Drawing.Rect.create = function(options) { var css = []; if (options.stroke) { if (options.stroke.color) { css.push('stroke:'+options.stroke.color); } if (options.stroke.width) { css.push('stroke-width:'+options.stroke.width); } } if (options.fill) { css.push('fill:'+options.fill); } options.node = hui.ui.Drawing._build({ tag : 'rect', parent : options.parent, attributes : { x : options.x, y : options.y, width : options.width, height : options.height, style : css.join(';') } }); return new hui.ui.Drawing.Circle(options); }; hui.ui.Drawing.Rect.prototype = { setPosition : function(point) { this.node.setAttribute('x',point.x); this.node.setAttribute('y',point.y); } }; // Arc hui.ui.Drawing.Arc = function(options) { this.node = options.node; this.options = hui.override({ center : {x:100,y:100}, startDegrees : 0, endDegrees : 0, innerRadius : 0, outerRadius : 0, skew: 0, fill : '#eee' },options); this._redraw(); }; hui.ui.Drawing.Arc.create = function(options) { var css = []; if (options.stroke) { if (options.stroke.color) { css.push('stroke:'+options.stroke.color); } if (options.stroke.width) { css.push('stroke-width:'+options.stroke.width); } } options.node = hui.ui.Drawing._build({ tag : 'path' ,parent : options.parent, attributes : {fill : options.fill || '#000', style:css.join(';')}}); var arc = new hui.ui.Drawing.Arc(options); return arc; }; hui.ui.Drawing.Arc.prototype = { update : function(options) { this.options = hui.override(this.options,options); this._redraw(); }, _redraw : function() { var o = this.options, cx = o.center.x, cy = o.center.y, startRadians = (o.startDegrees || 0) * Math.PI/180, closeRadians = (o.endDegrees || 0) * Math.PI/180, r1 = o.innerRadius, r2 = o.outerRadius; var points = [ [ cx + r2 * Math.cos(startRadians), cy + r2 * Math.sin(startRadians) ], [ cx + r2 * Math.cos(closeRadians), cy + r2 * Math.sin(closeRadians) ], [ cx + r1 * Math.cos(closeRadians - o.skew), cy + r1 * Math.sin(closeRadians - o.skew) ], [ cx + r1 * Math.cos(startRadians + o.skew), cy + r1 * Math.sin(startRadians + o.skew) ] ]; var angleDiff = closeRadians - startRadians; var largeArc = (angleDiff % (Math.PI*2)) > Math.PI ? 1 : 0; var cmds = [ "M"+points[0].join(), // Move to P0 "A"+[r2,r2,0,largeArc,1,points[1]].join(), // Arc to P1 "L"+points[2].join(), // Line to P2 "A"+[r1,r1,0,largeArc,0,points[3]].join(), // Arc to P3 "z" // Close path (Line to P0) ]; this.node.setAttribute('d',cmds.join(' ')); } }; // Element hui.ui.Drawing.Element = function(node) { this.node = node; }; hui.ui.Drawing.Element.prototype = { setPosition : function(point) { this.node.style.left = point.x+'px'; this.node.style.top = point.y+'px'; }, setCenter : function(point) { this.node.style.left = (point.x - this.node.clientWidth/2)+'px'; this.node.style.top = (point.y - this.node.clientHeight/2)+'px'; } }; hui.geometry = { intersectLineLine : function(a1, a2, b1, b2) { var ua_t = (b2.x - b1.x) * (a1.y - b1.y) - (b2.y - b1.y) * (a1.x - b1.x); var ub_t = (a2.x - a1.x) * (a1.y - b1.y) - (a2.y - a1.y) * (a1.x - b1.x); var u_b = (b2.y - b1.y) * (a2.x - a1.x) - (b2.x - b1.x) * (a2.y - a1.y); if ( u_b !== 0 ) { var ua = ua_t / u_b; var ub = ub_t / u_b; if ( 0 <= ua && ua <= 1 && 0 <= ub && ub <= 1 ) { return { x : a1.x + ua * (a2.x - a1.x), y : a1.y + ua * (a2.y - a1.y) }; } } return null; }, intersectLineRectangle : function(a1, a2, r1, r2) { var min = {x : Math.min(r1.x,r2.x),y : Math.min(r1.y,r2.y)}; var max = {x : Math.max(r1.x,r2.x),y : Math.max(r1.y,r2.y)}; var topRight = {x: max.x, y: min.y }; var bottomLeft = {x: min.x, y: max.y }; var inter1 = hui.geometry.intersectLineLine(min, topRight, a1, a2); var inter2 = hui.geometry.intersectLineLine(topRight, max, a1, a2); var inter3 = hui.geometry.intersectLineLine(max, bottomLeft, a1, a2); var inter4 = hui.geometry.intersectLineLine(bottomLeft, min, a1, a2); var result = []; if (inter1 !== null) result.push(inter1); if (inter2 !== null) result.push(inter2); if (inter3 !== null) result.push(inter3); if (inter4 !== null) result.push(inter4); return result; }, distance : function( point1, point2 ) { var xs = point2.x - point1.x; var ys = point2.y - point1.y; return Math.sqrt( xs * xs + ys * ys ); } };