/** * @namespace shape */ ovm.shape = ovm.shape || {}; /** * Definition of shape Lines */ ovm.shape.ruler = function(xPixelSpacing,yPixelSpacing,measure_Unit) { var handle = 5; var lines = []; var curr_line=null; var xPxlSpcing = xPixelSpacing; var yPxlSpcing = yPixelSpacing; var measureUnit = measure_Unit; var isCurrentDrawingLine = false; this.createNewLine = function(x1,y1,x2,y2) { if(curr_line!=undefined) { curr_line.setCoords(x1,y1,x2,y2,false); if(parseInt(curr_line.len)>0) { lines.push(curr_line); curr_line = undefined; } } }; this.initNewLine = function() { curr_line = new ovm.line(xPxlSpcing, yPxlSpcing,measureUnit, 0, 0, 0, 0, 0); }; this.draw = function(graphic,ctx) { ctx.strokeStyle=ctx.fillStyle='orange'; ctx.beginPath(); ctx.moveTo(graphic.x1,graphic.y1); ctx.lineTo(graphic.x2,graphic.y2); ctx.stroke(); ctx.closePath(); // Handles ctx.strokeStyle = ctx.fillStyle = graphic.active? 'red' : 'white'; ctx.strokeRect(graphic.x1-handle,graphic.y1-handle,handle*2,handle*2); ctx.strokeRect(graphic.x2-handle,graphic.y2-handle,handle*2,handle*2); // Text ctx.fillStyle = graphic.txtActive? "blue" : "maroon"; ctx.globalAlpha = 0.7; ctx.font = "14px Arial"; var text = ctx.measureText(graphic.len + " " + measureUnit); ctx.fillRect(graphic.textX,graphic.textY,Math.ceil(text.width)+5,20); ctx.globalAlpha = 0.9; ctx.fillStyle = "white"; //ctx.fillText(graphic.len+" " + measureUnit,graphic.textX+2,graphic.textY+14); if(state.hflip && !state.vflip && !state.rotate!=0 && !this.isCurrentDrawingLine){ ctx.save(); ctx.translate(drawCanvas.width,0); ctx.scale(-1,1); ctx.fillText(graphic.len+ " " + measureUnit,(drawCanvas.width - graphic.textX)-60,graphic.textY+14); ctx.restore(); } if(state.vflip && !state.hflip && !state.rotate!=0 && !this.isCurrentDrawingLine){ ctx.save(); ctx.translate(0,drawCanvas.height); ctx.scale(1,-1); ctx.fillText(graphic.len+ " " + measureUnit, graphic.textX,(drawCanvas.height -graphic.textY)); ctx.restore(); } if(!state.vflip && state.hflip && (state.rotate===90 || state.rotate===180 || state.rotate===270) && !this.isCurrentDrawingLine){ if(state.rotate===90|| state.rotate===180 || state.rotate===270) { ctx.save(); ctx.translate(0,drawCanvas.height); ctx.scale(1,-1); ctx.fillText(graphic.len+ " " + measureUnit, graphic.textX,(drawCanvas.height -graphic.textY)); ctx.restore(); } } if(state.vflip && !state.hflip && (state.rotate===90 || state.rotate===180 || state.rotate===270) && !this.isCurrentDrawingLine){ if(state.rotate===90 || state.rotate===180 || state.rotate===270) { ctx.save(); ctx.translate(drawCanvas.width,0); ctx.scale(-1,1); ctx.fillText(graphic.len+ " " + measureUnit,(drawCanvas.width - graphic.textX)-60,graphic.textY+14); ctx.restore(); } } if(state.rotate!=0 && !state.vflip && !state.hflip && !this.isCurrentDrawingLine) { if(state.rotate===180) { ctx.save(); ctx.translate(drawCanvas.width/2,drawCanvas.height/2); ctx.rotate(Math.PI); ctx.translate(-drawCanvas.width/2,-drawCanvas.height/2); ctx.fillText(graphic.len+ " " + measureUnit, (drawCanvas.width -graphic.textX)-60,(drawCanvas.height -graphic.textY)); ctx.restore(); } else { ctx.fillText(graphic.len+ " " + measureUnit,graphic.textX+2,graphic.textY+14); } } if((state.rotate===0 || state.rotate===90 || state.rotate===180 || state.rotate===270) && state.vflip && state.hflip && !this.isCurrentDrawingLine) { if(state.rotate===0) { ctx.save(); ctx.translate(drawCanvas.width,drawCanvas.height); ctx.scale(-1,-1); ctx.fillText(graphic.len+ " " + measureUnit, (drawCanvas.width -graphic.textX)-60,(drawCanvas.height -graphic.textY)); ctx.restore(); } else { ctx.fillText(graphic.len+ " " + measureUnit,graphic.textX+2,graphic.textY+14); } } if(!state.hflip && !state.vflip && !state.rotate!=0) { ctx.fillText(graphic.len+ " " + measureUnit,graphic.textX+2,graphic.textY+14); } if(this.isCurrentDrawingLine) { ctx.fillText(graphic.len+ " " + measureUnit, graphic.textX+2,graphic.textY+14); } // Reference lines if(graphic.x1!=graphic.textX) { ctx.save(); ctx.beginPath(); ctx.globalAlpha = 0.5; ctx.strokeStyle = "yellow"; ctx.setLineDash([10,7]); var closestPt = this.getClosestAnchor([{x:graphic.textX,y:graphic.textY},{x:graphic.textX+Math.ceil(text.width+5),y:graphic.textY},{x:graphic.textX,y:graphic.textY+20},{x:graphic.textX+Math.ceil(text.width+5),y:graphic.textY+20}],{x:graphic.refX,y:graphic.refY}); ctx.moveTo(closestPt.x, closestPt.y); ctx.lineTo(graphic.refX,graphic.refY); ctx.stroke(); ctx.closePath(); ctx.restore(); } }; this.drawData = function(ctx) { ctx.save(); ctx.lineWidth='2'; for(var i=0;i=start.x-handle && x<=start.x+handle && y>=start.y-handle && y<=start.y+handle) { target.style.cursor = "pointer"; return 0; } else if(x>=end.x-handle && x<=end.x+handle && y>=end.y-handle && y<=end.y+handle) { target.style.cursor = "pointer"; return 1; } else { return -1; } }; this.moveShape = function(deltaX,deltaY) { if(this.active) { this.x1+=deltaX; this.y1+=deltaY; this.x2+=deltaX; this.y2+=deltaY; } this.textX+=deltaX; this.textY+=deltaY; this.findClosestPointOnLine(); }; this.resizeShape = function(deltaX,deltaY,handle) { switch(handle) { case 0: this.x1+=deltaX; this.y1+=deltaY; this.len= this.calculateLength(this.x2-this.x1, this.y2-this.y1).toFixed(3); break; case 1: this.x2+=deltaX; this.y2+=deltaY; this.len = this.calculateLength(this.x2-this.x1, this.y2-this.y1).toFixed(3); break; } this.findClosestPointOnLine(); }; this.calculateLength = function(xDiff,yDiff) { var mult = Math.max(this.getFloatShift(this.xPxlSpcing),this.getFloatShift(this.yPxlSpcing)); var xDist = mult * this.xPxlSpcing * xDiff; var yDist = mult * this.yPxlSpcing * yDiff; return ((Math.sqrt((Math.pow(xDist,2)+Math.pow(yDist,2))/Math.pow(mult,2))))/10; }; this.getFloatShift = function(floatNum) { var decimalLen = 0; var floatElements = floatNum.toString().split('\.'); if(floatElements.length==2) { decimalLen = floatElements[1].length; } mult = Math.pow(10,decimalLen); return mult; }; this.canvasToImgcoordinates = function(point) { return {x:((point.x-state.translationX)/state.scale),y:((point.y-state.translationY)/state.scale)}; }; this.ImgTocanvascoordinates = function(point) { return {x:point.x*state.scale+state.translationX,y:point.y*state.scale+state.translationY}; }; this.isTextSelection = function(canvasCtx,mouseX,mouseY) { var x = (mouseX-state.translationX)/state.scale; var y = (mouseY-state.translationY)/state.scale; var textWid = Math.ceil(canvasCtx.measureText(this.len + " " + this.measureUnit).width)+5; this.txtActive = (x>=this.textX && x<=this.textX+(textWid/state.scale) && y>=this.textY && y<=(this.textY+(20/state.scale))); return this.txtActive; }; this.findClosestPointOnLine = function() { var ptWithinLine = true; var dotproduct = (this.textX - this.x1) * (this.x2 - this.x1) + (this.textY - this.y1)*(this.y2 - this.y1); if(dotproduct<0) { ptWithinLine = false; } var squaredlengthBA = (this.x2 - this.x1)*(this.x2 - this.x1) + (this.y2 - this.y1)*(this.y2 - this.y1); if(dotproduct > squaredlengthBA) { ptWithinLine = false; } if(ptWithinLine) { var a_to_p = [this.textX - this.x1 , this.textY - this.y1]; // Vector A to P var a_to_b = [this.x2 - this.x1 , this.y2 - this.y1]; // Vector A to B // Find squared magnitude of a_to_b var atb2 = Math.pow(a_to_b[0],2) + Math.pow(a_to_b[1],2); // Find dot product of a_to_p and a_to_b var atp_dot_atb = a_to_p[0] * a_to_b[0] + a_to_p[1] * a_to_b[1]; // Normalized distance from a to closest point var t = atp_dot_atb / atb2; // Add the distance to A, moving towards B this.refX = this.x1 + a_to_b[0] * t; this.refY = this.y1 + a_to_b[1] * t; } else { var p_to_a = Math.sqrt(Math.pow(this.textX-this.x1,2) + Math.pow(this.textY-this.y1,2)); // Distance from Point to A var p_to_b = Math.sqrt(Math.pow(this.textX-this.x2,2) + Math.pow(this.textY-this.y2,2)); // Distance from Point to B if(p_to_b>p_to_a) { this.refX = this.x1; this.refY = this.y1; } else { this.refX = this.x2; this.refY = this.y2; } } }; };