mirror of
https://github.com/xibyte/jsketcher
synced 2026-02-16 12:24:22 +01:00
shapes hierarchy refactoring
This commit is contained in:
parent
00b6b49b09
commit
32d79a1181
12 changed files with 720 additions and 692 deletions
13
web/app/sketcher/id-generator.js
Normal file
13
web/app/sketcher/id-generator.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
let ID_COUNTER = 0;
|
||||
|
||||
export const Generator = {
|
||||
genID : function() {
|
||||
return ID_COUNTER ++;
|
||||
},
|
||||
|
||||
resetIDGenerator : function(value) {
|
||||
ID_COUNTER = value;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
import {EndPoint, Layer, Styles, Segment, SketchObject} from './viewer2d'
|
||||
import {Generator} from './id-generator'
|
||||
import {Layer, Styles} from './viewer2d'
|
||||
import {Arc} from './shapes/arc'
|
||||
import {EndPoint} from './shapes/point'
|
||||
import {Segment} from './shapes/segment'
|
||||
import {Circle} from './shapes/circle'
|
||||
import {HDimension, VDimension, Dimension, DiameterDimension} from './shapes/dim'
|
||||
import {Constraints} from './parametric'
|
||||
|
|
@ -248,7 +251,7 @@ IO.prototype.cleanUpData = function() {
|
|||
}
|
||||
}
|
||||
this.viewer.deselectAll();
|
||||
SketchObject.resetIDGenerator(0);
|
||||
Generator.resetIDGenerator(0);
|
||||
if (this.viewer.parametricManager.subSystems.length != 0) {
|
||||
this.viewer.parametricManager.subSystems = [];
|
||||
this.viewer.parametricManager.notify();
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import * as utils from '../utils/utils'
|
||||
import {Ref} from './viewer2d'
|
||||
import {Ref} from './shapes/ref'
|
||||
import {Param, prepare} from './constr/solver'
|
||||
import {createByConstraintName} from './constr/constraints'
|
||||
import Vector from '../math/vector'
|
||||
|
|
|
|||
|
|
@ -1,132 +1,132 @@
|
|||
import * as utils from '../../utils/utils';
|
||||
import * as math from '../../math/math';
|
||||
import Vector from '../../math/vector'
|
||||
import {SketchObject, Ref} from '../viewer2d'
|
||||
import {Ref} from './ref'
|
||||
import {Constraints} from '../parametric'
|
||||
import {SketchObject} from './sketch-object'
|
||||
|
||||
/** @constructor */
|
||||
export function Arc(a, b, c) {
|
||||
SketchObject.call(this);
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
a.parent = this;
|
||||
b.parent = this;
|
||||
c.parent = this;
|
||||
this.children.push(a, b, c);
|
||||
this.r = new Ref(0);
|
||||
this.r.value = this.distanceA();
|
||||
this.r.obj = this;
|
||||
export class Arc extends SketchObject {
|
||||
|
||||
constructor(a, b, c) {
|
||||
super();
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.c = c;
|
||||
a.parent = this;
|
||||
b.parent = this;
|
||||
c.parent = this;
|
||||
this.children.push(a, b, c);
|
||||
this.r = new Ref(0);
|
||||
this.r.value = this.distanceA();
|
||||
this.r.obj = this;
|
||||
}
|
||||
|
||||
collectParams(params) {
|
||||
this.a.collectParams(params);
|
||||
this.b.collectParams(params);
|
||||
this.c.collectParams(params);
|
||||
params.push(this.r);
|
||||
}
|
||||
|
||||
getReferencePoint() {
|
||||
return this.c;
|
||||
}
|
||||
|
||||
translateImpl(dx, dy) {
|
||||
this.a.translate(dx, dy);
|
||||
this.b.translate(dx, dy);
|
||||
this.c.translate(dx, dy);
|
||||
}
|
||||
|
||||
|
||||
radiusForDrawing() {
|
||||
return this.distanceA();
|
||||
}
|
||||
|
||||
distanceA() {
|
||||
return math.distance(this.a.x, this.a.y, this.c.x, this.c.y);
|
||||
}
|
||||
|
||||
distanceB() {
|
||||
return math.distance(this.b.x, this.b.y, this.c.x, this.c.y);
|
||||
}
|
||||
|
||||
getStartAngle() {
|
||||
return Math.atan2(this.a.y - this.c.y, this.a.x - this.c.x);
|
||||
}
|
||||
|
||||
getEndAngle() {
|
||||
return Math.atan2(this.b.y - this.c.y, this.b.x - this.c.x);
|
||||
}
|
||||
|
||||
drawImpl(ctx, scale) {
|
||||
ctx.beginPath();
|
||||
var r = this.radiusForDrawing();
|
||||
var startAngle = this.getStartAngle();
|
||||
var endAngle;
|
||||
if (math.areEqual(this.a.x, this.b.x, math.TOLERANCE) &&
|
||||
math.areEqual(this.a.y, this.b.y, math.TOLERANCE)) {
|
||||
endAngle = startAngle + 2 * Math.PI;
|
||||
} else {
|
||||
endAngle = this.getEndAngle();
|
||||
}
|
||||
ctx.arc(this.c.x, this.c.y, r, startAngle, endAngle);
|
||||
var distanceB = this.distanceB();
|
||||
if (Math.abs(r - distanceB) * scale > 1) {
|
||||
var adj = r / distanceB;
|
||||
ctx.save();
|
||||
ctx.setLineDash([7 / scale]);
|
||||
ctx.lineTo(this.b.x, this.b.y);
|
||||
ctx.moveTo(this.b.x + (this.b.x - this.c.x) / adj, this.b.y + (this.b.y - this.c.y) / adj);
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
} else {
|
||||
ctx.stroke();
|
||||
}
|
||||
}
|
||||
|
||||
isPointInsideSector(x, y) {
|
||||
var ca = new Vector(this.a.x - this.c.x, this.a.y - this.c.y);
|
||||
var cb = new Vector(this.b.x - this.c.x, this.b.y - this.c.y);
|
||||
var ct = new Vector(x - this.c.x, y - this.c.y);
|
||||
|
||||
ca._normalize();
|
||||
cb._normalize();
|
||||
ct._normalize();
|
||||
var cosAB = ca.dot(cb);
|
||||
var cosAT = ca.dot(ct);
|
||||
|
||||
var isInside = cosAT >= cosAB;
|
||||
var abInverse = ca.cross(cb).z < 0;
|
||||
var atInverse = ca.cross(ct).z < 0;
|
||||
|
||||
var result;
|
||||
if (abInverse) {
|
||||
result = !atInverse || !isInside;
|
||||
} else {
|
||||
result = !atInverse && isInside;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
normalDistance(aim) {
|
||||
|
||||
var isInsideSector = this.isPointInsideSector(aim.x, aim.y);
|
||||
if (isInsideSector) {
|
||||
return Math.abs(math.distance(aim.x, aim.y, this.c.x, this.c.y) - this.radiusForDrawing());
|
||||
} else {
|
||||
return Math.min(
|
||||
math.distance(aim.x, aim.y, this.a.x, this.a.y),
|
||||
math.distance(aim.x, aim.y, this.b.x, this.b.y)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
stabilize(viewer) {
|
||||
this.r.set(this.distanceA());
|
||||
viewer.parametricManager._add(new Constraints.P2PDistanceV(this.b, this.c, this.r));
|
||||
viewer.parametricManager._add(new Constraints.P2PDistanceV(this.a, this.c, this.r));
|
||||
}
|
||||
}
|
||||
|
||||
utils.extend(Arc, SketchObject);
|
||||
|
||||
Arc.prototype._class = 'TCAD.TWO.Arc';
|
||||
|
||||
Arc.prototype.collectParams = function(params) {
|
||||
this.a.collectParams(params);
|
||||
this.b.collectParams(params);
|
||||
this.c.collectParams(params);
|
||||
params.push(this.r);
|
||||
};
|
||||
|
||||
Arc.prototype.getReferencePoint = function() {
|
||||
return this.c;
|
||||
};
|
||||
|
||||
Arc.prototype.translateImpl = function(dx, dy) {
|
||||
this.a.translate(dx, dy);
|
||||
this.b.translate(dx, dy);
|
||||
this.c.translate(dx, dy);
|
||||
};
|
||||
|
||||
|
||||
Arc.prototype.radiusForDrawing = function() {
|
||||
return this.distanceA();
|
||||
};
|
||||
|
||||
Arc.prototype.distanceA = function() {
|
||||
return math.distance(this.a.x, this.a.y, this.c.x, this.c.y);
|
||||
};
|
||||
|
||||
Arc.prototype.distanceB = function() {
|
||||
return math.distance(this.b.x, this.b.y, this.c.x, this.c.y);
|
||||
};
|
||||
|
||||
Arc.prototype.getStartAngle = function() {
|
||||
return Math.atan2(this.a.y - this.c.y, this.a.x - this.c.x);
|
||||
};
|
||||
|
||||
Arc.prototype.getEndAngle = function() {
|
||||
return Math.atan2(this.b.y - this.c.y, this.b.x - this.c.x);
|
||||
};
|
||||
|
||||
Arc.prototype.drawImpl = function(ctx, scale) {
|
||||
ctx.beginPath();
|
||||
var r = this.radiusForDrawing();
|
||||
var startAngle = this.getStartAngle();
|
||||
var endAngle;
|
||||
if (math.areEqual(this.a.x, this.b.x, math.TOLERANCE) &&
|
||||
math.areEqual(this.a.y, this.b.y, math.TOLERANCE)) {
|
||||
endAngle = startAngle + 2 * Math.PI;
|
||||
} else {
|
||||
endAngle = this.getEndAngle();
|
||||
}
|
||||
ctx.arc(this.c.x, this.c.y, r, startAngle, endAngle);
|
||||
var distanceB = this.distanceB();
|
||||
if (Math.abs(r - distanceB) * scale > 1) {
|
||||
var adj = r / distanceB;
|
||||
ctx.save();
|
||||
ctx.setLineDash([7 / scale]);
|
||||
ctx.lineTo(this.b.x, this.b.y);
|
||||
ctx.moveTo(this.b.x + (this.b.x - this.c.x) / adj, this.b.y + (this.b.y - this.c.y) / adj);
|
||||
ctx.stroke();
|
||||
ctx.restore();
|
||||
} else {
|
||||
ctx.stroke();
|
||||
}
|
||||
};
|
||||
|
||||
Arc.prototype.isPointInsideSector = function(x, y) {
|
||||
var ca = new Vector(this.a.x - this.c.x, this.a.y - this.c.y);
|
||||
var cb = new Vector(this.b.x - this.c.x, this.b.y - this.c.y);
|
||||
var ct = new Vector(x - this.c.x, y - this.c.y);
|
||||
|
||||
ca._normalize();
|
||||
cb._normalize();
|
||||
ct._normalize();
|
||||
var cosAB = ca.dot(cb);
|
||||
var cosAT = ca.dot(ct);
|
||||
|
||||
var isInside = cosAT >= cosAB;
|
||||
var abInverse = ca.cross(cb).z < 0;
|
||||
var atInverse = ca.cross(ct).z < 0;
|
||||
|
||||
var result;
|
||||
if (abInverse) {
|
||||
result = !atInverse || !isInside;
|
||||
} else {
|
||||
result = !atInverse && isInside;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
Arc.prototype.normalDistance = function(aim) {
|
||||
|
||||
var isInsideSector = this.isPointInsideSector(aim.x, aim.y);
|
||||
if (isInsideSector) {
|
||||
return Math.abs(math.distance(aim.x, aim.y, this.c.x, this.c.y) - this.radiusForDrawing());
|
||||
} else {
|
||||
return Math.min(
|
||||
math.distance(aim.x, aim.y, this.a.x, this.a.y),
|
||||
math.distance(aim.x, aim.y, this.b.x, this.b.y)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Arc.prototype.stabilize = function(viewer) {
|
||||
this.r.set(this.distanceA());
|
||||
viewer.parametricManager._add(new Constraints.P2PDistanceV(this.b, this.c, this.r));
|
||||
viewer.parametricManager._add(new Constraints.P2PDistanceV(this.a, this.c, this.r));
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,50 +2,49 @@ import * as utils from '../../utils/utils';
|
|||
import * as math from '../../math/math';
|
||||
import {EditCircleTool} from '../tools/circle'
|
||||
|
||||
import {SketchObject, EndPoint, Ref} from '../viewer2d'
|
||||
import {EndPoint} from './point'
|
||||
import {Ref} from './ref'
|
||||
import {SketchObject} from './sketch-object'
|
||||
|
||||
/** @constructor */
|
||||
function Circle(c) {
|
||||
SketchObject.call(this);
|
||||
this.c = c;
|
||||
c.parent = this;
|
||||
this.children.push(c);
|
||||
this.r = new Ref(0);
|
||||
this.r.obj = this;
|
||||
export class Circle extends SketchObject {
|
||||
|
||||
constructor(c) {
|
||||
super();
|
||||
this.c = c;
|
||||
c.parent = this;
|
||||
this.children.push(c);
|
||||
this.r = new Ref(0);
|
||||
this.r.obj = this;
|
||||
}
|
||||
|
||||
collectParams(params) {
|
||||
this.c.collectParams(params);
|
||||
params.push(this.r);
|
||||
}
|
||||
|
||||
getReferencePoint() {
|
||||
return this.c;
|
||||
}
|
||||
|
||||
translateImpl(dx, dy) {
|
||||
this.c.translate(dx, dy);
|
||||
}
|
||||
|
||||
drawImpl(ctx, scale) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.c.x, this.c.y, this.r.get(), 0, 2 * Math.PI);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
normalDistance(aim) {
|
||||
return Math.abs(math.distance(aim.x, aim.y, this.c.x, this.c.y) - this.r.get());
|
||||
}
|
||||
|
||||
getDefaultTool(viewer) {
|
||||
var editTool = new EditCircleTool(viewer, null);
|
||||
editTool.circle = this;
|
||||
return editTool;
|
||||
}
|
||||
}
|
||||
|
||||
utils.extend(Circle, SketchObject);
|
||||
|
||||
Circle.prototype._class = 'TCAD.TWO.Circle';
|
||||
|
||||
Circle.prototype.collectParams = function(params) {
|
||||
this.c.collectParams(params);
|
||||
params.push(this.r);
|
||||
};
|
||||
|
||||
Circle.prototype.getReferencePoint = function() {
|
||||
return this.c;
|
||||
};
|
||||
|
||||
Circle.prototype.translateImpl = function(dx, dy) {
|
||||
this.c.translate(dx, dy);
|
||||
};
|
||||
|
||||
Circle.prototype.drawImpl = function(ctx, scale) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.c.x, this.c.y, this.r.get(), 0, 2 * Math.PI);
|
||||
ctx.stroke();
|
||||
};
|
||||
|
||||
Circle.prototype.normalDistance = function(aim) {
|
||||
return Math.abs(math.distance(aim.x, aim.y, this.c.x, this.c.y) - this.r.get());
|
||||
};
|
||||
|
||||
Circle.prototype.getDefaultTool = function(viewer) {
|
||||
var editTool = new EditCircleTool(viewer, null);
|
||||
editTool.circle = this;
|
||||
return editTool;
|
||||
};
|
||||
|
||||
|
||||
export {Circle}
|
||||
|
|
@ -1,300 +1,306 @@
|
|||
import * as utils from '../../utils/utils'
|
||||
import * as math from '../../math/math'
|
||||
import {SketchObject} from '../viewer2d'
|
||||
import Vector from '../../math/vector'
|
||||
import {SketchObject} from './sketch-object'
|
||||
|
||||
/** @constructor */
|
||||
function LinearDimension(a, b) {
|
||||
SketchObject.call(this);
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.flip = false;
|
||||
}
|
||||
|
||||
utils.extend(LinearDimension, SketchObject);
|
||||
|
||||
LinearDimension.prototype.collectParams = function(params) {
|
||||
};
|
||||
|
||||
LinearDimension.prototype.getReferencePoint = function() {
|
||||
return this.a;
|
||||
};
|
||||
|
||||
LinearDimension.prototype.translateImpl = function(dx, dy) {
|
||||
};
|
||||
|
||||
LinearDimension.prototype.getA = function() { return this.a };
|
||||
LinearDimension.prototype.getB = function() { return this.b };
|
||||
|
||||
LinearDimension.getTextOff = function(scale) {
|
||||
return 3 * scale;
|
||||
};
|
||||
|
||||
LinearDimension.prototype.drawImpl = function(ctx, scale, viewer) {
|
||||
|
||||
var off = 30 * viewer.dimScale;
|
||||
var textOff = LinearDimension.getTextOff(viewer.dimScale);
|
||||
|
||||
var a, b, startA, startB;
|
||||
if (this.flip) {
|
||||
a = this.getB();
|
||||
b = this.getA();
|
||||
startA = this.b;
|
||||
startB = this.a;
|
||||
} else {
|
||||
a = this.getA();
|
||||
b = this.getB();
|
||||
startA = this.a;
|
||||
startB = this.b;
|
||||
class LinearDimension extends SketchObject {
|
||||
|
||||
constructor(a, b) {
|
||||
super();
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
this.flip = false;
|
||||
}
|
||||
|
||||
var d = math.distanceAB(a, b);
|
||||
|
||||
var _vx = - (b.y - a.y);
|
||||
var _vy = b.x - a.x;
|
||||
|
||||
//normalize
|
||||
var _vxn = _vx / d;
|
||||
var _vyn = _vy / d;
|
||||
|
||||
_vx = _vxn * off;
|
||||
_vy = _vyn * off;
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
var _ax = a.x + _vx;
|
||||
var _ay = a.y + _vy;
|
||||
var _bx = b.x + _vx;
|
||||
var _by = b.y + _vy;
|
||||
|
||||
ctx.moveTo(_ax, _ay);
|
||||
ctx.lineTo(_bx, _by);
|
||||
|
||||
|
||||
function drawRef(start, x, y) {
|
||||
var vec = new Vector(x - start.x, y - start.y);
|
||||
vec._normalize();
|
||||
vec._multiply(7 * viewer.dimScale);
|
||||
|
||||
ctx.moveTo(start.x, start.y );
|
||||
ctx.lineTo(x, y);
|
||||
ctx.lineTo(x + vec.x, y + vec.y);
|
||||
}
|
||||
|
||||
drawRef(startA, _ax, _ay);
|
||||
drawRef(startB, _bx, _by);
|
||||
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
function drawArrow(x, y) {
|
||||
var s1 = 50;
|
||||
var s2 = 20;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y);
|
||||
ctx.lineTo(x - s1, y - s2);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// drawArrow(_ax, _ay);
|
||||
// drawArrow(_bx, _by);
|
||||
|
||||
ctx.font= (12 * viewer.dimScale) + "px Arial";
|
||||
var txt = d.toFixed(2);
|
||||
var h = d / 2 - ctx.measureText(txt).width / 2;
|
||||
|
||||
if (h > 0) {
|
||||
var tx = (_ax + _vxn * textOff) - (- _vyn) * h;
|
||||
var ty = (_ay + _vyn * textOff) - ( _vxn) * h;
|
||||
ctx.save();
|
||||
ctx.translate(tx, ty);
|
||||
ctx.rotate( - Math.atan2(_vxn, _vyn));
|
||||
ctx.scale(1, -1);
|
||||
ctx.fillText(txt, 0, 0);
|
||||
ctx.restore();
|
||||
}
|
||||
};
|
||||
|
||||
LinearDimension.prototype.normalDistance = function(aim) {
|
||||
return -1;
|
||||
};
|
||||
|
||||
/** @constructor */
|
||||
function Dimension(a, b) {
|
||||
LinearDimension.call(this, a, b);
|
||||
}
|
||||
|
||||
utils.extend(Dimension, LinearDimension);
|
||||
|
||||
Dimension.prototype._class = 'TCAD.TWO.Dimension';
|
||||
|
||||
/** @constructor */
|
||||
function HDimension(a, b) {
|
||||
LinearDimension.call(this, a, b);
|
||||
}
|
||||
|
||||
utils.extend(HDimension, LinearDimension);
|
||||
|
||||
HDimension.prototype._class = 'TCAD.TWO.HDimension';
|
||||
|
||||
HDimension.prototype.getA = function() { return this.a };
|
||||
HDimension.prototype.getB = function() { return {x : this.b.x, y : this.a.y} };
|
||||
|
||||
/** @constructor */
|
||||
function VDimension(a, b) {
|
||||
LinearDimension.call(this, a, b);
|
||||
}
|
||||
|
||||
utils.extend(VDimension, LinearDimension);
|
||||
|
||||
VDimension.prototype._class = 'TCAD.TWO.VDimension';
|
||||
|
||||
VDimension.prototype.getA = function() { return this.a };
|
||||
VDimension.prototype.getB = function() { return {x : this.a.x, y : this.b.y} };
|
||||
|
||||
|
||||
/** @constructor */
|
||||
function DiameterDimension(obj) {
|
||||
SketchObject.call(this);
|
||||
this.obj = obj;
|
||||
this.angle = Math.PI / 4;
|
||||
}
|
||||
|
||||
DiameterDimension.prototype._class = 'TCAD.TWO.DiameterDimension';
|
||||
|
||||
utils.extend(DiameterDimension, SketchObject);
|
||||
|
||||
DiameterDimension.prototype.collectParams = function(params) {
|
||||
};
|
||||
|
||||
DiameterDimension.prototype.getReferencePoint = function() {
|
||||
};
|
||||
|
||||
DiameterDimension.prototype.translateImpl = function(dx, dy) {
|
||||
};
|
||||
|
||||
DiameterDimension.prototype.drawImpl = function(ctx, scale, viewer) {
|
||||
if (this.obj == null) return;
|
||||
if (this.obj._class === 'TCAD.TWO.Circle') {
|
||||
this.drawForCircle(ctx, scale, viewer);
|
||||
} else if (this.obj._class === 'TCAD.TWO.Arc') {
|
||||
this.drawForArc(ctx, scale, viewer);
|
||||
}
|
||||
};
|
||||
|
||||
DiameterDimension.prototype.drawForCircle = function(ctx, scale, viewer) {
|
||||
var c = new Vector().setV(this.obj.c);
|
||||
var r = this.obj.r.get();
|
||||
var angled = new Vector(r * Math.cos(this.angle), r * Math.sin(this.angle), 0);
|
||||
var a = c.minus(angled);
|
||||
var b = c.plus(angled);
|
||||
var textOff = LinearDimension.getTextOff(viewer.dimScale);
|
||||
|
||||
var d = 2 * r;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(a.x, a.y);
|
||||
ctx.lineTo(b.x, b.y);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
var fontSize = 12 * viewer.dimScale;
|
||||
ctx.font = (fontSize) + "px Arial";
|
||||
var txt = String.fromCharCode(216) + ' ' + d.toFixed(2);
|
||||
var textWidth = ctx.measureText(txt).width;
|
||||
var h = d / 2 - textWidth / 2;
|
||||
|
||||
var _vx = - (b.y - a.y);
|
||||
var _vy = b.x - a.x;
|
||||
|
||||
//normalize
|
||||
var _vxn = _vx / d;
|
||||
var _vyn = _vy / d;
|
||||
|
||||
function drawText(tx, ty) {
|
||||
ctx.save();
|
||||
ctx.translate(tx, ty);
|
||||
ctx.rotate(-Math.atan2(_vxn, _vyn));
|
||||
ctx.scale(1, -1);
|
||||
ctx.fillText(txt, 0, 0);
|
||||
ctx.restore();
|
||||
collectParams(params) {
|
||||
}
|
||||
|
||||
var tx, ty;
|
||||
if (h - fontSize * .3 > 0) { // take into account font size to not have circle overlap symbols
|
||||
tx = (a.x + _vxn * textOff) - (-_vyn) * h;
|
||||
ty = (a.y + _vyn * textOff) - ( _vxn) * h;
|
||||
drawText(tx, ty);
|
||||
} else {
|
||||
var off = 2 * viewer.dimScale;
|
||||
angled._normalize();
|
||||
var extraLine = angled.multiply(textWidth + off * 2);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(b.x, b.y);
|
||||
ctx.lineTo(b.x + extraLine.x, b.y + extraLine.y);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
angled._multiply(off);
|
||||
|
||||
tx = (b.x + _vxn * textOff) + angled.x;
|
||||
ty = (b.y + _vyn * textOff) + angled.y;
|
||||
drawText(tx, ty);
|
||||
getReferencePoint() {
|
||||
return this.a;
|
||||
}
|
||||
};
|
||||
|
||||
DiameterDimension.prototype.drawForArc = function(ctx, scale, viewer) {
|
||||
|
||||
var r = this.obj.distanceA();
|
||||
|
||||
var hxn = Math.cos(this.angle);
|
||||
var hyn = Math.sin(this.angle);
|
||||
|
||||
var vxn = - hyn;
|
||||
var vyn = hxn;
|
||||
|
||||
//fix angle if needed
|
||||
if (!this.obj.isPointInsideSector(this.obj.c.x + hxn, this.obj.c.y + hyn)) {
|
||||
var cosA = hxn * (this.obj.a.x - this.obj.c.x) + hyn * (this.obj.a.y - this.obj.c.y);
|
||||
var cosB = hxn * (this.obj.b.x - this.obj.c.x) + hyn * (this.obj.b.y - this.obj.c.y);
|
||||
if (cosA - hxn > cosB - hxn) {
|
||||
this.angle = this.obj.getStartAngle();
|
||||
|
||||
translateImpl(dx, dy) {
|
||||
}
|
||||
|
||||
getA() { return this.a }
|
||||
getB() { return this.b }
|
||||
|
||||
drawImpl(ctx, scale, viewer) {
|
||||
|
||||
var off = 30 * viewer.dimScale;
|
||||
var textOff = getTextOff(viewer.dimScale);
|
||||
|
||||
var a, b, startA, startB;
|
||||
if (this.flip) {
|
||||
a = this.getB();
|
||||
b = this.getA();
|
||||
startA = this.b;
|
||||
startB = this.a;
|
||||
} else {
|
||||
this.angle = this.obj.getEndAngle();
|
||||
a = this.getA();
|
||||
b = this.getB();
|
||||
startA = this.a;
|
||||
startB = this.b;
|
||||
}
|
||||
|
||||
var d = math.distanceAB(a, b);
|
||||
|
||||
var _vx = - (b.y - a.y);
|
||||
var _vy = b.x - a.x;
|
||||
|
||||
//normalize
|
||||
var _vxn = _vx / d;
|
||||
var _vyn = _vy / d;
|
||||
|
||||
_vx = _vxn * off;
|
||||
_vy = _vyn * off;
|
||||
|
||||
ctx.beginPath();
|
||||
|
||||
var _ax = a.x + _vx;
|
||||
var _ay = a.y + _vy;
|
||||
var _bx = b.x + _vx;
|
||||
var _by = b.y + _vy;
|
||||
|
||||
ctx.moveTo(_ax, _ay);
|
||||
ctx.lineTo(_bx, _by);
|
||||
|
||||
|
||||
function drawRef(start, x, y) {
|
||||
var vec = new Vector(x - start.x, y - start.y);
|
||||
vec._normalize();
|
||||
vec._multiply(7 * viewer.dimScale);
|
||||
|
||||
ctx.moveTo(start.x, start.y );
|
||||
ctx.lineTo(x, y);
|
||||
ctx.lineTo(x + vec.x, y + vec.y);
|
||||
}
|
||||
|
||||
drawRef(startA, _ax, _ay);
|
||||
drawRef(startB, _bx, _by);
|
||||
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
function drawArrow(x, y) {
|
||||
var s1 = 50;
|
||||
var s2 = 20;
|
||||
ctx.lineCap = 'round';
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(x, y);
|
||||
ctx.lineTo(x - s1, y - s2);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// drawArrow(_ax, _ay);
|
||||
// drawArrow(_bx, _by);
|
||||
|
||||
ctx.font= (12 * viewer.dimScale) + "px Arial";
|
||||
var txt = d.toFixed(2);
|
||||
var h = d / 2 - ctx.measureText(txt).width / 2;
|
||||
|
||||
if (h > 0) {
|
||||
var tx = (_ax + _vxn * textOff) - (- _vyn) * h;
|
||||
var ty = (_ay + _vyn * textOff) - ( _vxn) * h;
|
||||
ctx.save();
|
||||
ctx.translate(tx, ty);
|
||||
ctx.rotate( - Math.atan2(_vxn, _vyn));
|
||||
ctx.scale(1, -1);
|
||||
ctx.fillText(txt, 0, 0);
|
||||
ctx.restore();
|
||||
}
|
||||
}
|
||||
|
||||
normalDistance(aim) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
var vertOff = LinearDimension.getTextOff(viewer.dimScale);
|
||||
var horOff = 5 * viewer.dimScale;
|
||||
export class Dimension extends LinearDimension {
|
||||
constructor(a, b) {
|
||||
super(a, b);
|
||||
}
|
||||
}
|
||||
Dimension.prototype._class = 'TCAD.TWO.Dimension';
|
||||
|
||||
var fontSize = 12 * viewer.dimScale;
|
||||
ctx.font = (fontSize) + "px Arial";
|
||||
var txt = 'R ' + r.toFixed(2);
|
||||
var textWidth = ctx.measureText(txt).width;
|
||||
|
||||
var startX = this.obj.c.x + hxn * r;
|
||||
var startY = this.obj.c.y + hyn * r;
|
||||
var lineLength = textWidth + horOff * 2;
|
||||
export class HDimension extends LinearDimension {
|
||||
constructor(a, b) {
|
||||
super(a, b);
|
||||
}
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(startX, startY);
|
||||
ctx.lineTo(startX + hxn * lineLength, startY + hyn * lineLength);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
getA() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
getB() {
|
||||
return {x: this.b.x, y: this.a.y};
|
||||
}
|
||||
}
|
||||
HDimension.prototype._class = 'TCAD.TWO.HDimension';
|
||||
|
||||
var tx = startX + vxn * vertOff + hxn * horOff;
|
||||
var ty = startY + vyn * vertOff + hyn * horOff;
|
||||
ctx.save();
|
||||
ctx.translate(tx, ty);
|
||||
ctx.rotate(-Math.atan2(vxn, vyn));
|
||||
ctx.scale(1, -1);
|
||||
ctx.fillText(txt, 0, 0);
|
||||
ctx.restore();
|
||||
};
|
||||
export class VDimension extends LinearDimension {
|
||||
|
||||
constructor(a, b) {
|
||||
super(a, b);
|
||||
}
|
||||
|
||||
getA() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
getB() {
|
||||
return {x: this.a.x, y: this.b.y};
|
||||
}
|
||||
}
|
||||
VDimension.prototype._class = 'TCAD.TWO.VDimension';
|
||||
|
||||
|
||||
export class DiameterDimension extends SketchObject {
|
||||
|
||||
constructor(obj) {
|
||||
super();
|
||||
this.obj = obj;
|
||||
this.angle = Math.PI / 4;
|
||||
}
|
||||
|
||||
collectParams(params) {
|
||||
}
|
||||
|
||||
getReferencePoint() {
|
||||
}
|
||||
|
||||
translateImpl(dx, dy) {
|
||||
}
|
||||
|
||||
drawImpl(ctx, scale, viewer) {
|
||||
if (this.obj == null) return;
|
||||
if (this.obj._class === 'TCAD.TWO.Circle') {
|
||||
this.drawForCircle(ctx, scale, viewer);
|
||||
} else if (this.obj._class === 'TCAD.TWO.Arc') {
|
||||
this.drawForArc(ctx, scale, viewer);
|
||||
}
|
||||
}
|
||||
|
||||
drawForCircle(ctx, scale, viewer) {
|
||||
var c = new Vector().setV(this.obj.c);
|
||||
var r = this.obj.r.get();
|
||||
var angled = new Vector(r * Math.cos(this.angle), r * Math.sin(this.angle), 0);
|
||||
var a = c.minus(angled);
|
||||
var b = c.plus(angled);
|
||||
var textOff = getTextOff(viewer.dimScale);
|
||||
|
||||
var d = 2 * r;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(a.x, a.y);
|
||||
ctx.lineTo(b.x, b.y);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
var fontSize = 12 * viewer.dimScale;
|
||||
ctx.font = (fontSize) + "px Arial";
|
||||
var txt = String.fromCharCode(216) + ' ' + d.toFixed(2);
|
||||
var textWidth = ctx.measureText(txt).width;
|
||||
var h = d / 2 - textWidth / 2;
|
||||
|
||||
var _vx = - (b.y - a.y);
|
||||
var _vy = b.x - a.x;
|
||||
|
||||
//normalize
|
||||
var _vxn = _vx / d;
|
||||
var _vyn = _vy / d;
|
||||
|
||||
function drawText(tx, ty) {
|
||||
ctx.save();
|
||||
ctx.translate(tx, ty);
|
||||
ctx.rotate(-Math.atan2(_vxn, _vyn));
|
||||
ctx.scale(1, -1);
|
||||
ctx.fillText(txt, 0, 0);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
var tx, ty;
|
||||
if (h - fontSize * .3 > 0) { // take into account font size to not have circle overlap symbols
|
||||
tx = (a.x + _vxn * textOff) - (-_vyn) * h;
|
||||
ty = (a.y + _vyn * textOff) - ( _vxn) * h;
|
||||
drawText(tx, ty);
|
||||
} else {
|
||||
var off = 2 * viewer.dimScale;
|
||||
angled._normalize();
|
||||
var extraLine = angled.multiply(textWidth + off * 2);
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(b.x, b.y);
|
||||
ctx.lineTo(b.x + extraLine.x, b.y + extraLine.y);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
angled._multiply(off);
|
||||
|
||||
tx = (b.x + _vxn * textOff) + angled.x;
|
||||
ty = (b.y + _vyn * textOff) + angled.y;
|
||||
drawText(tx, ty);
|
||||
}
|
||||
}
|
||||
|
||||
drawForArc(ctx, scale, viewer) {
|
||||
|
||||
var r = this.obj.distanceA();
|
||||
|
||||
var hxn = Math.cos(this.angle);
|
||||
var hyn = Math.sin(this.angle);
|
||||
|
||||
var vxn = - hyn;
|
||||
var vyn = hxn;
|
||||
|
||||
//fix angle if needed
|
||||
if (!this.obj.isPointInsideSector(this.obj.c.x + hxn, this.obj.c.y + hyn)) {
|
||||
var cosA = hxn * (this.obj.a.x - this.obj.c.x) + hyn * (this.obj.a.y - this.obj.c.y);
|
||||
var cosB = hxn * (this.obj.b.x - this.obj.c.x) + hyn * (this.obj.b.y - this.obj.c.y);
|
||||
if (cosA - hxn > cosB - hxn) {
|
||||
this.angle = this.obj.getStartAngle();
|
||||
} else {
|
||||
this.angle = this.obj.getEndAngle();
|
||||
}
|
||||
}
|
||||
|
||||
var vertOff = getTextOff(viewer.dimScale);
|
||||
var horOff = 5 * viewer.dimScale;
|
||||
|
||||
var fontSize = 12 * viewer.dimScale;
|
||||
ctx.font = (fontSize) + "px Arial";
|
||||
var txt = 'R ' + r.toFixed(2);
|
||||
var textWidth = ctx.measureText(txt).width;
|
||||
|
||||
var startX = this.obj.c.x + hxn * r;
|
||||
var startY = this.obj.c.y + hyn * r;
|
||||
var lineLength = textWidth + horOff * 2;
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(startX, startY);
|
||||
ctx.lineTo(startX + hxn * lineLength, startY + hyn * lineLength);
|
||||
ctx.closePath();
|
||||
ctx.stroke();
|
||||
|
||||
var tx = startX + vxn * vertOff + hxn * horOff;
|
||||
var ty = startY + vyn * vertOff + hyn * horOff;
|
||||
ctx.save();
|
||||
ctx.translate(tx, ty);
|
||||
ctx.rotate(-Math.atan2(vxn, vyn));
|
||||
ctx.scale(1, -1);
|
||||
ctx.fillText(txt, 0, 0);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
normalDistance(aim) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
DiameterDimension.prototype._class = 'TCAD.TWO.DiameterDimension';
|
||||
|
||||
|
||||
function getTextOff(scale) {
|
||||
return 3 * scale;
|
||||
}
|
||||
|
||||
DiameterDimension.prototype.normalDistance = function(aim) {
|
||||
return -1;
|
||||
};
|
||||
|
||||
export {HDimension, VDimension, Dimension, DiameterDimension}
|
||||
|
|
|
|||
12
web/app/sketcher/shapes/draw-utils.js
Normal file
12
web/app/sketcher/shapes/draw-utils.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
export function DrawPoint(ctx, x, y, rad, scale) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, rad / scale, 0, 2 * Math.PI, false);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
export function SetStyle(style, ctx, scale) {
|
||||
ctx.lineWidth = style.lineWidth / scale;
|
||||
ctx.strokeStyle = style.strokeStyle;
|
||||
ctx.fillStyle = style.fillStyle;
|
||||
}
|
||||
55
web/app/sketcher/shapes/point.js
Normal file
55
web/app/sketcher/shapes/point.js
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
import {SketchObject} from './sketch-object'
|
||||
import {DrawPoint} from './draw-utils'
|
||||
import {Generator} from '../id-generator'
|
||||
import Vector from '../../math/vector'
|
||||
|
||||
export class EndPoint extends SketchObject {
|
||||
|
||||
constructor(x, y) {
|
||||
super();
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.parent = null;
|
||||
this._x = new Param(this, 'x');
|
||||
this._y = new Param(this, 'y');
|
||||
}
|
||||
|
||||
collectParams(params) {
|
||||
params.push(this._x);
|
||||
params.push(this._y);
|
||||
}
|
||||
|
||||
normalDistance(aim) {
|
||||
return aim.minus(new Vector(this.x, this.y)).length();
|
||||
}
|
||||
|
||||
getReferencePoint() {
|
||||
return this;
|
||||
}
|
||||
|
||||
translateImpl(dx, dy) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
}
|
||||
|
||||
drawImpl(ctx, scale) {
|
||||
DrawPoint(ctx, this.x, this.y, 3, scale)
|
||||
}
|
||||
}
|
||||
EndPoint.prototype._class = 'TCAD.TWO.EndPoint';
|
||||
|
||||
export class Param {
|
||||
constructor(obj, prop) {
|
||||
this.id = Generator.genID();
|
||||
this.obj = obj;
|
||||
this.prop = prop;
|
||||
}
|
||||
|
||||
set(value) {
|
||||
this.obj[this.prop] = value;
|
||||
}
|
||||
|
||||
get() {
|
||||
return this.obj[this.prop];
|
||||
}
|
||||
}
|
||||
14
web/app/sketcher/shapes/ref.js
Normal file
14
web/app/sketcher/shapes/ref.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import {Generator} from '../id-generator'
|
||||
|
||||
export function Ref(value) {
|
||||
this.id = Generator.genID();
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
Ref.prototype.set = function(value) {
|
||||
this.value = value;
|
||||
};
|
||||
|
||||
Ref.prototype.get = function() {
|
||||
return this.value;
|
||||
};
|
||||
74
web/app/sketcher/shapes/segment.js
Normal file
74
web/app/sketcher/shapes/segment.js
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
import {SketchObject} from './sketch-object'
|
||||
import Vector from '../../math/vector'
|
||||
import * as math from '../../math/math'
|
||||
|
||||
export class Segment extends SketchObject {
|
||||
|
||||
constructor(a, b) {
|
||||
super();
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
a.parent = this;
|
||||
b.parent = this;
|
||||
this.children.push(a, b);
|
||||
}
|
||||
|
||||
validate() {
|
||||
return math.distanceAB(this.a, this.b) > math.TOLERANCE;
|
||||
}
|
||||
|
||||
recover() {
|
||||
var recoverLength = 100;
|
||||
this.a.translate(-recoverLength, -recoverLength);
|
||||
this.b.translate( recoverLength, recoverLength);
|
||||
}
|
||||
|
||||
collectParams(params) {
|
||||
this.a.collectParams(params);
|
||||
this.b.collectParams(params);
|
||||
}
|
||||
|
||||
normalDistance(aim) {
|
||||
var x = aim.x;
|
||||
var y = aim.y;
|
||||
|
||||
var ab = new Vector(this.b.x - this.a.x, this.b.y - this.a.y)
|
||||
var e = ab.normalize();
|
||||
var a = new Vector(aim.x - this.a.x, aim.y - this.a.y);
|
||||
var b = e.multiply(a.dot(e));
|
||||
var n = a.minus(b);
|
||||
|
||||
//Check if vector b lays on the vector ab
|
||||
if (b.length() > ab.length()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (b.dot(ab) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n.length();
|
||||
}
|
||||
|
||||
getReferencePoint() {
|
||||
return this.a;
|
||||
}
|
||||
|
||||
translateImpl(dx, dy) {
|
||||
this.a.translate(dx, dy);
|
||||
this.b.translate(dx, dy);
|
||||
}
|
||||
|
||||
drawImpl(ctx, scale) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.a.x, this.a.y);
|
||||
ctx.lineTo(this.b.x, this.b.y);
|
||||
// ctx.save();
|
||||
// ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
ctx.stroke();
|
||||
// ctx.restore();
|
||||
}
|
||||
}
|
||||
|
||||
Segment.prototype._class = 'TCAD.TWO.Segment';
|
||||
|
||||
85
web/app/sketcher/shapes/sketch-object.js
Normal file
85
web/app/sketcher/shapes/sketch-object.js
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
import {Generator} from '../id-generator'
|
||||
import {SetStyle} from './draw-utils'
|
||||
import {DragTool} from '../tools/drag'
|
||||
|
||||
export class SketchObject {
|
||||
constructor() {
|
||||
this.id = Generator.genID();
|
||||
this.aux = false;
|
||||
this.marked = null;
|
||||
this.visible = true;
|
||||
this.children = [];
|
||||
this.linked = [];
|
||||
this.layer = null;
|
||||
}
|
||||
|
||||
accept(visitor) {
|
||||
return this.acceptV(false, visitor);
|
||||
}
|
||||
|
||||
acceptV(onlyVisible, visitor) {
|
||||
if (onlyVisible && !this.visible) return true;
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if (!child.acceptV(onlyVisible, visitor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return visitor(this);
|
||||
}
|
||||
|
||||
validate() {
|
||||
return true;
|
||||
}
|
||||
|
||||
recover() {
|
||||
}
|
||||
|
||||
getDefaultTool(viewer) {
|
||||
return new DragTool(this, viewer);
|
||||
}
|
||||
|
||||
isAuxOrLinkedTo() {
|
||||
if (!!this.aux) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0; i < this.linked.length; ++i) {
|
||||
if (!!this.linked[i].aux) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
_translate(dx, dy, translated) {
|
||||
translated[this.id] = 'x';
|
||||
for (var i = 0; i < this.linked.length; ++i) {
|
||||
if (translated[this.linked[i].id] != 'x') {
|
||||
this.linked[i]._translate(dx, dy, translated);
|
||||
}
|
||||
}
|
||||
this.translateImpl(dx, dy);
|
||||
};
|
||||
|
||||
translate(dx, dy) {
|
||||
// this.translateImpl(dx, dy);
|
||||
if (this.isAuxOrLinkedTo()) {
|
||||
return;
|
||||
}
|
||||
this._translate(dx, dy, {});
|
||||
}
|
||||
|
||||
draw(ctx, scale, viewer) {
|
||||
if (!this.visible) return;
|
||||
if (this.marked != null) {
|
||||
ctx.save();
|
||||
SetStyle(this.marked, ctx, scale);
|
||||
}
|
||||
this.drawImpl(ctx, scale, viewer);
|
||||
if (this.marked != null) ctx.restore();
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
this.children[i].draw(ctx, scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,11 +1,15 @@
|
|||
import {Generator} from './id-generator'
|
||||
import {Parameters, Bus} from '../ui/toolkit'
|
||||
import {ParametricManager} from './parametric'
|
||||
import {HistoryManager} from './history'
|
||||
import {ToolManager} from './tools/manager'
|
||||
import {PanTool} from './tools/pan'
|
||||
import {DragTool} from './tools/drag'
|
||||
import {Segment} from './shapes/segment'
|
||||
import {EndPoint} from './shapes/point'
|
||||
import Vector from '../math/vector'
|
||||
import * as utils from '../utils/utils'
|
||||
|
||||
import * as draw_utils from './shapes/draw-utils'
|
||||
import * as math from '../math/math'
|
||||
|
||||
var Styles = {
|
||||
|
|
@ -53,18 +57,6 @@ var Styles = {
|
|||
};
|
||||
|
||||
|
||||
function _drawPoint(ctx, x, y, rad, scale) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, rad / scale, 0, 2 * Math.PI, false);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
function setStyle(style, ctx, scale) {
|
||||
ctx.lineWidth = style.lineWidth / scale;
|
||||
ctx.strokeStyle = style.strokeStyle;
|
||||
ctx.fillStyle = style.fillStyle;
|
||||
}
|
||||
|
||||
/** @constructor */
|
||||
function Viewer(canvas, IO) {
|
||||
|
||||
|
|
@ -264,7 +256,7 @@ Viewer.prototype.repaint = function() {
|
|||
for (var o = 0; o < layer.objects.length; o++) {
|
||||
var obj = layer.objects[o];
|
||||
style = obj.style != null ? obj.style : layer.style;
|
||||
if (style != prevStyle) setStyle(style, ctx, this.scale / this.retinaPxielRatio);
|
||||
if (style != prevStyle) draw_utils.SetStyle(style, ctx, this.scale / this.retinaPxielRatio);
|
||||
obj.draw(ctx, this.scale / this.retinaPxielRatio, this);
|
||||
}
|
||||
}
|
||||
|
|
@ -477,231 +469,6 @@ Polyline.prototype.draw = function(ctx) {
|
|||
ctx.stroke();
|
||||
};
|
||||
|
||||
var ID_COUNTER = 0;
|
||||
|
||||
/** @constructor */
|
||||
function SketchObject() {
|
||||
this.id = SketchObject.genID();
|
||||
this.aux = false;
|
||||
this.marked = null;
|
||||
this.visible = true;
|
||||
this.children = [];
|
||||
this.linked = [];
|
||||
this.layer = null;
|
||||
}
|
||||
|
||||
SketchObject.genID = function() {
|
||||
return ID_COUNTER ++;
|
||||
};
|
||||
|
||||
SketchObject.resetIDGenerator = function(value) {
|
||||
ID_COUNTER = value;
|
||||
};
|
||||
|
||||
SketchObject.prototype.accept = function(visitor) {
|
||||
return this.acceptV(false, visitor);
|
||||
};
|
||||
|
||||
SketchObject.prototype.acceptV = function(onlyVisible, visitor) {
|
||||
if (onlyVisible && !this.visible) return true;
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
var child = this.children[i];
|
||||
if (!child.acceptV(onlyVisible, visitor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return visitor(this);
|
||||
};
|
||||
|
||||
SketchObject.prototype.validate = function() {
|
||||
return true;
|
||||
};
|
||||
|
||||
SketchObject.prototype.recover = function() {
|
||||
};
|
||||
|
||||
SketchObject.prototype.getDefaultTool = function(viewer) {
|
||||
return new DragTool(this, viewer);
|
||||
};
|
||||
|
||||
SketchObject.prototype.isAuxOrLinkedTo = function() {
|
||||
if (!!this.aux) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0; i < this.linked.length; ++i) {
|
||||
if (!!this.linked[i].aux) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
SketchObject.prototype._translate = function(dx, dy, translated) {
|
||||
translated[this.id] = 'x';
|
||||
for (var i = 0; i < this.linked.length; ++i) {
|
||||
if (translated[this.linked[i].id] != 'x') {
|
||||
this.linked[i]._translate(dx, dy, translated);
|
||||
}
|
||||
}
|
||||
this.translateImpl(dx, dy);
|
||||
};
|
||||
|
||||
SketchObject.prototype.translate = function(dx, dy) {
|
||||
// this.translateImpl(dx, dy);
|
||||
if (this.isAuxOrLinkedTo()) {
|
||||
return;
|
||||
}
|
||||
this._translate(dx, dy, {});
|
||||
};
|
||||
|
||||
SketchObject.prototype.draw = function(ctx, scale, viewer) {
|
||||
if (!this.visible) return;
|
||||
if (this.marked != null) {
|
||||
ctx.save();
|
||||
setStyle(this.marked, ctx, scale);
|
||||
}
|
||||
this.drawImpl(ctx, scale, viewer);
|
||||
if (this.marked != null) ctx.restore();
|
||||
for (var i = 0; i < this.children.length; i++) {
|
||||
this.children[i].draw(ctx, scale);
|
||||
}
|
||||
};
|
||||
|
||||
/** @constructor */
|
||||
function Ref(value) {
|
||||
this.id = SketchObject.genID();
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
Ref.prototype.set = function(value) {
|
||||
this.value = value;
|
||||
};
|
||||
|
||||
Ref.prototype.get = function() {
|
||||
return this.value;
|
||||
};
|
||||
|
||||
/** @constructor */
|
||||
function Param(obj, prop) {
|
||||
this.id = SketchObject.genID();
|
||||
this.obj = obj;
|
||||
this.prop = prop;
|
||||
}
|
||||
|
||||
Param.prototype.set = function(value) {
|
||||
this.obj[this.prop] = value;
|
||||
};
|
||||
|
||||
Param.prototype.get = function() {
|
||||
return this.obj[this.prop];
|
||||
};
|
||||
|
||||
/** @constructor */
|
||||
function EndPoint(x, y) {
|
||||
SketchObject.call(this);
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.parent = null;
|
||||
this._x = new Param(this, 'x');
|
||||
this._y = new Param(this, 'y');
|
||||
}
|
||||
|
||||
utils.extend(EndPoint, SketchObject);
|
||||
|
||||
EndPoint.prototype._class = 'TCAD.TWO.EndPoint';
|
||||
|
||||
EndPoint.prototype.collectParams = function(params) {
|
||||
params.push(this._x);
|
||||
params.push(this._y);
|
||||
};
|
||||
|
||||
EndPoint.prototype.normalDistance = function(aim) {
|
||||
return aim.minus(new Vector(this.x, this.y)).length();
|
||||
};
|
||||
|
||||
EndPoint.prototype.getReferencePoint = function() {
|
||||
return this;
|
||||
};
|
||||
|
||||
EndPoint.prototype.translateImpl = function(dx, dy) {
|
||||
this.x += dx;
|
||||
this.y += dy;
|
||||
};
|
||||
|
||||
EndPoint.prototype.drawImpl = function(ctx, scale) {
|
||||
_drawPoint(ctx, this.x, this.y, 3, scale)
|
||||
};
|
||||
|
||||
/** @constructor */
|
||||
function Segment(a, b) {
|
||||
SketchObject.call(this);
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
a.parent = this;
|
||||
b.parent = this;
|
||||
this.children.push(a, b);
|
||||
}
|
||||
|
||||
utils.extend(Segment, SketchObject);
|
||||
|
||||
Segment.prototype._class = 'TCAD.TWO.Segment';
|
||||
|
||||
Segment.prototype.validate = function() {
|
||||
return math.distanceAB(this.a, this.b) > math.TOLERANCE;
|
||||
};
|
||||
|
||||
Segment.prototype.recover = function() {
|
||||
var recoverLength = 100;
|
||||
this.a.translate(-recoverLength, -recoverLength);
|
||||
this.b.translate( recoverLength, recoverLength);
|
||||
};
|
||||
|
||||
Segment.prototype.collectParams = function(params) {
|
||||
this.a.collectParams(params);
|
||||
this.b.collectParams(params);
|
||||
};
|
||||
|
||||
Segment.prototype.normalDistance = function(aim) {
|
||||
var x = aim.x;
|
||||
var y = aim.y;
|
||||
|
||||
var ab = new Vector(this.b.x - this.a.x, this.b.y - this.a.y)
|
||||
var e = ab.normalize();
|
||||
var a = new Vector(aim.x - this.a.x, aim.y - this.a.y);
|
||||
var b = e.multiply(a.dot(e));
|
||||
var n = a.minus(b);
|
||||
|
||||
//Check if vector b lays on the vector ab
|
||||
if (b.length() > ab.length()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (b.dot(ab) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n.length();
|
||||
};
|
||||
|
||||
Segment.prototype.getReferencePoint = function() {
|
||||
return this.a;
|
||||
};
|
||||
|
||||
Segment.prototype.translateImpl = function(dx, dy) {
|
||||
this.a.translate(dx, dy);
|
||||
this.b.translate(dx, dy);
|
||||
};
|
||||
|
||||
Segment.prototype.drawImpl = function(ctx, scale) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(this.a.x, this.a.y);
|
||||
ctx.lineTo(this.b.x, this.b.y);
|
||||
// ctx.save();
|
||||
// ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
ctx.stroke();
|
||||
// ctx.restore();
|
||||
};
|
||||
|
||||
/** @constructor */
|
||||
function Point(x, y, rad) {
|
||||
this.x = x;
|
||||
|
|
@ -711,7 +478,7 @@ function Point(x, y, rad) {
|
|||
}
|
||||
|
||||
Point.prototype.draw = function(ctx, scale) {
|
||||
_drawPoint(ctx, this.x, this.y, this.rad, scale);
|
||||
draw_utils.DrawPoint(ctx, this.x, this.y, this.rad, scale);
|
||||
};
|
||||
|
||||
/** @constructor */
|
||||
|
|
@ -825,4 +592,4 @@ ReferencePoint.prototype.draw = function(ctx, scale) {
|
|||
ctx.stroke();
|
||||
};
|
||||
|
||||
export {Styles, Viewer, Layer, SketchObject, EndPoint, Point, Segment, Ref}
|
||||
export {Viewer, Layer, Styles}
|
||||
Loading…
Reference in a new issue