/** * Definition of shape */ ovm.shape.angle = function() { var handleSize = 5; var angles = []; this.curr_angle = null; this.isCurrentDrawingAngle = false; this.initAngle = function() { this.curr_angle = new ovm.angle(); }; this.angleStarted = function() { return this.curr_angle!=null; }; this.drawAngle = function(canvasCtx) { canvasCtx.save(); this.draw(canvasCtx,this.curr_angle); canvasCtx.restore(); }; this.draw = function(canvasCtx,graphic) { canvasCtx.strokeStyle=canvasCtx.fillStyle='orange'; canvasCtx.lineWidth='2'; canvasCtx.beginPath(); canvasCtx.moveTo(graphic.xA,graphic.yA); canvasCtx.lineTo(graphic.x0,graphic.y0); if(graphic.xB!=undefined && graphic.yB!=undefined) { canvasCtx.lineTo(graphic.xB,graphic.yB); } canvasCtx.stroke(); canvasCtx.closePath(); if(graphic.arcAngle1!=undefined && graphic.arcAngle2!=undefined) { canvasCtx.save(); canvasCtx.beginPath(); canvasCtx.moveTo(graphic.x0,graphic.y0); canvasCtx.arc(graphic.x0,graphic.y0,graphic.arcRadius,graphic.arcAngle1,graphic.arcAngle2,graphic.counterClockwise); canvasCtx.closePath(); canvasCtx.stroke(); canvasCtx.restore(); } // Handles canvasCtx.strokeStyle=canvasCtx.fillStyle=graphic.active ? 'red' : 'white'; canvasCtx.beginPath(); canvasCtx.fillRect(graphic.xA-handleSize,graphic.yA-handleSize,handleSize*2,handleSize*2); canvasCtx.fillRect(graphic.x0-handleSize,graphic.y0-handleSize,handleSize*2,handleSize*2); canvasCtx.fillRect(graphic.xB-handleSize,graphic.yB-handleSize,handleSize*2,handleSize*2); canvasCtx.closePath(); // Text if(graphic.angle!=undefined) { canvasCtx.beginPath(); canvasCtx.fillStyle = !graphic.txtActive ? "maroon" : "blue"; canvasCtx.globalAlpha = 0.7; canvasCtx.font = "14px Arial"; var text = canvasCtx.measureText(graphic.angle); canvasCtx.fillRect(graphic.textX,graphic.textY,Math.ceil(text.width)+5,20); canvasCtx.globalAlpha = 0.9; canvasCtx.fillStyle = "white"; //canvasCtx.fillText(graphic.angle,graphic.textX+2,graphic.textY+15); if(state.hflip && !state.vflip && !state.rotate!=0 && !this.isCurrentDrawingAngle){ canvasCtx.save(); canvasCtx.translate(drawCanvas.width,0); canvasCtx.scale(-1,1); canvasCtx.fillText(graphic.angle,(drawCanvas.width - graphic.textX)-60,graphic.textY+14); canvasCtx.restore(); } if(state.vflip && !state.hflip && !state.rotate!=0 && !this.isCurrentDrawingAngle){ canvasCtx.save(); canvasCtx.translate(0,drawCanvas.height); canvasCtx.scale(1,-1); canvasCtx.fillText(graphic.angle, graphic.textX,(drawCanvas.height -graphic.textY)); canvasCtx.restore(); } if(!state.vflip && state.hflip && (state.rotate===90 || state.rotate===180 || state.rotate===270) && !this.isCurrentDrawingAngle){ if(state.rotate===90 || state.rotate===180 || state.rotate===270) { canvasCtx.save(); canvasCtx.translate(0,drawCanvas.height); canvasCtx.scale(1,-1); canvasCtx.fillText(graphic.angle,graphic.textX,(drawCanvas.height -graphic.textY)); canvasCtx.restore(); } } if(state.vflip && !state.hflip && (state.rotate===90 || state.rotate===180 || state.rotate===270) && !this.isCurrentDrawingAngle){ if(state.rotate===90 || state.rotate===180 || state.rotate===270) { canvasCtx.save(); canvasCtx.translate(drawCanvas.width,0); canvasCtx.scale(-1,1); canvasCtx.fillText(graphic.angle, (drawCanvas.width - graphic.textX)-60, graphic.textY+14); canvasCtx.restore(); } } if(state.rotate!=0 && !state.vflip && !state.hflip && !this.isCurrentDrawingAngle) { if(state.rotate===180) { canvasCtx.save(); canvasCtx.translate(drawCanvas.width/2,drawCanvas.height/2); canvasCtx.rotate(Math.PI); canvasCtx.translate(-drawCanvas.width/2,-drawCanvas.height/2); canvasCtx.fillText(graphic.angle, (drawCanvas.width -graphic.textX)-60,(drawCanvas.height -graphic.textY)); canvasCtx.restore(); } else { canvasCtx.fillText(graphic.angle,graphic.textX+2,graphic.textY+14); } } if((state.rotate===0 || state.rotate===90 || state.rotate===180 || state.rotate===270) && state.vflip && state.hflip && !this.isCurrentDrawingAngle) { if(state.rotate===0) { canvasCtx.save(); canvasCtx.translate(drawCanvas.width,drawCanvas.height); canvasCtx.scale(-1,-1); canvasCtx.fillText(graphic.angle, (drawCanvas.width -graphic.textX)-60,(drawCanvas.height -graphic.textY)); canvasCtx.restore(); } else { canvasCtx.fillText(graphic.angle,graphic.textX+2,graphic.textY+14); } } //if((!state.rotate===0 || !state.rotate===90 || !state.rotate===180 || !state.rotate===270) && state.hflip && state.vflip) { //console.log("if(state.hflip && state.vflip) called state.rotate="+state.rotate); //canvasCtx.save(); //canvasCtx.translate(drawCanvas.width,drawCanvas.height); //canvasCtx.scale(-1,-1); //canvasCtx.fillText(graphic.angle, (drawCanvas.width -graphic.textX)-60,(drawCanvas.height -graphic.textY)); //canvasCtx.restore(); //} if(!state.hflip && !state.vflip && !state.rotate!=0) { canvasCtx.fillText(graphic.angle,graphic.textX+2,graphic.textY+14); } if(this.isCurrentDrawingAngle) { canvasCtx.fillText(graphic.angle,graphic.textX+2,graphic.textY+14); } canvasCtx.closePath(); // Reference Lines if(graphic.textX!=(graphic.xB+15)) { canvasCtx.save(); canvasCtx.beginPath(); canvasCtx.globalAlpha = 0.5; canvasCtx.strokeStyle = "yellow"; canvasCtx.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}); canvasCtx.moveTo(closestPt.x, closestPt.y); canvasCtx.lineTo(graphic.refX,graphic.refY); canvasCtx.stroke(); canvasCtx.closePath(); canvasCtx.restore(); } } }; this.createNewAngle = function() { this.curr_angle.generateTrueGraphic(); angles.push(this.curr_angle); this.curr_angle = null; }; this.drawData = function(ctx) { ctx.save(); for(var i=0;ithis.arcAngle2); } var tangent = this.getRadians({x:this.xA,y:this.yA},{x:this.x0,y:this.y0},{x:this.xB,y:this.yB}); var deg = tangent * (180/Math.PI); this.angle = deg % 360.0; if (Math.abs(this.angle) > 180.0) { this.counterClockwise = (this.arcAngle2>this.arcAngle1); this.angle -= Math.sign(this.angle) * 360.0; } this.angle = Math.abs(this.angle).toFixed(2) + " deg"; }; this.validate = function() { this.OAvalid = (this.xA!=undefined && this.yA!=undefined && this.x0!=undefined && this.y0!=undefined && this.x0!=this.xA && this.y0!=this.yA); this.OBvalid = (this.x0!=undefined && this.y0!=undefined && this.xB!=undefined && this.yB!=undefined && this.x0!=this.xB && this.y0!=this.yB); this.arcAngle1 = this.arcAngle2 = undefined; this.lineColinear = false; this.counterClockwise = false; this.angle = 0.0; if(this.OAvalid && this.OBvalid) { this.lineColinear = this.isColinear({x:this.x0,y:this.yo}, {x:this.xA,y:this.yA}, {x:this.x0,y:this.y0}, {x:this.xB,y:this.yB}); this.calculateAngle(); } }; this.isColinear = function(ptA,ptB,ptC,ptD) { if(this.isParallel(ptA, ptB, ptC, ptD)) { if (((ptA.y - ptC.y) * (ptD.x - ptC.x) - (ptA.x - ptC.x) * (ptD.y - ptC.y)) == 0) { return true; } } return false; }; this.isParallel = function(ptA,ptB,ptC,ptD) { if (((ptB.x - ptA.x) * (ptD.y - ptC.y) - (ptB.y - ptA.y) * (ptD.x - ptC.x)) == 0) { return true; } return false; }; this.calculateArcAngles = function(pt1,pt2,pt3) { this.arcAngle1 = Math.atan2(pt3.y - pt2.y, pt3.x - pt2.x); this.arcAngle2 = Math.atan2(pt1.y - pt2.y, pt1.x - pt2.x); }; this.getRadians2 = function(ptA,ptB) { return Math.atan2(ptA.y-ptB.y,ptB.x-ptA.x); }; this.getRadians = function(ptA,ptB,ptC) { return this.getRadians2(ptB,ptC)-this.getRadians2(ptB,ptA); }; this.getType = function() { return "angle"; }; this.detectHandle = function(mouseX,mouseY,target) { var x = (mouseX-state.translationX)/state.scale; var y = (mouseY-state.translationY)/state.scale; if(x>=this.xA-handleSize && x<=this.xA+handleSize && y>=this.yA-handleSize && y<=this.yA+handleSize) { target.style.cursor = "pointer"; return 0; } else if(x>=this.x0-handleSize && x<=this.x0+handleSize && y>=this.y0-handleSize && y<=this.y0+handleSize) { target.style.cursor = "pointer"; return 1; } else if(x>=this.xB-handleSize && x<=this.xB+handleSize && y>=this.yB-handleSize && y<=this.yB+handleSize) { target.style.cursor = "pointer"; return 2; } else { return -1; } }; this.detectLine = function(start,end,mouse) { var a = Math.round(Math.sqrt(Math.pow((end.x+handleSize)-(start.x+handleSize),2) + Math.pow((end.y+handleSize)-(start.y+handleSize),2))); var b = Math.round(Math.sqrt(Math.pow(mouse.x-(start.x+handleSize),2) + Math.pow(mouse.y-(start.y+handleSize),2))); var c = Math.round(Math.sqrt(Math.pow((end.x+handleSize)-mouse.x,2) + Math.pow((end.y+handleSize)-mouse.y,2))); return (a==b+c); }; this.isActiveShape = function(canvasCtx,mouseX,mouseY) { var x = (mouseX-state.translationX)/state.scale; var y = (mouseY-state.translationY)/state.scale; if(this.detectLine({x:this.xA,y:this.yA},{x:this.x0,y:this.y0},{x:x,y:y}) || this.detectLine({x:this.x0,y:this.y0},{x:this.xB,y:this.yB},{x:x,y:y})) { this.active = true; } else { this.active = false; } return this.active || this.isTextSelection(canvasCtx,mouseX,mouseY); }; this.moveShape = function(deltaX,deltaY) { if(this.active) { this.x0+=deltaX; this.y0+=deltaY; this.xA+=deltaX; this.yA+=deltaY; this.xB+=deltaX; this.yB+=deltaY; } this.textX+=deltaX; this.textY+=deltaY; this.fixReferencePoints(); }; this.resizeShape = function(deltaX,deltaY,handleIndex) { switch(handleIndex) { case 0: this.xA+=deltaX; this.yA+=deltaY; break; case 1: this.x0+=deltaX; this.y0+=deltaY; break; case 2: this.xB+=deltaX; this.yB+=deltaY; this.textX = this.xB+15; this.textY = this.yB+15; break; } this.validate(); this.fixReferencePoints(); }; this.isTextSelection = function(canvasCtx,mouseX,mouseY) { var x = Math.ceil((mouseX-state.translationX)/state.scale); var y = Math.floor((mouseY-state.translationY)/state.scale); var textWid = Math.ceil(canvasCtx.measureText(this.angle).width)+5; this.txtActive = (x>=this.textX && x<=this.textX+(textWid/state.scale)+5 && y>=this.textY && y<=(this.textY+(15/state.scale))); return this.txtActive; }; this.distanceToLine = function(line,point) { return Math.round(Math.sqrt(Math.pow(point.x-line.x1,2) + Math.pow(point.y-line.y1,2))) + Math.round(Math.sqrt(Math.pow(line.x2-point.x,2) + Math.pow(line.y2-point.y,2))); }; this.distanceToPoint = function(point1,point2) { return Math.round(Math.sqrt(Math.pow(point2.x-point1.x,2) + Math.pow(point2.y-point1.y,2))); }; this.fixReferencePoints = function() { var dist1 = this.distanceToLine({x1:this.xA,y1:this.yA,x2:this.x0,y2:this.y0}, {x:this.textX,y:this.textY}); var dist2 = this.distanceToLine({x1:this.xB,y1:this.yB,x2:this.x0,y2:this.y0}, {x:this.textX,y:this.textY}); if(dist1=P.x || A.x>=P.x && B.x<=P.x) { if(A.y<=P.y && B.y>=P.y || A.y>=P.y && B.y<=P.y) { return true; } } return false; }; this.selectNearestAnchor = function(ptA,ptB,ptC) { var d1 = this.distanceToPoint(ptA, ptC); var d2 = this.distanceToPoint(ptB, ptC); if(d1