mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-15 04:45:06 +01:00
rewrite point, line and origin using classes
This commit is contained in:
parent
8e67c2cd39
commit
238e9ffb04
10 changed files with 236 additions and 214 deletions
|
|
@ -1,82 +0,0 @@
|
|||
/** @constructor */
|
||||
export function ReferencePointTool(viewer) {
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
ReferencePointTool.prototype.keydown = function(e) {};
|
||||
ReferencePointTool.prototype.keypress = function(e) {};
|
||||
ReferencePointTool.prototype.keyup = function(e) {};
|
||||
|
||||
ReferencePointTool.prototype.restart = function(e) {
|
||||
this.sendMessage('specify point');
|
||||
};
|
||||
|
||||
ReferencePointTool.prototype.sendMessage = function(text) {
|
||||
this.viewer.bus.notify('tool-message', text);
|
||||
};
|
||||
|
||||
ReferencePointTool.prototype.cleanup = function(e) {
|
||||
this.viewer.cleanSnap();
|
||||
};
|
||||
|
||||
ReferencePointTool.prototype.mousemove = function(e) {
|
||||
var p = this.viewer.screenToModel(e);
|
||||
this.viewer.snap(p.x, p.y, []);
|
||||
this.viewer.refresh();
|
||||
};
|
||||
|
||||
ReferencePointTool.prototype.mouseup = function(e) {
|
||||
};
|
||||
|
||||
ReferencePointTool.prototype.mousedown = function(e) {
|
||||
const needSnap = this.viewer.snapped.length != 0;
|
||||
let p = needSnap ? this.viewer.snapped.pop() : this.viewer.screenToModel(e);
|
||||
this.viewer.referencePoint.x = p.x;
|
||||
this.viewer.referencePoint.y = p.y;
|
||||
this.sendMessage(p.x + ', ' + p.y);
|
||||
this.viewer.refresh();
|
||||
this.viewer.toolManager.releaseControl();
|
||||
};
|
||||
|
||||
ReferencePointTool.prototype.mousewheel = function(e) {
|
||||
};
|
||||
|
||||
ReferencePointTool.prototype.processCommand = function(command) {
|
||||
var referencePoint = this.viewer.referencePoint;
|
||||
let result = ParseVector(referencePoint, command);
|
||||
if(typeof result === 'string') {
|
||||
return result;
|
||||
}
|
||||
referencePoint.x += result.x;
|
||||
referencePoint.y += result.y;
|
||||
this.viewer.refresh();
|
||||
this.viewer.toolManager.releaseControl();
|
||||
|
||||
};
|
||||
|
||||
const VECTOR_PATTERNS = /^(@)?(.+)(,|<)(.+)$/;
|
||||
|
||||
function ParseVector(referencePoint, command) {
|
||||
command = command.replace(/\s+/g, '');
|
||||
|
||||
const match = command.match(VECTOR_PATTERNS);
|
||||
if (match) {
|
||||
const ref = !match[1];
|
||||
let x = parseFloat(eval(match[2]));
|
||||
if (isNaN(x)) return "wrong input for number: " + match[2];
|
||||
const polar = match[3] == '<';
|
||||
let y = parseFloat(eval(match[4]));
|
||||
if (isNaN(y)) return "wrong input for number: " + match[4];
|
||||
if (polar) {
|
||||
y = y * Math.sin(x);
|
||||
x = x * Math.cos(x);
|
||||
}
|
||||
if (ref) {
|
||||
x += referencePoint.x;
|
||||
y += referencePoint.y;
|
||||
}
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
return "wrong input, point is expected: x,y | @x,y | r<polar ";
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
import {EndPoint} from '../viewer2d'
|
||||
|
||||
/** @constructor */
|
||||
function AddSegmentTool(viewer, multi) {
|
||||
this.viewer = viewer;
|
||||
this.line = null;
|
||||
this.multi = multi;
|
||||
}
|
||||
|
||||
AddSegmentTool.prototype.mousemove = function(e) {
|
||||
var p = this.viewer.screenToModel(e);
|
||||
if (this.line != null) {
|
||||
this.viewer.snap(p.x, p.y, [this.line.a, this.line.b]);
|
||||
this.line.b.x = p.x;
|
||||
this.line.b.y = p.y;
|
||||
this.viewer.refresh();
|
||||
} else {
|
||||
this.viewer.snap(p.x, p.y, []);
|
||||
this.viewer.refresh();
|
||||
}
|
||||
};
|
||||
|
||||
AddSegmentTool.prototype.cleanup = function(e) {
|
||||
this.viewer.cleanSnap();
|
||||
this.line = null;
|
||||
};
|
||||
|
||||
AddSegmentTool.prototype.mousedown = function(e) {
|
||||
|
||||
};
|
||||
|
||||
AddSegmentTool.prototype.mouseup = function(e) {
|
||||
if (this.line == null) {
|
||||
const b = this.viewer.screenToModel(e);
|
||||
var a = b;
|
||||
var needSnap = false;
|
||||
if (this.viewer.snapped.length != 0) {
|
||||
a = this.viewer.snapped.pop();
|
||||
this.viewer.cleanSnap();
|
||||
needSnap = true;
|
||||
}
|
||||
this.line = this.viewer.addSegment(a.x, a.y, b.x, b.y, this.viewer.activeLayer);
|
||||
if (needSnap) {
|
||||
this.viewer.parametricManager.linkObjects([this.line.a, a]);
|
||||
}
|
||||
this.viewer.refresh();
|
||||
} else {
|
||||
if (this.viewer.snapped.length != 0) {
|
||||
var p = this.viewer.snapped.pop();
|
||||
this.viewer.cleanSnap();
|
||||
this.line.b.x = p.x;
|
||||
this.line.b.y = p.y;
|
||||
this.viewer.parametricManager.linkObjects([this.line.b, p]);
|
||||
this.viewer.refresh();
|
||||
}
|
||||
if (this.multi) {
|
||||
const b = this.line.b;
|
||||
this.line = this.viewer.addSegment(b.x, b.y, b.x, b.y, this.viewer.activeLayer);
|
||||
this.viewer.parametricManager.linkObjects([this.line.a, b]);
|
||||
} else {
|
||||
this.line = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AddSegmentTool.prototype.dblclick = function(e) {
|
||||
this.cancelSegment();
|
||||
};
|
||||
|
||||
AddSegmentTool.prototype.mousewheel = function(e) {
|
||||
};
|
||||
|
||||
AddSegmentTool.prototype.keydown = function(e) {
|
||||
if (e.keyCode == 27) {
|
||||
this.cancelSegment();
|
||||
}
|
||||
};
|
||||
|
||||
AddSegmentTool.prototype.cancelSegment = function() {
|
||||
if (this.multi && this.line != null) {
|
||||
this.viewer.remove(this.line);
|
||||
this.viewer.refresh();
|
||||
this.cleanup(null);
|
||||
}
|
||||
};
|
||||
|
||||
AddSegmentTool.prototype.keypress = function(e) {};
|
||||
AddSegmentTool.prototype.keyup = function(e) {};
|
||||
|
||||
/** @constructor */
|
||||
function AddPointTool(viewer) {
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
AddPointTool.prototype.mousemove = function(e) {
|
||||
};
|
||||
|
||||
AddPointTool.prototype.cleanup = function(e) {
|
||||
};
|
||||
|
||||
AddPointTool.prototype.mousedown = function(e) {
|
||||
};
|
||||
|
||||
AddPointTool.prototype.mouseup = function(e) {
|
||||
this.viewer.historyManager.checkpoint();
|
||||
var a = this.viewer.screenToModel(e);
|
||||
var p = new EndPoint(a.x, a.y);
|
||||
var layer = this.viewer.activeLayer;
|
||||
layer.objects.push(p);
|
||||
p.layer = layer;
|
||||
this.viewer.refresh();
|
||||
};
|
||||
|
||||
AddPointTool.prototype.mousewheel = function(e) {
|
||||
};
|
||||
|
||||
AddPointTool.prototype.keydown = function(e) {
|
||||
};
|
||||
|
||||
AddSegmentTool.prototype.keypress = function(e) {};
|
||||
AddSegmentTool.prototype.keyup = function(e) {};
|
||||
|
||||
export {AddSegmentTool, AddPointTool}
|
||||
|
|
@ -3,11 +3,12 @@ import * as ui from '../ui/ui'
|
|||
import {Terminal} from '../ui/terminal'
|
||||
import {IO, BBox} from './io'
|
||||
import {AddDimTool, AddCircleDimTool, HDimension, VDimension, Dimension, DiameterDimension} from './shapes/dim'
|
||||
import {AddPointTool, AddSegmentTool} from './shapes/segment'
|
||||
import {AddPointTool} from './tools/point'
|
||||
import {AddSegmentTool} from './tools/segment'
|
||||
import {AddArcTool} from './shapes/arc'
|
||||
import {EditCircleTool} from './shapes/circle'
|
||||
import {FilletTool} from './helpers'
|
||||
import {ReferencePointTool} from './shapes/origin'
|
||||
import {ReferencePointTool} from './tools/origin'
|
||||
import {InputManager} from './input-manager'
|
||||
|
||||
/** @constructor */
|
||||
|
|
@ -371,9 +372,11 @@ App2D.prototype.bindToolsToTerminal = function() {
|
|||
this.viewer.bus.subscribe('tool-state', () => {
|
||||
var tool = this.viewer.toolManager.tool;
|
||||
this.terminalHandler = tool.processCommand;
|
||||
});
|
||||
$('.tool-info').text('tool: ' + tool.name);
|
||||
})();
|
||||
this.viewer.bus.subscribe('tool-message', (message) => {
|
||||
this.terminal.print(message);
|
||||
$('.tool-message').text(': ' + message);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
46
web/app/sketcher/tools/origin.js
Normal file
46
web/app/sketcher/tools/origin.js
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import {Tool} from './tool'
|
||||
|
||||
export class ReferencePointTool extends Tool {
|
||||
|
||||
constructor(viewer) {
|
||||
super('origin', viewer);
|
||||
}
|
||||
|
||||
restart() {
|
||||
this.sendMessage('specify point', false);
|
||||
};
|
||||
|
||||
cleanup(e) {
|
||||
this.viewer.cleanSnap();
|
||||
};
|
||||
|
||||
mousemove(e) {
|
||||
var p = this.viewer.screenToModel(e);
|
||||
this.viewer.snap(p.x, p.y, []);
|
||||
this.viewer.refresh();
|
||||
};
|
||||
|
||||
mousedown(e) {
|
||||
const needSnap = this.viewer.snapped.length != 0;
|
||||
let p = needSnap ? this.viewer.snapped.pop() : this.viewer.screenToModel(e);
|
||||
this.viewer.referencePoint.x = p.x;
|
||||
this.viewer.referencePoint.y = p.y;
|
||||
this.sendMessage(p.x + ', ' + p.y);
|
||||
this.viewer.refresh();
|
||||
this.viewer.toolManager.releaseControl();
|
||||
};
|
||||
|
||||
processCommand(command) {
|
||||
var referencePoint = this.viewer.referencePoint;
|
||||
let result = Tool.ParseVector(referencePoint, command);
|
||||
if(typeof result === 'string') {
|
||||
return result;
|
||||
}
|
||||
referencePoint.x += result.x;
|
||||
referencePoint.y += result.y;
|
||||
this.viewer.refresh();
|
||||
this.viewer.toolManager.releaseControl();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
19
web/app/sketcher/tools/point.js
Normal file
19
web/app/sketcher/tools/point.js
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import {EndPoint} from '../viewer2d'
|
||||
import {Tool} from './tool'
|
||||
|
||||
export class AddPointTool extends Tool{
|
||||
|
||||
constructor(viewer) {
|
||||
super('point', viewer);
|
||||
}
|
||||
|
||||
mouseup(e) {
|
||||
this.viewer.historyManager.checkpoint();
|
||||
var a = this.viewer.screenToModel(e);
|
||||
var p = new EndPoint(a.x, a.y);
|
||||
var layer = this.viewer.activeLayer;
|
||||
layer.objects.push(p);
|
||||
p.layer = layer;
|
||||
this.viewer.refresh();
|
||||
};
|
||||
}
|
||||
87
web/app/sketcher/tools/segment.js
Normal file
87
web/app/sketcher/tools/segment.js
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
import {Tool} from './tool'
|
||||
|
||||
export class AddSegmentTool extends Tool {
|
||||
|
||||
constructor(viewer, multi) {
|
||||
super(multi ? "multi line" : "line", viewer);
|
||||
this.line = null;
|
||||
this.multi = multi;
|
||||
}
|
||||
|
||||
restart(e) {
|
||||
this.sendMessage('specify the first point')
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
this.viewer.cleanSnap();
|
||||
this.line = null;
|
||||
}
|
||||
|
||||
|
||||
mousemove(e) {
|
||||
var p = this.viewer.screenToModel(e);
|
||||
if (this.line != null) {
|
||||
this.viewer.snap(p.x, p.y, [this.line.a, this.line.b]);
|
||||
this.line.b.x = p.x;
|
||||
this.line.b.y = p.y;
|
||||
this.viewer.refresh();
|
||||
} else {
|
||||
this.viewer.snap(p.x, p.y, []);
|
||||
this.viewer.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
mouseup(e) {
|
||||
if (this.line == null) {
|
||||
const b = this.viewer.screenToModel(e);
|
||||
var a = b;
|
||||
var needSnap = false;
|
||||
if (this.viewer.snapped.length != 0) {
|
||||
a = this.viewer.snapped.pop();
|
||||
this.viewer.cleanSnap();
|
||||
needSnap = true;
|
||||
}
|
||||
this.line = this.viewer.addSegment(a.x, a.y, b.x, b.y, this.viewer.activeLayer);
|
||||
if (needSnap) {
|
||||
this.viewer.parametricManager.linkObjects([this.line.a, a]);
|
||||
}
|
||||
this.sendMessage('specify ' + (this.multi ? 'next' : 'end') +' point');
|
||||
this.viewer.refresh();
|
||||
} else {
|
||||
if (this.viewer.snapped.length != 0) {
|
||||
var p = this.viewer.snapped.pop();
|
||||
this.viewer.cleanSnap();
|
||||
this.line.b.x = p.x;
|
||||
this.line.b.y = p.y;
|
||||
this.viewer.parametricManager.linkObjects([this.line.b, p]);
|
||||
this.viewer.refresh();
|
||||
}
|
||||
if (this.multi) {
|
||||
const b = this.line.b;
|
||||
this.line = this.viewer.addSegment(b.x, b.y, b.x, b.y, this.viewer.activeLayer);
|
||||
this.viewer.parametricManager.linkObjects([this.line.a, b]);
|
||||
} else {
|
||||
this.line = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dblclick(e) {
|
||||
this.cancelSegment();
|
||||
}
|
||||
|
||||
keydown(e) {
|
||||
if (e.keyCode == 27) {
|
||||
this.cancelSegment();
|
||||
}
|
||||
}
|
||||
|
||||
cancelSegment() {
|
||||
if (this.multi && this.line != null) {
|
||||
this.viewer.remove(this.line);
|
||||
this.viewer.refresh();
|
||||
this.cleanup(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
61
web/app/sketcher/tools/tool.js
Normal file
61
web/app/sketcher/tools/tool.js
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
|
||||
export class Tool {
|
||||
|
||||
constructor(name, viewer) {
|
||||
this.name = name;
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
restart() {};
|
||||
|
||||
cleanup() {};
|
||||
|
||||
mousemove(e) {};
|
||||
|
||||
mousedown(e) {};
|
||||
|
||||
mouseup(e) {};
|
||||
|
||||
dblclick(e) {};
|
||||
|
||||
mousewheel(e) {};
|
||||
|
||||
keydown(e) {};
|
||||
|
||||
keypress(e) {};
|
||||
|
||||
keyup(e) {};
|
||||
|
||||
sendMessage(text) {
|
||||
this.viewer.bus.notify('tool-message', text);
|
||||
};
|
||||
}
|
||||
|
||||
const VECTOR_PATTERNS = /^(@)?(.+)(,|<)(.+)$/;
|
||||
|
||||
Tool.ParseVector = function(referencePoint, command) {
|
||||
command = command.replace(/\s+/g, '');
|
||||
|
||||
const match = command.match(VECTOR_PATTERNS);
|
||||
if (match) {
|
||||
const ref = match[1] !== undefined;
|
||||
let x = parseFloat(eval(match[2]));
|
||||
if (isNaN(x)) return "wrong input for number: " + match[2];
|
||||
const polar = match[3] == '<';
|
||||
let y = parseFloat(eval(match[4]));
|
||||
if (isNaN(y)) return "wrong input for number: " + match[4];
|
||||
if (polar) {
|
||||
y = y * Math.sin(x);
|
||||
x = x * Math.cos(x);
|
||||
}
|
||||
if (ref) {
|
||||
x += referencePoint.x;
|
||||
y += referencePoint.y;
|
||||
}
|
||||
return {x, y};
|
||||
}
|
||||
|
||||
return "wrong input, point is expected: x,y | @x,y | r<polar ";
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -875,8 +875,7 @@ ToolManager.prototype.takeControl = function(tool) {
|
|||
|
||||
ToolManager.prototype.releaseControl = function() {
|
||||
this.tool.cleanup();
|
||||
this.tool = this.defaultTool;
|
||||
this.viewer.bus.notify("tool-state");
|
||||
this.takeControl(this.defaultTool);
|
||||
};
|
||||
|
||||
ToolManager.prototype.getTool = function() {
|
||||
|
|
|
|||
|
|
@ -309,12 +309,22 @@ input[type=checkbox], input[type=radio] {
|
|||
|
||||
#status {
|
||||
font-family: 'Helvetica Neue Light', HelveticaNeue-Light, 'Helvetica Neue', Helvetica, sans-serif;
|
||||
color: white;
|
||||
color: #fff;
|
||||
font-size: 11px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#status .coordinates-info {
|
||||
padding-right: 5px;
|
||||
font-style: italic;
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
.status-item {
|
||||
padding-right: 5px;
|
||||
padding-left: 5px;
|
||||
float: right;
|
||||
color:#bbb;
|
||||
}
|
||||
#viewer-container .tool-message {
|
||||
color:
|
||||
}
|
||||
|
|
@ -60,7 +60,8 @@
|
|||
<div style="height: 10px;"></div>
|
||||
<button class="btn rbtn act-addFillet" style="background-image: url(img/vec/fillet.svg);"></button>
|
||||
</div>
|
||||
<div style="background: black; overflow: hidden; height: 100%;">
|
||||
<div id="viewer-container" style="background: black; overflow: hidden; height: 100%; position: relative">
|
||||
<div class="tool-message" style="position: absolute; bottom: 5px; left: 5px;"></div>
|
||||
<canvas width="300" height="300" id="viewer"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -69,7 +70,8 @@
|
|||
<div class="button-group" style="float: left">
|
||||
<span id='showActions' class="dock-btn" ><i class="fa fa-slack"></i></span>
|
||||
</div>
|
||||
<div class="coordinates-info" style="float: right"></div>
|
||||
<div class="status-item coordinates-info">0.000:0.000</div>
|
||||
<div class="status-item tool-info"></div>
|
||||
</div>
|
||||
|
||||
<div id="actions" class="scroll win" style="display: none;">
|
||||
|
|
|
|||
Loading…
Reference in a new issue