2085 lines
92 KiB
JavaScript
2085 lines
92 KiB
JavaScript
// Scripting by Oleg Okhotnikov, contact - svoboda200786@gmail.com
|
||
let legend_back;
|
||
let active_obj;
|
||
let move_flag = false;
|
||
let drawing_object = false;
|
||
let deltaX = 0;
|
||
let deltaY = 0;
|
||
let borders;
|
||
let point;
|
||
let min_val = 0.95;
|
||
let shape_change_flag = false;
|
||
let katet_min_length = 10;
|
||
let stick_array = [];
|
||
var text_editing; // показывает, есть ли активный текстовый элемент внутри составного объекта,
|
||
// иначе клик по полю снимает активность текстового элемента
|
||
// "Составные" объекты состоят из нескольких примитивов и в отличие от групп позволяют
|
||
// перемещать подобъекты по отдельности, при этом сохраняя целостность фигуры
|
||
// Создаем составные объекты, линия (line), размерность (size), выноска (cap), розетка (socket) и т.д.:
|
||
let btn_stick = document.querySelector("#stick");
|
||
let arrow_middle_pointX = 16;
|
||
function add_line(e, obj, ispart=false, x1=old_arrow_X, y1=old_arrow_Y, x2=canvas.getPointer(e.e).x, y2=canvas.getPointer(e.e).y, flag=true, name="line", stroke = fieldcolor, line_type="line"){
|
||
var line,
|
||
arrow,
|
||
arrow2;
|
||
if(!ispart){ // не подобъект, как например, стрелки у розетки. У каждого составного объекта
|
||
// есть родительский подобъект, обычно линия,
|
||
// (object.parent), который записывается в массив всех фигур (shape)
|
||
index++;
|
||
|
||
if(obj != undefined){
|
||
for(let i in obj){
|
||
obj[i].groupName = /[a-zA-Z\_]+/.exec(obj[i].groupName) + index; // перезаписываем groupName, добавляя новый индекс
|
||
}
|
||
}
|
||
}
|
||
|
||
if(obj != undefined){ // значит мы записываем в объект line линию, которую вернул канвас в start.js
|
||
line = obj.line; // первый элемент составного объекта
|
||
line.index = index;
|
||
}
|
||
else{ // создаем новый объект line
|
||
line = drawArrowLine([x1, y1, x2, y2], stroke, index, name, calcLineLength({x1: x1, y1: y1, x2: x2, y2: y2}), line_type);
|
||
}
|
||
|
||
if(!ispart){ // если стрелка не часть составного объекта вроде socket, то
|
||
shape[index] = line; // делаем элемент line ключевым - при его (line) перемещении,
|
||
// все части составного объекта arrow двигаются за ним (то есть за line)
|
||
}
|
||
|
||
var centerX = (line.x1 + line.x2) / 2,
|
||
centerY = (line.y1 + line.y2) / 2;
|
||
deltaX = line.left - centerX,
|
||
deltaY = line.top - centerY;
|
||
if(obj != undefined){
|
||
arrow = obj.arrow;
|
||
arrow.index = index;
|
||
}
|
||
else{
|
||
switch(name){
|
||
case "line":
|
||
arrow = drawArrowCircle(line, deltaX, deltaY, flag, index, name, "arrow_start");
|
||
break;
|
||
case "arrow":
|
||
case "size":
|
||
arrow = drawArrowPoly(x2, y2, x1, y1, deltaX, deltaY, line, stroke, index, name, "arrow_start");
|
||
break;
|
||
case "socket":
|
||
arrow = drawArrowPoly(x1, y1, x2, y2, deltaX, deltaY, line, stroke, index, name, "arrow_start");
|
||
break;
|
||
}
|
||
}
|
||
if(!ispart){
|
||
if(obj != undefined){
|
||
arrow2 = obj.arrow2;
|
||
arrow2.index = index;
|
||
}
|
||
else{
|
||
switch(name){
|
||
case "line":
|
||
case "arrow":
|
||
arrow2 = drawArrowCircle(line, deltaX, deltaY, flag, index, name, "arrow_end");
|
||
break;
|
||
case "size":
|
||
arrow2 = drawArrowPoly(x1, y1, x2, y2, deltaX, deltaY, line, stroke, index, name, "arrow_end", -1);
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
arrow.line = line.line = line;
|
||
line.arrow = arrow.arrow = arrow;
|
||
// свойство parent обозначает родительский подобъект или, иначе говоря, объект,
|
||
// к которому привязаны остальные подобъекты составного объекта
|
||
line.parent = arrow.parent = line;
|
||
line.parent.objects = ['line', 'arrow', 'arrow2'];
|
||
|
||
if(!ispart){ // у линий внутри составных объектов нет стрелок
|
||
arrow2.line = arrow.line;
|
||
arrow2.arrow = arrow.arrow;
|
||
line.arrow2 = arrow.arrow2 = arrow2.arrow2 = arrow2;
|
||
arrow2.parent = arrow.parent;
|
||
arrow2.perPixelTargetFind = false;
|
||
|
||
if(name == "line"){
|
||
arrow.stroke_colorable = false;
|
||
}
|
||
arrow2.stroke_colorable = false;
|
||
}
|
||
|
||
arrow.perPixelTargetFind = false;
|
||
|
||
if(!window.add_geometry_flag && name != "socket"){
|
||
// stick(e, line.arrow2);
|
||
}
|
||
|
||
if(obj != undefined){
|
||
line.parent.added = true;
|
||
}
|
||
|
||
if(obj){
|
||
var groupType = /[a-zA-Z\_]+/.exec(obj.line.groupName);
|
||
|
||
let key = obj.line.groupName;
|
||
if(!stick_array[key]){
|
||
stick_array[key] = {};
|
||
if(obj.arrow2 && groupType != "geometry"){
|
||
// let param = text2Angle(obj.arrow.get('left'), obj.arrow.get('top'), obj.arrow2.get('left'), obj.arrow2.get('top'));
|
||
// stick_array[key].x0 = param.x;
|
||
// stick_array[key].y0 = param.y;
|
||
// stick_array[key].x1 = obj.arrow.get('left');
|
||
// stick_array[key].y1 = obj.arrow.get('top');
|
||
// stick_array[key].x2 = obj.arrow2.get('left');
|
||
// stick_array[key].y2 = obj.arrow2.get('top');
|
||
// console.log(groupType);
|
||
moveEnd({pointer: {x: obj.line.parent.arrow.left, y: obj.line.parent.arrow.top}}, obj.line.parent.arrow);
|
||
// moveEnd({pointer: {x: obj.line.parent.arrow2.left, y: obj.line.parent.arrow2.top}}, obj.line.parent.arrow2);
|
||
|
||
}
|
||
else{
|
||
if(groupType == "geometry"){
|
||
setTimeout(function(){ // свойство parent поменятеся, поэтоу вызываем таймаут
|
||
obj.parent = shape[obj.line.index];
|
||
|
||
let param = text2Angle(obj.line.get('x1'), obj.line.get('y1'), obj.line.get('x2'), obj.line.get('y2'));
|
||
x0 = stick_array[key].x0 = param.x;
|
||
y0 = stick_array[key].y0 = param.y;
|
||
|
||
x1 = stick_array[key].x1 = obj.line.get('x1');
|
||
y1 = stick_array[key].y1 = obj.line.get('y1');
|
||
x2 = stick_array[key].x2 = obj.line.get('x2');
|
||
y2 = stick_array[key].y2 = obj.line.get('y2');
|
||
x3 = stick_array[key].x3 = obj.parent.line_part1.get('x1');
|
||
y3 = stick_array[key].y3 = obj.parent.line_part1.get('y1');
|
||
x4 = stick_array[key].x4 = obj.parent.line_part2.get('x1');
|
||
y4 = stick_array[key].y4 = obj.parent.line_part2.get('y1');
|
||
param = text2Angle(obj.parent.line_part1.get('x1'), obj.parent.line_part1.get('y1'), obj.parent.line.get('x1'), obj.parent.line.get('y1'));
|
||
x5 = stick_array[key].x5 = param.x;
|
||
y5 = stick_array[key].y5 = param.y;
|
||
param = text2Angle(obj.parent.line_part2.get('x1'), obj.parent.line_part2.get('y1'), obj.parent.line.get('x2'), obj.parent.line.get('y2'));
|
||
x6 = stick_array[key].x6 = param.x;
|
||
y6 = stick_array[key].y6 = param.y;
|
||
|
||
// var t = canvas.viewportTransform;
|
||
|
||
// canvas.contextTop.fillRect(t[0]*x0+t[4], t[3]*y0+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x1+t[4], t[3]*y1+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x2+t[4], t[3]*y2+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x3+t[4], t[3]*y3+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x4+t[4], t[3]*y4+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x5+t[4], t[3]*y5+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x6+t[4], t[3]*y6+t[5], 10, 10)
|
||
|
||
}, 10);
|
||
}
|
||
else{
|
||
setTimeout(function(){
|
||
moveEnd({pointer: {x: obj.line.parent.arrow_part1.left, y: obj.line.parent.arrow_part1.top}}, obj.line.parent.arrow_part1);
|
||
moveEnd({pointer: {x: obj.line.parent.arrow_part2.left, y: obj.line.parent.arrow_part2.top}}, obj.line.parent.arrow_part2);
|
||
}, 10);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
line.on('mousedown', function (e) {
|
||
if(this.name != "line_part1" && this.name != "line_part2" || this.groupType == "geometry"){
|
||
if(this.groupType == "size"){
|
||
this.line.x1 = this.arrow.left;
|
||
this.line.y1 = this.arrow.top;
|
||
this.line.x2 = this.arrow2.left;
|
||
this.line.y2 = this.arrow2.top;
|
||
}
|
||
this.first_center = {
|
||
x: line.x1 + (line.x2 - line.x1) / 2,
|
||
y: line.y1 + (line.y2 - line.y1) / 2
|
||
};
|
||
this.first_click = {
|
||
x: canvas.getPointer(e.e).x,
|
||
y: canvas.getPointer(e.e).y
|
||
};
|
||
this.delta_between_arrow_and_click = {
|
||
x: this.parent.arrow.get("left") - canvas.getPointer(e.e).x,
|
||
y: this.parent.arrow.get("top") - canvas.getPointer(e.e).y
|
||
};
|
||
}
|
||
})
|
||
arrow.on('mousedown', function (e) {
|
||
shape_change_flag = true;
|
||
hideLens();
|
||
if(this.parent.line_part1 != undefined){
|
||
this.parent.line_part1.first_click = {
|
||
x: canvas.getPointer(e.e).x,
|
||
y: canvas.getPointer(e.e).y
|
||
};
|
||
}
|
||
})
|
||
if(arrow2 != undefined){
|
||
shape_change_flag = true;
|
||
arrow2.on('mousedown', function (e) {
|
||
hideLens();
|
||
shape_change_flag = true;
|
||
if(this.parent.line_part2 != undefined){
|
||
this.parent.line_part2.first_click = {
|
||
x: canvas.getPointer(e.e).x,
|
||
y: canvas.getPointer(e.e).y
|
||
};
|
||
}
|
||
})
|
||
}
|
||
|
||
if(obj === undefined){
|
||
if(!ispart){
|
||
canvas.add(line, arrow, arrow2);
|
||
canvas.setActiveObject(arrow);
|
||
}
|
||
}
|
||
canvas.bringToFront(arrow).renderAll();
|
||
line.on('mouseover', function () {
|
||
canvas.bringToFront(arrow).renderAll();
|
||
})
|
||
// canvasEvents();
|
||
setTimeout(function(){
|
||
arrow.setCoords();
|
||
if(arrow2){
|
||
arrow2.setCoords();
|
||
}
|
||
}, 10);
|
||
return {line: line, arrow: arrow, arrow2: arrow2};
|
||
}
|
||
|
||
function canvasEvents(){
|
||
canvas.on('mouse:down', function (e) {
|
||
let obj = canvas.getActiveObject();
|
||
|
||
if(obj && obj.parent && obj.parent.groupType == "geometry"){
|
||
|
||
obj.parent.line_part1.x1 = obj.parent.arrow_part1.get('left');
|
||
obj.parent.line_part1.y1 = obj.parent.arrow_part1.get('top');
|
||
obj.parent.line_part1.x2 = obj.parent.arrow.get('left');
|
||
obj.parent.line_part1.y2 = obj.parent.arrow.get('top');
|
||
|
||
obj.parent.line_part2.x1 = obj.parent.arrow_part2.get('left');
|
||
obj.parent.line_part2.y1 = obj.parent.arrow_part2.get('top');
|
||
obj.parent.line_part2.x2 = obj.parent.arrow2.get('left');
|
||
obj.parent.line_part2.y2 = obj.parent.arrow2.get('top');
|
||
|
||
obj.parent.line.x1 = obj.parent.arrow.get('left');
|
||
obj.parent.line.y1 = obj.parent.arrow.get('top');
|
||
obj.parent.line.x2 = obj.parent.arrow2.get('left');
|
||
obj.parent.line.y2 = obj.parent.arrow2.get('top');
|
||
|
||
obj.oldX = obj.parent.line_part1.x2
|
||
obj.oldY = obj.parent.line_part1.y2
|
||
}
|
||
})
|
||
|
||
canvas.on('mouse:move', function (e) {
|
||
let obj = canvas.getActiveObject();
|
||
|
||
if(obj && obj.parent){
|
||
if(obj != undefined && obj.type != "activeSelection" && obj.parent.name != "rect"){
|
||
if(obj.pointType == "arrow_start" || obj.pointType == "arrow_end"){
|
||
obj.parent.line.length = calcLineLength({x1: obj.parent.arrow.left, y1: obj.parent.arrow.top, x2: obj.parent.arrow2.left, y2: obj.parent.arrow2.top});
|
||
if (obj.name == "arrow_part1" || obj.name == "arrow_part2"){
|
||
obj.parent.line.length = calcLineLength({x1: obj.parent.arrow_part1.left, y1: obj.parent.arrow_part1.top, x2: obj.parent.arrow_part2.left, y2: obj.parent.arrow_part2.top});
|
||
}
|
||
}
|
||
if (obj.name == "line_part1" || obj.name == "line_part2"){
|
||
obj.parent.line.length = calcLineLength({x1: obj.parent.line_part1.left, y1: obj.parent.line_part1.top, x2: obj.parent.line_part2.left, y2: obj.parent.line_part2.top});
|
||
}
|
||
|
||
if(obj.parent.added && obj.parent.arrow){
|
||
if(obj.parent.groupType != "cap"){
|
||
line_min_length = obj.parent.arrow.width * obj.parent.arrow.scaleX;
|
||
}
|
||
else{
|
||
line_min_length = 10;
|
||
}
|
||
}
|
||
|
||
if(obj.parent.line != undefined){
|
||
if(obj.parent.line.length >= line_min_length || obj.parent.groupType == "geometry"){
|
||
if(obj.pointType == "arrow_start" && shape_change_flag){
|
||
moveEnd(e, obj);
|
||
}
|
||
if(obj.pointType == "arrow_end" && shape_change_flag){
|
||
moveEnd(e, obj);
|
||
}
|
||
if(obj.type == "line" && !obj.ispart && (geometry_obj || mouse_down_flag) ){
|
||
moveLine(e, obj);
|
||
window.geometry_selected = false;
|
||
}
|
||
}
|
||
else{
|
||
if(obj.pointType == "arrow_start"){
|
||
if (obj.name == "arrow_part1"){
|
||
obj.set({
|
||
left: obj.parent.line_part1.x1,
|
||
top: obj.parent.line_part1.y1,
|
||
})
|
||
}
|
||
else if (obj.name == "arrow_part2"){
|
||
obj.set({
|
||
left: obj.parent.line_part2.x1,
|
||
top: obj.parent.line_part2.y1,
|
||
})
|
||
}
|
||
else{
|
||
obj.set({
|
||
left: obj.parent.line.x1,
|
||
top: obj.parent.line.y1,
|
||
})
|
||
}
|
||
}
|
||
if(obj.pointType == "arrow_end"){
|
||
obj.set({
|
||
left: obj.parent.line.x2,
|
||
top: obj.parent.line.y2,
|
||
})
|
||
}
|
||
if(obj.type == "line"){
|
||
if(obj.name == "line_part1"){
|
||
obj.set({
|
||
x1: obj.parent.arrow_part1.left,
|
||
y1: obj.parent.arrow_part1.top,
|
||
x2: obj.parent.line.x1,
|
||
y2: obj.parent.line.y1
|
||
})
|
||
}
|
||
if(obj.name == "line_part2"){
|
||
obj.set({
|
||
x1: obj.parent.arrow_part2.left,
|
||
y1: obj.parent.arrow_part2.top,
|
||
x2: obj.parent.line.x2,
|
||
y2: obj.parent.line.y2
|
||
})
|
||
}
|
||
}
|
||
// canvas.renderAll();
|
||
}
|
||
}
|
||
|
||
}
|
||
else if(obj != undefined && obj.parent != undefined && obj.parent.name == "rect" && shape_change_flag){
|
||
if (obj.name == "arrow_part1"){
|
||
obj.parent.line_part1.length = calcLineLength({x1: obj.parent.arrow_part1.left, y1: obj.parent.arrow_part1.top, x2: obj.parent.line_part1.x2, y2: obj.parent.line_part1.y2});
|
||
}
|
||
if (obj.name == "arrow_part2"){
|
||
obj.parent.line_part2.length = calcLineLength({x1: obj.parent.arrow_part2.left, y1: obj.parent.arrow_part2.top, x2: obj.parent.line_part2.x2, y2: obj.parent.line_part2.y2});
|
||
}
|
||
if(obj.pointType == "arrow_start"){
|
||
moveEnd(e, obj);
|
||
}
|
||
// if(obj.pointType == "arrow_end"){
|
||
// moveEnd(e, obj);
|
||
// }
|
||
}
|
||
}
|
||
})
|
||
}
|
||
|
||
function drawArrowLine(array, stroke, index, name, length, line_type){
|
||
let line = new fabric.Line(array, {
|
||
stroke: stroke,
|
||
selectable: true,
|
||
hasBorders: false,
|
||
hasControls: false,
|
||
fill: 'rgba(0,0,0,0)',
|
||
originX: 'center',
|
||
originY: 'center',
|
||
lockScalingX: true,
|
||
lockScalingY: true,
|
||
perPixelTargetFind: true,
|
||
length: length,
|
||
name: 'line',
|
||
groupName: name+index,
|
||
index: index
|
||
});
|
||
if(line_type == "geometry_line_part1" || line_type == "geometry_line_part2"){
|
||
setTimeout(function(){
|
||
line.strokeWidth = selectStrokeWidth("geometry", line_type);
|
||
}, 10);
|
||
}
|
||
else{
|
||
line.strokeWidth = selectStrokeWidth(name, line_type);
|
||
}
|
||
return line;
|
||
}
|
||
function drawArrowPoly(x1, y1, x2, y2, deltaX, deltaY, line, stroke, index, name, pointType, direction = 1){
|
||
if(direction == 1){
|
||
var arrow = new fabric.Path('M 0,2.5 13,-6.31861e-7 9.19811,2.5 13,5 Z');
|
||
}
|
||
else{
|
||
var arrow = new fabric.Path('M 13,2.5 0,-6.31861e-7 3.80189,2.5 0,5 Z');
|
||
}
|
||
arrow.set({
|
||
left: x1 + deltaX,
|
||
top: y1 + deltaY,
|
||
angle: calcArrowAngle(x1, y1, x2, y2),
|
||
originX: 'left', // стрелка изначально имеет горизонтальную ориентацию, поэтому острие слева посередине
|
||
originY: 'center',
|
||
hasBorders: false,
|
||
hasControls: false,
|
||
lockScalingX: true,
|
||
lockScalingY: true,
|
||
centeredRotation: true,
|
||
centeredScaling: true,
|
||
centeredScaling: true,
|
||
fill: fieldcolor,
|
||
strokeUniform: true,
|
||
stroke: stroke,
|
||
strokeWidth: 0,
|
||
pointType: pointType,
|
||
name: 'arrow',
|
||
groupName: name + index,
|
||
index: index
|
||
});
|
||
scaleArrow(arrow);
|
||
if(pointType == "arrow_end"){
|
||
arrow.set({
|
||
name: 'arrow2',
|
||
originX: 'right',
|
||
angle: calcArrowAngle(x2, y2, x1, y1),
|
||
});
|
||
}
|
||
return arrow;
|
||
}
|
||
function drawArrowCircle(line, deltaX, deltaY, flag, index, name, pointType){
|
||
let arrow = new fabric.Circle({
|
||
left: line.get('x1'),
|
||
top: line.get('y1'),
|
||
radius: 5,
|
||
stroke: 'rgba(0, 0, 0, 0)',
|
||
strokeWidth: 1,
|
||
selectable: flag,
|
||
originX: 'center',
|
||
originY: 'center',
|
||
hasBorders: false,
|
||
hasControls: false,
|
||
lockScalingX: true,
|
||
lockScalingY: true,
|
||
lockRotation: true,
|
||
pointType: pointType,
|
||
fill: 'rgba(0, 0, 0, 0)',
|
||
perPixelTargetFind: true,
|
||
name: 'arrow',
|
||
groupName: name + index,
|
||
index: index
|
||
})
|
||
if(pointType == "arrow_end"){
|
||
arrow.name = "arrow2";
|
||
}
|
||
return arrow;
|
||
}
|
||
function drawArrowText(text, left, top, angle, originX, originY, index, name, groupName, flag){
|
||
let text2 = new fabric.IText(text, {
|
||
fontSize: text_dimension[zoom_size],
|
||
// fontWeight: 100 + 100 * stroke_width,
|
||
originX: originX,
|
||
originY: originY,
|
||
fontFamily: "Golos Text",
|
||
fill: "black",
|
||
backgroundColor: 'rgba(0,0,0,0)',
|
||
hasBorders: false,
|
||
hasControls: false,
|
||
lockScalingX: true,
|
||
lockScalingY: true,
|
||
lockRotation: true,
|
||
lockMovementX: flag,
|
||
lockMovementY: flag,
|
||
left: left,
|
||
top: top,
|
||
angle: angle,
|
||
fill: fieldcolor,
|
||
textAlign: 'center',
|
||
name: name,
|
||
groupName: groupName+index,
|
||
index: index
|
||
})
|
||
return text2;
|
||
}
|
||
function drawSocketRect(x, y, index, name){
|
||
var rect = new fabric.Path("M 0 0 L 0 18.484375 L 18.160156 18.484375 L 18.160156 0 L 0 0 z M 9.0800781 2.4316406 A 6.8098435 6.8098435 0 0 1 15.888672 9.2421875 A 6.8098435 6.8098435 0 0 1 9.0800781 16.052734 A 6.8098435 6.8098435 0 0 1 2.2695312 9.2421875 A 6.8098435 6.8098435 0 0 1 9.0800781 2.4316406 z ");
|
||
rect.set({
|
||
left: x,
|
||
top: y,
|
||
originX: 'center',
|
||
originY: 'center',
|
||
hasBorders: false,
|
||
hasControls: false,
|
||
lockScalingX: true,
|
||
lockScalingY: true,
|
||
centeredRotation: true,
|
||
centeredScaling: true,
|
||
centeredScaling: true,
|
||
fill: fieldcolor,
|
||
strokeUniform: true,
|
||
strokeWidth: 0,
|
||
name: "rect_back",
|
||
groupName: name + index,
|
||
index: index
|
||
});
|
||
return rect;
|
||
}
|
||
function add_arrow(e, obj, ispart=false, x1=old_arrow_X, y1=old_arrow_Y, x2=canvas.getPointer(e.e).x, y2=canvas.getPointer(e.e).y, flag=true, name="arrow", stroke = fieldcolor){
|
||
return add_line(e, obj, ispart, x1, y1, x2, y2, flag, name, stroke);
|
||
}
|
||
|
||
//////////////////////////// Size //////////////////////////////
|
||
|
||
function add_size(e, obj, ispart=false, x1=old_arrow_X, y1=old_arrow_Y, x2=canvas.getPointer(e.e).x, y2=canvas.getPointer(e.e).y, flag=true, name="size", stroke = fieldcolor){
|
||
let temp = add_line(e, obj, ispart, x1, y1, x2, y2, flag, name, stroke);
|
||
let line = temp.line;
|
||
let arrow = temp.arrow;
|
||
let arrow2 = temp.arrow2;
|
||
|
||
if(obj != undefined){
|
||
text2 = obj.text2;
|
||
text2.index = index;
|
||
}
|
||
else{
|
||
let left = text2Angle(line.x1, line.y1, line.x2, line.y2).x - 20;
|
||
let top = text2Angle(line.x1, line.y1, line.x2, line.y2).y;
|
||
let angle = text2Angle(line.x1, line.y1, line.x2, line.y2).ang;
|
||
text2 = drawArrowText("000", left, top, angle, 'left', 'bottom', index, "text2", name, true);
|
||
}
|
||
line.text2 = arrow.text2 = text2.text2 = text2;
|
||
line.text2.selectable = false;
|
||
// свойство parent обозначает родительский подобъект или, иначе говоря, объект,
|
||
// к которому привязаны остальные подобъекты составного объекта
|
||
line.parent = arrow.parent = text2.parent = line;
|
||
if(!ispart){
|
||
arrow2.text2 = arrow.text2;
|
||
arrow2.parent = arrow.parent;
|
||
}
|
||
if(obj != undefined){
|
||
setTimeout(function(){
|
||
changeTextWidth(text2);
|
||
}, 100);
|
||
text2.on('changed', function () {
|
||
changeTextWidth(text2);
|
||
});
|
||
}
|
||
text2.on('changed', function () {
|
||
if(this.width <= 2){
|
||
this.width = 33;
|
||
}
|
||
if(this.name == "text2_part1"){
|
||
var parent = this.parent.line_part1;
|
||
}
|
||
if(this.name == "text2_part2"){
|
||
var parent = this.parent.line_part2;
|
||
}
|
||
if(this.name == "text2"){
|
||
var parent = this.parent.line;
|
||
}
|
||
|
||
// центрирование текста
|
||
textRotate(parent);
|
||
this.setCoords();
|
||
});
|
||
text2.on('editing:entered', function () {
|
||
text_editing = true;
|
||
})
|
||
text2.on('editing:exited', function () {
|
||
if(!editor_command){
|
||
element_cursor(true);
|
||
}
|
||
mouse_down_flag = false;
|
||
this.initialized = true;
|
||
if(this.name == "text2_part1"){
|
||
if(!this.parent.line_part2.text2.initialized){
|
||
this.parent.line_part2.text2.enterEditing();
|
||
this.parent.line_part2.text2.hiddenTextarea.focus();
|
||
this.parent.line_part2.text2.selectLine(1);
|
||
let text_obj = this.parent.line_part2.text2;
|
||
text_editing = true;
|
||
setTimeout(function(){canvas.setActiveObject(text_obj);}, 10);
|
||
}
|
||
else{
|
||
text_editing = false;
|
||
}
|
||
}
|
||
if(this.name == "text2_part2"){
|
||
if(!this.parent.line_part1.text2.initialized){
|
||
this.parent.line_part1.text2.enterEditing();
|
||
this.parent.line_part1.text2.hiddenTextarea.focus();
|
||
this.parent.line_part1.text2.selectLine(1);
|
||
let text_obj = this.parent.line_part1.text2;
|
||
text_editing = true;
|
||
setTimeout(function(){canvas.setActiveObject(text_obj);}, 10);
|
||
}
|
||
else{
|
||
text_editing = false;
|
||
}
|
||
}
|
||
if(this.name == "text2"){
|
||
text_editing = false;
|
||
}
|
||
});
|
||
text2.on('mousedown:before', function (e) {
|
||
this.first_click = {
|
||
x: canvas.getPointer(e.e).x,
|
||
y: canvas.getPointer(e.e).y
|
||
};
|
||
mouse_down_flag = true;
|
||
});
|
||
text2.on('mouseup', function (e) {
|
||
mouse_down_flag = false;
|
||
canvas.setActiveObject(this);
|
||
if(!this.was_moved){
|
||
this.enterEditing();
|
||
}
|
||
this.was_moved = false;
|
||
canvas.defaultCursor = null;
|
||
canvas.defaultCursor_old = null;
|
||
});
|
||
text2.on('mousemove', function (e) {
|
||
if(mouse_down_flag){
|
||
this.exitEditing();
|
||
this.was_moved = true;
|
||
}
|
||
if(!this.isEditing){
|
||
if(this.parent.arrow != undefined){
|
||
var turn_angle = this.parent.arrow.angle;
|
||
}
|
||
else if(this == this.parent.text2){
|
||
var turn_angle = this.parent.arrow_part2.angle;
|
||
}
|
||
else{
|
||
var turn_angle = this.parent.arrow_part1.angle;
|
||
}
|
||
if((turn_angle >= 90 && turn_angle <= 135) || (turn_angle >= -90 && turn_angle <= -45))
|
||
{
|
||
if(mouse_down_flag && this.first_click != undefined && canvas.getPointer(e.e).x > this.first_click.x){
|
||
this.set('originY', 'top');
|
||
}
|
||
if(mouse_down_flag && this.first_click != undefined && canvas.getPointer(e.e).x < this.first_click.x){
|
||
this.set('originY', 'bottom');
|
||
}
|
||
}
|
||
else if((turn_angle >= 45 && turn_angle <= 90) || turn_angle == 270 || (turn_angle >= -135 && turn_angle <= -90))
|
||
{
|
||
if(mouse_down_flag && this.first_click != undefined && canvas.getPointer(e.e).x > this.first_click.x){
|
||
this.set('originY', 'bottom');
|
||
}
|
||
if(mouse_down_flag && this.first_click != undefined && canvas.getPointer(e.e).x < this.first_click.x){
|
||
this.set('originY', 'top');
|
||
}
|
||
}
|
||
else if(Math.ceil(turn_angle) == 0){
|
||
if(mouse_down_flag && this.first_click != undefined && canvas.getPointer(e.e).y > this.first_click.y){
|
||
this.set('originY', 'bottom');
|
||
}
|
||
if(mouse_down_flag && this.first_click != undefined && canvas.getPointer(e.e).y < this.first_click.y){
|
||
this.set('originY', 'top');
|
||
}
|
||
}
|
||
else{
|
||
if(mouse_down_flag && this.first_click != undefined && canvas.getPointer(e.e).y > this.first_click.y){
|
||
this.set('originY', 'top');
|
||
}
|
||
if(mouse_down_flag && this.first_click != undefined && canvas.getPointer(e.e).y < this.first_click.y){
|
||
this.set('originY', 'bottom');
|
||
}
|
||
}
|
||
canvas.renderAll();
|
||
}
|
||
})
|
||
if(obj === undefined && !ispart){
|
||
canvas.add(text2);
|
||
canvas.setActiveObject(arrow);
|
||
}
|
||
line.parent.objects.push("text2");
|
||
line.setCoords();
|
||
arrow.setCoords();
|
||
if(!ispart){
|
||
arrow2.setCoords();
|
||
return {line: line, arrow: arrow, arrow2: arrow2, text2: text2};
|
||
}
|
||
else{
|
||
return {line: line, arrow: arrow, text2: text2};
|
||
}
|
||
}
|
||
|
||
//////////////////////////// Geometry //////////////////////////////
|
||
|
||
function add_geometry(e, obj, ispart=false, x1=old_arrow_X, y1=old_arrow_Y, x2=canvas.getPointer(e.e).x, y2=canvas.getPointer(e.e).y, flag=true, name="size", stroke = fieldcolor){
|
||
window.add_geometry_flag = true;
|
||
let line_main, line_part1, line_part2;
|
||
|
||
if(obj != undefined){ // значит мы создаем составной объект при загрузке документа из сохраненного файла
|
||
obj1 = {
|
||
line: obj.line,
|
||
arrow: obj.arrow,
|
||
arrow2: obj.arrow2,
|
||
text2: obj.text2
|
||
};
|
||
line_main = editor_obj.add_size(e, obj1, false);
|
||
obj2 = {
|
||
line: obj.line_part1,
|
||
arrow: obj.arrow_part1
|
||
};
|
||
line_part1 = editor_obj.add_line(e, obj2, true);
|
||
|
||
obj3 = {
|
||
line: obj.line_part2,
|
||
arrow: obj.arrow_part2
|
||
};
|
||
line_part2 = editor_obj.add_line(e, obj3, true);
|
||
|
||
// Меняем координаты на глобальные
|
||
line_main.line.x1 = line_main.line.left + line_main.line.x1;
|
||
line_main.line.y1 = line_main.line.top + line_main.line.y1;
|
||
line_main.line.x2 = line_main.line.left + line_main.line.x2;
|
||
line_main.line.y2 = line_main.line.top+ line_main.line.y2;
|
||
|
||
line_part1.line.x1 = line_part1.line.left + line_part1.line.x1;
|
||
line_part1.line.y1 = line_part1.line.top + line_part1.line.y1;
|
||
line_part1.line.x2 = line_part1.line.left + line_part1.line.x2;
|
||
line_part1.line.y2 = line_part1.line.top+ line_part1.line.y2;
|
||
|
||
line_part2.line.x1 = line_part2.line.left + line_part2.line.x1;
|
||
line_part2.line.y1 = line_part2.line.top + line_part2.line.y1;
|
||
line_part2.line.x2 = line_part2.line.left + line_part2.line.x2;
|
||
line_part2.line.y2 = line_part2.line.top+ line_part2.line.y2;
|
||
|
||
line_main.line.setCoords();
|
||
line_part1.line.setCoords();
|
||
line_part2.line.setCoords();
|
||
}
|
||
else{
|
||
line_main = editor_obj.add_size(e, undefined, false, x1, y1, x2, y2, false, "size");
|
||
line_part1 = editor_obj.add_line(e, obj, true, line_main.arrow.left, line_main.arrow.top, line_main.arrow.left, line_main.arrow.top, flag, "line", fieldcolor, "geometry_line_part1");
|
||
line_part2 = editor_obj.add_line(e, obj, true, line_main.arrow2.left, line_main.arrow2.top, line_main.arrow2.left, line_main.arrow2.top, flag, "line", fieldcolor, "geometry_line_part2");
|
||
}
|
||
|
||
// var rect = editor_obj.add_rect(null, true, canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, 18, 18, "rgba(0, 0, 0, 0)", fieldcolor, "socket", true);
|
||
|
||
line_main.line.objects = ["arrow_part1", "line_part1", "arrow_part2", "line_part2", "line", "arrow", "arrow2", "text2"];
|
||
|
||
line_part1.ispart = true;
|
||
line_part2.ispart = true;
|
||
|
||
line_main.line.line_part1 = line_part1.line;
|
||
line_main.line.line_part2 = line_part2.line;
|
||
line_main.line.arrow_part1 = line_part1.arrow;
|
||
line_main.line.arrow_part2 = line_part2.arrow;
|
||
line_main.line.arrow_part1.scale(0); // в текущей реализации верхушки боковых линий объекта не используются
|
||
line_main.line.arrow_part2.scale(0); // в текущей реализации верхушки боковых линий объекта не используются
|
||
|
||
// свойство parent обозначает родительский подобъект или, иначе говоря, объект,
|
||
// к которому привязаны остальные подобъекты составного объекта
|
||
line_main.line.parent = line_main.arrow.parent = line_main.text2.parent = line_main.line.line_part1.parent = line_main.line.line_part2.parent = line_main.line.arrow_part1.parent =
|
||
line_main.line.line_part1.parent = line_main.line.arrow_part2.parent = line_main.line.line_part2.parent = line_main.line;
|
||
|
||
line_main.line.parent.groupType = "geometry";
|
||
|
||
if(obj != undefined){
|
||
line_main.line.parent.added = true;
|
||
}
|
||
|
||
line_main.line.line_part1.name = "line_part1";
|
||
line_main.line.arrow_part1.name = "arrow_part1";
|
||
line_main.line.line_part2.name = "line_part2";
|
||
line_main.line.arrow_part2.name = "arrow_part2";
|
||
|
||
for (i of line_main.line.parent.objects){
|
||
line_main.line.parent[i].groupName = "geometry" + index;
|
||
}
|
||
|
||
shape[index] = line_main.line.line;
|
||
if(obj == undefined){
|
||
canvas.add(line_part1.line, line_part2.line);
|
||
}
|
||
// line_main.rect = rect;
|
||
// window.rect2 = rect;
|
||
// canvas.add(line_main.rect);
|
||
// console.log(line_main.rect);
|
||
|
||
line_main.line.line_part1.lockMovementX = true;
|
||
line_main.line.line_part1.lockMovementY = true;
|
||
line_main.line.line_part2.lockMovementX = true;
|
||
line_main.line.line_part2.lockMovementY = true;
|
||
|
||
line_part1.line.strokeWidth = 1;
|
||
line_part2.line.strokeWidth = 1;
|
||
|
||
line_main.line.arrow_part1.on('mousedown', function (e) {
|
||
this.parent.line_part1.first_click = {
|
||
x: canvas.getPointer(e.e).x,
|
||
y: canvas.getPointer(e.e).y
|
||
};
|
||
})
|
||
line_main.line.arrow_part2.on('mousedown', function (e) {
|
||
this.parent.line_part2.first_click = {
|
||
x: canvas.getPointer(e.e).x,
|
||
y: canvas.getPointer(e.e).y
|
||
};
|
||
})
|
||
window.add_geometry_flag = false;
|
||
}
|
||
|
||
//////////////////////////// Caption //////////////////////////
|
||
|
||
function add_cap(e, obj, x1=old_arrow_X, y1=old_arrow_Y, x2=canvas.getPointer(e.e).x, y2=canvas.getPointer(e.e).y, stroke = fieldcolor, name="cap"){
|
||
index++;
|
||
if(obj != undefined){
|
||
for(let i in obj){
|
||
obj[i].groupName = /[a-zA-Z\_]+/.exec(obj[i].groupName) + index; // перезаписываем groupName, добавляя новый индекс
|
||
}
|
||
}
|
||
var line,
|
||
arrow,
|
||
arrow2;
|
||
|
||
if(obj != undefined){
|
||
line = obj.line;
|
||
line.index = index;
|
||
}
|
||
else{
|
||
line = drawArrowLine([x2, y2, x1, y1], stroke, index, name, calcLineLength({x1: x1, y1: y1, x2: x2, y2: y2}));
|
||
}
|
||
line.objects = ['line', 'arrow', 'arrow2'];
|
||
shape[index] = line;
|
||
var centerX = (line.x1 + line.x2) / 2,
|
||
centerY = (line.y1 + line.y2) / 2;
|
||
deltaX = line.left - centerX,
|
||
deltaY = line.top - centerY;
|
||
|
||
if(obj != undefined){
|
||
arrow = obj.arrow;
|
||
arrow.index = index;
|
||
}
|
||
else{
|
||
arrow = drawArrowText("000", line.x2, line.y2, 0, 'right', 'bottom', index, "arrow", name, false);
|
||
}
|
||
|
||
if(obj != undefined){
|
||
setTimeout(function(){
|
||
changeTextWidth(arrow);
|
||
}, 100);
|
||
arrow.on('changed', function () {
|
||
changeTextWidth(arrow);
|
||
});
|
||
}
|
||
|
||
arrow.pointType = 'arrow_start';
|
||
arrow.line = line;
|
||
// arrow.line.strokeLineCap = 'round';
|
||
|
||
if(obj != undefined){
|
||
arrow2 = obj.arrow2;
|
||
arrow2.index = index;
|
||
}
|
||
else{
|
||
var diameter = line.strokeWidth * 3 + 1;
|
||
|
||
arrow2 = new fabric.Circle({
|
||
left: line.get('x2') + deltaX,
|
||
top: line.get('y2') + deltaY,
|
||
radius: diameter / 2,
|
||
stroke: stroke,
|
||
strokeWidth: line.strokeWidth,
|
||
originX: 'center',
|
||
originY: 'center',
|
||
hasBorders: true,
|
||
hasControls: false,
|
||
lockScalingX: true,
|
||
lockScalingY: true,
|
||
lockRotation: true,
|
||
pointType: 'arrow_end',
|
||
fill: 'rgba(255, 255, 255, 0)',
|
||
perPixelTargetFind: true,
|
||
name: "arrow2",
|
||
groupName: name + index,
|
||
index: index
|
||
});
|
||
}
|
||
arrow2.line = line;
|
||
arrow2.hasBorders = false;
|
||
arrow2.colorable = false;
|
||
|
||
line.line = arrow.line = arrow2.line = line;
|
||
line.arrow = arrow.arrow = arrow2.arrow = arrow;
|
||
line.arrow2 = arrow.arrow2 = arrow2.arrow2 = arrow2;
|
||
line.text2 = arrow.text2 = arrow2.text2 = arrow;
|
||
// свойство parent обозначает родительский подобъект или, иначе говоря, объект,
|
||
// к которому привязаны остальные подобъекты составного объекта
|
||
line.parent = arrow2.parent = arrow.parent = line;
|
||
|
||
stick(e, arrow2);
|
||
|
||
if(obj != undefined){
|
||
line.parent.added = true;
|
||
moveEnd({pointer: {x: obj.line.parent.arrow.left, y: obj.line.parent.arrow.top}}, obj.line.parent.arrow);
|
||
}
|
||
|
||
if(obj == undefined){
|
||
canvas.add(line, arrow, arrow2);
|
||
canvas.setActiveObject(arrow);
|
||
}
|
||
shape_change_flag = true;
|
||
arrow.on('mousedown', function (e) {
|
||
shape_change_flag = true;
|
||
hideLens()
|
||
})
|
||
arrow2.on('mousedown', function () {
|
||
shape_change_flag = true;
|
||
hideLens()
|
||
});
|
||
line.on('moving', function (e) {
|
||
moveLine(e, line);
|
||
});
|
||
}
|
||
//////////////////////////// Socket ////////////////////////////
|
||
function add_socket(e, obj){
|
||
// circle, small_circle1, small_circle2,
|
||
let rect, rect_back, line_part1, line_part2;
|
||
|
||
index++;
|
||
if(obj != undefined){
|
||
for(let i in obj){
|
||
obj[i].groupName = /[a-zA-Z\_]+/.exec(obj[i].groupName) + index; // перезаписываем groupName, добавляя новый индекс
|
||
}
|
||
}
|
||
if(obj != undefined){ // значит мы создаем составной объект при загрузке документа из сохраненного файла
|
||
obj1 = {
|
||
line: obj.line_part1,
|
||
arrow: obj.arrow_part1,
|
||
text2: obj.text2_part1
|
||
};
|
||
line_part1 = editor_obj.add_size(e, obj1, true);
|
||
obj2 = {
|
||
line: obj.line_part2,
|
||
arrow: obj.arrow_part2,
|
||
text2: obj.text2_part2
|
||
};
|
||
line_part2 = editor_obj.add_size(e, obj2, true);
|
||
rect_back = obj.rect_back;
|
||
// circle = obj.circle;
|
||
// small_circle1 = obj.small_circle1;
|
||
// small_circle2 = obj.small_circle2;
|
||
rect = obj.rect;
|
||
}
|
||
else{
|
||
line_part1 = editor_obj.add_size(null, undefined, true, canvas.getPointer(e.e).x, canvas.getPointer(e.e).y+100, canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, false, "socket");
|
||
line_part2 = editor_obj.add_size(null, undefined, true, canvas.getPointer(e.e).x+100, canvas.getPointer(e.e).y, canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, false, "socket");
|
||
// rect_back = editor_obj.add_rect(null, false, canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, 18, 18, fieldcolor, fieldcolor, "socket", true);
|
||
rect_back = drawSocketRect(canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, index, "socket");
|
||
// circle = editor_obj.add_circle(null, true, canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, 8, "rgba(255, 255, 255)", fieldcolor, "socket", true);
|
||
// small_circle1 = editor_obj.add_circle(null, true, canvas.getPointer(e.e).x - 4, canvas.getPointer(e.e).y, 1, fieldcolor, fieldcolor, "socket", true);
|
||
// small_circle2 = editor_obj.add_circle(null, true, canvas.getPointer(e.e).x + 4, canvas.getPointer(e.e).y, 1, fieldcolor, fieldcolor, "socket", true);
|
||
rect = editor_obj.add_rect(null, true, canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, 18, 18, "rgba(0, 0, 0, 0)", fieldcolor, "socket", true);
|
||
}
|
||
|
||
// circle.strokeWidth = 1;
|
||
// small_circle1.strokeWidth = 1;
|
||
// small_circle2.strokeWidth = 1;
|
||
rect.strokeWidth = 1;
|
||
rect.index = index;
|
||
rect.groupName = "socket" + index;
|
||
rect.groupType = "socket";
|
||
|
||
rect.lockScalingX = true;
|
||
rect.lockScalingY = true;
|
||
rect.hasControls = false;
|
||
// "circle", "small_circle1", "small_circle2",
|
||
rect.objects = ["rect_back", "arrow_part1", "text2_part1", "line_part1", "arrow_part2", "text2_part2", "line_part2", "rect"];
|
||
|
||
rect.perPixelTargetFind = false;
|
||
rect_back.ispart = true;
|
||
// circle.ispart = true;
|
||
// small_circle1.ispart = true;
|
||
// small_circle2.ispart = true;
|
||
line_part1.line.ispart = true;
|
||
line_part2.line.ispart = true;
|
||
line_part1.arrow.ispart = true;
|
||
line_part2.arrow.ispart = true;
|
||
line_part1.text2.ispart = true;
|
||
line_part2.text2.ispart = true;
|
||
|
||
rect_back.colorable = true;
|
||
// small_circle1.colorable = true;
|
||
// small_circle2.colorable = true;
|
||
rect.colorable = false;
|
||
|
||
rect.rect = rect;
|
||
rect.rect_back = rect_back;
|
||
rect.line_part1 = line_part1;
|
||
rect.line_part2 = line_part2;
|
||
rect.arrow_part1 = line_part1.arrow;
|
||
rect.text2_part1 = line_part1.text2;
|
||
rect.line_part1 = line_part1.line;
|
||
rect.arrow_part2 = line_part2.arrow;
|
||
rect.text2_part2 = line_part2.text2;
|
||
rect.text2 = rect.text2_part2;
|
||
rect.line_part2 = line_part2.line;
|
||
// rect.circle = circle;
|
||
// rect.small_circle1 = small_circle1;
|
||
// rect.small_circle2 = small_circle2;
|
||
|
||
rect.arrow_part1.canvas = canvas; // для правильного расчета координат в getViewportTransform fabric.js
|
||
rect.arrow_part2.canvas = canvas; // для правильного расчета координат в getViewportTransform fabric.js
|
||
|
||
// свойство parent обозначает родительский подобъект или, иначе говоря, объект,
|
||
// к которому привязаны остальные подобъекты составного объекта
|
||
|
||
// = rect.circle.parent = rect.small_circle1.parent = rect.small_circle2.parent
|
||
rect.rect.parent = rect.rect_back.parent = rect.line_part1.parent = rect.line_part2.parent = rect.arrow_part1.parent =
|
||
rect.line_part1.parent = rect.text2_part1.parent = rect.arrow_part2.parent = rect.text2_part2.parent = rect.line_part2.parent = rect;
|
||
if(obj != undefined){
|
||
rect.parent.added = true;
|
||
}
|
||
rect.rect.name = "rect";
|
||
// rect.rect_back.name = "rect_back";
|
||
// rect.circle.name = "circle";
|
||
// rect.small_circle1.name = "small_circle1";
|
||
// rect.small_circle2.name = "small_circle2";
|
||
rect.line_part1.name = "line_part1";
|
||
rect.arrow_part1.name = "arrow_part1";
|
||
rect.text2_part1.name = "text2_part1";
|
||
rect.line_part2.name = "line_part2";
|
||
rect.arrow_part2.name = "arrow_part2";
|
||
rect.text2_part2.name = "text2_part2";
|
||
|
||
for(var i of rect.objects){
|
||
rect[i].hasBorders = false;
|
||
rect[i].hasControls = false;
|
||
}
|
||
|
||
rect.line_part1.selectable = false;
|
||
rect.line_part2.selectable = false;
|
||
rect.text2_part1.selectable = false;
|
||
rect.text2_part2.selectable = false;
|
||
|
||
shape[index] = rect.rect;
|
||
|
||
if(obj == undefined){
|
||
canvas.setActiveObject(shape[index]);
|
||
moveEnd(e, line_part1.arrow);
|
||
moveEnd(e, line_part2.arrow);
|
||
canvas.add(line_part1.text2, line_part1.line, line_part2.text2, line_part2.line, rect.rect_back, rect);
|
||
}
|
||
|
||
// canvas.bringToFront(circle).renderAll();
|
||
// canvas.bringToFront(small_circle1).renderAll();
|
||
// canvas.bringToFront(small_circle2).renderAll();
|
||
canvas.bringToFront(rect).renderAll();
|
||
|
||
if(obj == undefined){
|
||
scaleSocket(shape[index]);
|
||
}
|
||
|
||
rect.on('moving', function () {
|
||
let deltaX = rect.left - rect.oldX;
|
||
let deltaY = rect.top - rect.oldY;
|
||
rect.oldX = rect.left;
|
||
rect.oldY = rect.top;
|
||
rect_back.left += deltaX;
|
||
rect_back.top += deltaY;
|
||
// circle.left += deltaX;
|
||
// circle.top += deltaY;
|
||
// small_circle1.left += deltaX;
|
||
// small_circle2.left += deltaX;
|
||
// small_circle1.top += deltaY;
|
||
// small_circle2.top += deltaY;
|
||
line_part1.line.left += deltaX;
|
||
line_part1.line.top += deltaY;
|
||
line_part2.line.left += deltaX;
|
||
line_part2.line.top += deltaY;
|
||
moveLine(e, line_part1.line);
|
||
moveLine(e, line_part2.line);
|
||
})
|
||
rect.on('mousedown', function () {
|
||
rect.oldX = rect.left;
|
||
rect.oldY = rect.top;
|
||
})
|
||
rect.line_part1.on('mouseover', function () {
|
||
this.hoverCursor = "no-drop";
|
||
})
|
||
rect.line_part2.on('mouseover', function () {
|
||
this.hoverCursor = "no-drop";
|
||
})
|
||
// эти три обработчика нужны для копирования, потому что круги копируются поверх квадрата
|
||
// circle.on('mousedown:before', function () {
|
||
// canvas.bringToFront(this.parent.rect).renderAll();
|
||
// })
|
||
// small_circle1.on('mousedown:before', function () {
|
||
// canvas.bringToFront(this.parent.rect).renderAll();
|
||
// })
|
||
// small_circle2.on('mousedown:before', function () {
|
||
// canvas.bringToFront(this.parent.rect).renderAll();
|
||
// })
|
||
}
|
||
//////////////////////////// Legend ////////////////////////////
|
||
function add_legend_back(obj){
|
||
let rect;
|
||
if(obj != undefined){
|
||
rect = obj;
|
||
}
|
||
else{
|
||
rect = editor_obj.add_rect(null, false, canvas.width - 210, canvas.height - 160, 200, 150, "#eee", "gray", "back", true);
|
||
canvas.add(rect);
|
||
rect.rx = 10;
|
||
rect.ry = 10;
|
||
}
|
||
rect.originX = 'left';
|
||
rect.originY = 'top';
|
||
rect.oldX = rect.left;
|
||
rect.oldY = rect.top;
|
||
rect.selectable = false;
|
||
rect.hasControls = true;
|
||
rect.lockRotation = true;
|
||
rect.parent = rect;
|
||
|
||
canvas.on('mouse:down', reCalculate);
|
||
rect.on('moving', reCalculate);
|
||
rect.on('scaling', reCalculate);
|
||
function reCalculate(e) {
|
||
// не даем уменьшить легенду, если ее ширина меньше самого длинного айтема
|
||
// if(rect.width * rect.scaleX < (legend_back.margin + biggest_legend_item_width) || canvas.getPointer(e.e).x < rect.left &&
|
||
// (legend_back.__corner == "mr" || legend_back.__corner == "tr" || legend_back.__corner == "br" ) ){
|
||
|
||
//////////// top - bottom ///////////////
|
||
|
||
if( (rect.height * rect.scaleY < text_height || canvas.getPointer(e.e).y > rect.top + text_height) &&
|
||
(legend_back.__corner == "mt" || legend_back.__corner == "tl" || legend_back.__corner == "tr" ) ){
|
||
|
||
var t = canvas.viewportTransform;
|
||
|
||
rect.scaleY = text_height / legend_back.height;
|
||
rect.top = Math.round((rect.oldrY - t[5]) / t[3]) - text_height - rect.strokeWidth;
|
||
}
|
||
|
||
if( (rect.height * rect.scaleY < text_height || canvas.getPointer(e.e).y < rect.top) &&
|
||
(legend_back.__corner == "mb" || legend_back.__corner == "bl" || legend_back.__corner == "br" ) ){
|
||
rect.scaleY = text_height / legend_back.height;
|
||
rect.top = rect.oldY;
|
||
}
|
||
|
||
//////////// left - right ////////////
|
||
|
||
if( (rect.width * rect.scaleX < (legend_back.margin + biggest_legend_item_width) || canvas.getPointer(e.e).x > rect.left + biggest_legend_item_width)
|
||
&& (legend_back.__corner == "ml" || legend_back.__corner == "tl" || legend_back.__corner == "bl" ) ){
|
||
|
||
var t = canvas.viewportTransform;
|
||
|
||
rect.scaleX = 1;
|
||
rect.left = Math.round((rect.oldrX - t[4]) / t[0]) - rect.oldWidth - rect.strokeWidth;
|
||
|
||
canvas.renderAll();
|
||
}
|
||
|
||
if( (rect.width * rect.scaleX < (legend_back.margin + biggest_legend_item_width) || canvas.getPointer(e.e).x < rect.left) &&
|
||
(legend_back.__corner == "mr" || legend_back.__corner == "tr" || legend_back.__corner == "br" ) ){
|
||
|
||
rect.scaleX = 1;
|
||
rect.left = rect.oldX;
|
||
|
||
canvas.renderAll();
|
||
}
|
||
|
||
|
||
canvas.bringToFront(rect).renderAll();
|
||
let deltaX = rect.left - rect.oldX;
|
||
let deltaY = rect.top - rect.oldY;
|
||
|
||
rect.oldX = rect.left;
|
||
rect.oldrX = rect.oCoords.tr.x;
|
||
|
||
rect.oldY = rect.top;
|
||
rect.oldrY = rect.oCoords.br.y;
|
||
|
||
rect.oldWidth = rect.width;
|
||
|
||
let array = canvas.getObjects();
|
||
for(var i in array){
|
||
let shape_type = /legend.*/.test(array[i].groupName);
|
||
if(shape_type){
|
||
array[i].left += deltaX;
|
||
array[i].top += deltaY;
|
||
canvas.bringToFront(array[i]);
|
||
}
|
||
}
|
||
rect.rx = rect.border_radius * (1 / rect.scaleX);
|
||
rect.ry = rect.border_radius * (1 / rect.scaleY);
|
||
}
|
||
rect.on('mousedown', function (e) {
|
||
canvas.preserveObjectStacking = true;
|
||
rect.hasControls = true;
|
||
canvas.setActiveObject(rect);
|
||
})
|
||
rect.on('mouseover', function () {
|
||
rect.selectable = true;
|
||
})
|
||
rect.on('mouseout', function () {
|
||
editor_obj.add_legend();
|
||
})
|
||
canvas.on('mouse:down:before', function (e) {
|
||
canvas.preserveObjectStacking = true;
|
||
let array = canvas.getObjects();
|
||
for(var i in array){
|
||
let shape_type = /legend.*/.test(array[i].groupName);
|
||
if(shape_type && array[i].type == "i-text"
|
||
&& canvas.getPointer(e.e).x > array[i].left && canvas.getPointer(e.e).x < array[i].left + array[i].width
|
||
&& canvas.getPointer(e.e).y > array[i].top && canvas.getPointer(e.e).y < array[i].top + array[i].height){
|
||
|
||
canvas.setActiveObject(array[i]);
|
||
array[i].enterEditing();
|
||
}
|
||
}
|
||
})
|
||
legend_back = rect;
|
||
legend_back.border_radius = 10;
|
||
}
|
||
// Общие функции
|
||
|
||
function stick(e, obj){
|
||
for(key in stick_array){
|
||
if(obj.groupName != key){
|
||
for(var n = 0; n <= Object.keys(stick_array[key]).length / 2; n++){
|
||
if(obj.name != "line_part1" && obj.name != "line_part2"){
|
||
obj_x = obj.get('left');
|
||
obj_y = obj.get('top');
|
||
}
|
||
else{
|
||
obj_x = obj.get('x1');
|
||
obj_y = obj.get('y1');
|
||
}
|
||
let stick_distance_line = {
|
||
x1: obj_x,
|
||
y1: obj_y,
|
||
x2: stick_array[key]["x" + n],
|
||
y2: stick_array[key]["y" + n],
|
||
};
|
||
|
||
if(Math.abs(calcLineLength(stick_distance_line)) < 20){
|
||
var stick_x = stick_distance_line["x2"];
|
||
var stick_y = stick_distance_line["y2"];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if(obj.name != "line_part1" && obj.name != "line_part2" ){
|
||
if(obj.parent.name == "rect"){
|
||
var opposite_point =obj.parent;
|
||
}
|
||
else{
|
||
if(obj.pointType == "arrow_start"){
|
||
var opposite_point = obj.parent.arrow2;
|
||
}
|
||
if(obj.pointType == "arrow_end"){
|
||
var opposite_point = obj.parent.arrow;
|
||
}
|
||
}
|
||
|
||
var angle = calcArrowAngle(canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, opposite_point.left, opposite_point.top, false);
|
||
var gap = 5;
|
||
var katet = obj.line.length;
|
||
var cross = false;
|
||
|
||
if(angle <= 0 + gap && angle >= 0 || angle >= 360 - gap && angle <= 360){
|
||
cross = "horizontal";
|
||
var stick_x = opposite_point.left - katet * Math.cos(0 * Math.PI / 180);
|
||
var stick_y = opposite_point.top;
|
||
}
|
||
|
||
if(angle <= 180 + gap && angle >= 180 - gap){
|
||
cross = "horizontal";
|
||
var stick_x = opposite_point.left - katet * Math.cos(180 * Math.PI / 180);
|
||
var stick_y = opposite_point.top;
|
||
}
|
||
|
||
if(angle <= 90 + gap && angle >= 90 - gap){
|
||
cross = "vertical";
|
||
var stick_x = opposite_point.left;
|
||
var stick_y = opposite_point.top - katet * Math.sin(90 * Math.PI / 180);
|
||
|
||
}
|
||
if(angle <= 270 + gap && angle >= 270 - gap){
|
||
cross = "vertical";
|
||
var stick_x = opposite_point.left;
|
||
var stick_y = opposite_point.top - katet * Math.sin(270 * Math.PI / 180);
|
||
}
|
||
|
||
var ctx = canvas.contextTop;
|
||
ctx.strokeStyle = "lime";
|
||
ctx.beginPath();
|
||
ctx.setLineDash([5, 5]);
|
||
|
||
if(cross == "horizontal"){
|
||
var transform = fabric.util.transformPoint(new fabric.Point(canvas.vptCoords.tr.x, stick_y), canvas.viewportTransform);
|
||
ctx.moveTo(transform.x, transform.y);
|
||
ctx.lineTo(0, transform.y);
|
||
ctx.stroke();
|
||
}
|
||
else if(cross == "vertical"){
|
||
var transform = fabric.util.transformPoint(new fabric.Point(stick_x, canvas.vptCoords.br.y), canvas.viewportTransform);
|
||
ctx.moveTo(transform.x, transform.y);
|
||
ctx.lineTo(transform.x, 0);
|
||
ctx.stroke();
|
||
}
|
||
else{
|
||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||
}
|
||
}
|
||
|
||
|
||
if(typeof stick_x == "number"){
|
||
obj.set('left', stick_x);
|
||
obj.set('top', stick_y);
|
||
if(obj.pointType == "arrow_start"){
|
||
obj.line.set('x1', stick_x);
|
||
obj.line.set('y1', stick_y);
|
||
}
|
||
}
|
||
}
|
||
|
||
function moveEnd(e, obj, cap_flag = false) {
|
||
|
||
if(btn_stick.classList.contains("top-menu-button-selected")){
|
||
stick(e, obj);
|
||
var stick_flag = true;
|
||
}
|
||
else{
|
||
var stick_flag = false;
|
||
}
|
||
|
||
if(obj.name == "arrow" || obj.name == "arrow_part1" || obj.name == "line_part1"){
|
||
obj.line.oldX = obj.line.x1;
|
||
obj.line.oldY = obj.line.y1;
|
||
|
||
if(obj.parent.groupType == "geometry"){
|
||
obj.line.old_fake_X = obj.parent.line_part1.x1;
|
||
obj.line.old_fake_Y = obj.parent.line_part1.y1;
|
||
}
|
||
|
||
}
|
||
else{
|
||
// obj.fill = "blue";
|
||
obj.line.oldX = obj.line.x2;
|
||
obj.line.oldY = obj.line.y2;
|
||
|
||
if(obj.parent.groupType == "geometry"){
|
||
obj.line.old_fake_X = obj.parent.line_part2.x1;
|
||
obj.line.old_fake_Y = obj.parent.line_part2.y1;
|
||
}
|
||
}
|
||
if(obj.name == "arrow" || obj.name == "arrow2" || obj.name == "arrow_part1" || obj.name == "arrow_part2"){
|
||
if(!obj.parent.border){
|
||
obj.line.set('x1', obj.arrow.get('left'));
|
||
obj.line.set('y1', obj.arrow.get('top'));
|
||
if(obj.arrow2 != undefined){
|
||
obj.line.set('x2', obj.arrow2.get('left'));
|
||
obj.line.set('y2', obj.arrow2.get('top'));
|
||
}
|
||
else{
|
||
obj.line.set('x2', obj.parent.get('left'));
|
||
obj.line.set('y2', obj.parent.get('top'));
|
||
}
|
||
}
|
||
|
||
textRotate(obj);
|
||
var x1, y1, x2, y2;
|
||
var side_line1, side_line2;
|
||
if(obj.name == "arrow"){
|
||
side_line1 = obj.parent.line_part1;
|
||
side_line2 = obj.parent.line_part2;
|
||
var param1 = "1";
|
||
var param2 = "2";
|
||
var param3 = "2";
|
||
}
|
||
else if(obj.name == "arrow2"){
|
||
side_line1 = obj.parent.line_part2;
|
||
side_line2 = obj.parent.line_part1;
|
||
var param1 = "2";
|
||
var param2 = "1";
|
||
var param3 = "";
|
||
}
|
||
if(side_line2 != undefined){ // объект geometry
|
||
|
||
var diag_angle_new = calcArrowAngle(canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, side_line2.x1, side_line2.y1, true);
|
||
|
||
//////////
|
||
var r2 = obj.parent.diag = calcLineLength({x1: side_line2.x1, y1: side_line2.y1, x2: canvas.getPointer(e.e).x, y2: canvas.getPointer(e.e).y});
|
||
|
||
obj.parent.old_diag_angle = diag_angle_new;
|
||
|
||
var katet2 = side_line2.length;
|
||
|
||
// угол между курсором (стрелкой основной линии) и нижней точкой боковой линии
|
||
var temp_angle = calcArrowAngle(canvas.getPointer(e.e).x, canvas.getPointer(e.e).y, side_line1.x1, side_line1.y1, true);
|
||
|
||
var rotate_angle = Math.PI/2 - temp_angle + diag_angle_new; // угол, нак который поворачивается
|
||
// координатная плоскость, угол между диагональю и линией,
|
||
// проходящей мужду двух нижних точек боковых линий (фактически основание прямоугольника фигуры geometry)
|
||
// x3 показывает, слева или справа находится x в координатной плоскости центром которой является точка, за которую тянем,
|
||
// если x3 слева от x4, то мы поворачивали фигуру, а не перетаскивали курсор так, чтобы она зеркально отразилась
|
||
// иначе говоря, x3 это проекция точки курсора на линию, проходящую мужду двух нижних точек боковых линий, которая становится осью Х
|
||
var luft = 50;
|
||
if(obj.parent.opposite == false){
|
||
luft = -50;
|
||
}
|
||
let x3 = side_line2.x1 - r2 * Math.cos(rotate_angle) + luft;
|
||
let y3 = side_line2.y1 + r2 * Math.cos(Math.PI - rotate_angle);
|
||
let x4 = side_line2.x1;
|
||
let y4 = side_line2.y1;
|
||
|
||
var ctx = canvas.upperCanvasEl.getContext('2d');
|
||
ctx.fillStyle = "lime";
|
||
|
||
// var ctx = canvas.upperCanvasEl.getContext('2d');
|
||
// ctx.fillStyle = "orange";
|
||
// ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||
// var transform = fabric.util.transformPoint(new fabric.Point(x3, 300), canvas.viewportTransform);
|
||
// ctx.fillRect(transform.x, transform.y, 10, 10);
|
||
|
||
// obj.parent.opposite — если true, это означает, что мы переместили край, за который тянем, за точку,
|
||
// из которой начали рисовать
|
||
var hyp = Math.sqrt(Math.pow(r2, 2) - Math.pow(katet2, 2));
|
||
if(hyp <= 150 || isNaN(hyp)){
|
||
if(!obj.parent.border){
|
||
side_line1.start = {
|
||
x: obj.left,
|
||
y: obj.top
|
||
}
|
||
}
|
||
obj.parent.border = true;
|
||
// console.log(obj.parent.border);
|
||
}
|
||
else{
|
||
obj.parent.border = false;
|
||
}
|
||
|
||
if(x3 < x4 && y3 < y4){
|
||
obj.parent.opposite = true;
|
||
// console.log("слева");
|
||
}
|
||
else{
|
||
obj.parent.opposite = false;
|
||
// console.log("справа");
|
||
}
|
||
|
||
if(obj.parent.border){
|
||
let beta = calcArrowAngle(obj.line.get("x" + param2), obj.line.get("y" + param2), side_line1.start.x, side_line1.start.y, true);
|
||
// console.log(beta * 180 / Math.PI);
|
||
var x0 = side_line1.start.x;
|
||
var y0 = side_line1.start.y;
|
||
|
||
var xr = canvas.getPointer(e.e).x;
|
||
var yr = y0 - (x0 - xr) * Math.tan(beta);
|
||
|
||
obj.left = xr;
|
||
obj.top = yr;
|
||
obj.line.set("x" + param1, obj.get('left'));
|
||
obj.line.set("y" + param1, obj.get('top'));
|
||
}
|
||
|
||
// в некотором диапазоне от начальной точки меняем формулу, но не меняем obj.parent.opposite. Также меняем
|
||
// формулу, если obj.parent.opposite равен true
|
||
if(!obj.parent.opposite || (!obj.parent.opposite && !obj.parent.added)){
|
||
var signX = 1;
|
||
var signY = 1;
|
||
var ugol2 = diag_angle_new - Math.acos(katet2 / r2);
|
||
}
|
||
else{
|
||
var signX = -1;
|
||
var signY = 1;
|
||
var ugol2 = Math.PI - (diag_angle_new + Math.acos(katet2 / r2));
|
||
}
|
||
// если больше определенной длины линии между курсором и верхней точкой боковой линии
|
||
if(Math.sqrt(Math.pow(r2, 2) - Math.pow(katet2, 2)) >= 5){
|
||
// side_line2 изменяется и определен выше
|
||
// тут рисуем точку основной линии, противоположной той, со стороны которй находится стрелка, за которую тянем
|
||
// x1 — расчетная нижняя точка боковой линии
|
||
// x2 — расчетная верхняя точка боковой линии
|
||
x2 = side_line2.x1 - signX * katet2 * Math.cos(ugol2);
|
||
y2 = side_line2.y1 - signY * katet2 * Math.sin(ugol2);
|
||
if(!obj.parent.border){
|
||
obj.line.set("x" + param2, x2);
|
||
obj.line.set("y" + param2, y2);
|
||
}
|
||
|
||
obj.lockMovementX = false;
|
||
obj.lockMovementY = false;
|
||
}
|
||
else{
|
||
obj.lockMovementX = true;
|
||
obj.lockMovementY = true;
|
||
|
||
obj.line.set("x" + param1, obj.line["lastX" + param1]);
|
||
obj.line.set("y" + param1, obj.line["lastY" + param1]);
|
||
|
||
obj.set('left', obj.line.get("x" + param1));
|
||
obj.set('top', obj.line.get("y" + param1));
|
||
}
|
||
|
||
}
|
||
else{ // если не объект geometry
|
||
var coords;
|
||
|
||
if(obj.arrow2){
|
||
var angle = calcArrowAngle(obj.arrow.get('left'), obj.arrow.get('top'), obj.arrow2.get('left'), obj.arrow2.get('top'), true);
|
||
}
|
||
else{
|
||
var angle = calcArrowAngle(obj.arrow.get('left'), obj.arrow.get('top'), obj.line.get('x2'), obj.line.get('y2'), true);
|
||
}
|
||
}
|
||
|
||
obj.line._setWidthHeight();
|
||
|
||
var key = obj.groupName;
|
||
stick_array[key] = {};
|
||
|
||
let param = text2Angle(obj.line.get('x1'), obj.line.get('y1'), obj.line.get('x2'), obj.line.get('y2'));
|
||
x0 = stick_array[key].x0 = param.x;
|
||
x0 = stick_array[key].y0 = param.y;
|
||
|
||
x1 = stick_array[key].x1 = obj.line.get('x1');
|
||
y1 = stick_array[key].y1 = obj.line.get('y1');
|
||
x2 = stick_array[key].x2 = obj.line.get('x2');
|
||
y2 = stick_array[key].y2 = obj.line.get('y2');
|
||
|
||
// var t = canvas.viewportTransform;
|
||
|
||
// canvas.contextTop.fillRect(t[0]*x0+t[4], t[3]*y0+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x1+t[4], t[3]*y1+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x2+t[4], t[3]*y2+t[5], 10, 10)
|
||
|
||
if(obj.parent.groupType == "geometry"){
|
||
x3 = stick_array[key].x3 = obj.parent.line_part1.get('x1');
|
||
y3 = stick_array[key].y3 = obj.parent.line_part1.get('y1');
|
||
x4 = stick_array[key].x4 = obj.parent.line_part2.get('x1');
|
||
y4 = stick_array[key].y4 = obj.parent.line_part2.get('y1');
|
||
param = text2Angle(obj.parent.line_part1.get('x1'), obj.parent.line_part1.get('y1'), obj.parent.line.get('x1'), obj.parent.line.get('y1'));
|
||
x5 = stick_array[key].x5 = param.x;
|
||
y5 = stick_array[key].y5 = param.y;
|
||
param = text2Angle(obj.parent.line_part2.get('x1'), obj.parent.line_part2.get('y1'), obj.parent.line.get('x2'), obj.parent.line.get('y2'));
|
||
x6 = stick_array[key].x6 = param.x;
|
||
y6 = stick_array[key].y6 = param.y;
|
||
|
||
// var t = canvas.viewportTransform;
|
||
|
||
// canvas.contextTop.fillRect(t[0]*x0+t[4], t[3]*y0+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x1+t[4], t[3]*y1+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x2+t[4], t[3]*y2+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x3+t[4], t[3]*y3+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x4+t[4], t[3]*y4+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x5+t[4], t[3]*y5+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x6+t[4], t[3]*y6+t[5], 10, 10)
|
||
}
|
||
if(obj.parent.groupType == "socket"){
|
||
if(obj.name == "arrow_part1"){
|
||
param = text2Angle(obj.parent.line_part2.get('x1'), obj.parent.line_part2.get('y1'), obj.parent.line_part2.get('x2'), obj.parent.line_part2.get('y2'));
|
||
x3 = stick_array[key].x3 = param.x;
|
||
y3 = stick_array[key].y3 = param.y;
|
||
x4 = stick_array[key].x4 = obj.parent.line_part2.get('x1');
|
||
y4 = stick_array[key].y4 = obj.parent.line_part2.get('y1');
|
||
}
|
||
else{
|
||
param = text2Angle(obj.parent.line_part1.get('x1'), obj.parent.line_part1.get('y1'), obj.parent.line_part1.get('x2'), obj.parent.line_part1.get('y2'));
|
||
x3 = stick_array[key].x3 = param.x;
|
||
y3 = stick_array[key].y3 = param.y;
|
||
x4 = stick_array[key].x4 = obj.parent.line_part1.get('x1');
|
||
y4 = stick_array[key].y4 = obj.parent.line_part1.get('y1');
|
||
}
|
||
|
||
// var t = canvas.viewportTransform;
|
||
|
||
// canvas.contextTop.fillRect(t[0]*x0+t[4], t[3]*y0+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x1+t[4], t[3]*y1+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x2+t[4], t[3]*y2+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x3+t[4], t[3]*y3+t[5], 10, 10)
|
||
// canvas.contextTop.fillRect(t[0]*x4+t[4], t[3]*y4+t[5], 10, 10)
|
||
}
|
||
|
||
if(typeof angle == "undefined"){
|
||
var angle = calcArrowAngle(x1, y1, x2, y2);
|
||
}
|
||
else{
|
||
angle = angle * 180 / Math.PI;
|
||
}
|
||
|
||
if(obj.parent.groupType != "cap"){
|
||
obj.arrow.set('angle', angle);
|
||
}
|
||
|
||
if(obj.arrow2 != undefined && obj.type != "circle"){
|
||
obj.arrow2.set('angle', angle);
|
||
}
|
||
|
||
obj.line.setCoords();
|
||
|
||
if(obj.parent.groupType == "cap" && !cap_flag){
|
||
if(Math.sign(Math.cos(angle * Math.PI/180))>0){
|
||
obj.arrow.originX = 'right';
|
||
}
|
||
else{
|
||
obj.arrow.originX = 'left';
|
||
}
|
||
}
|
||
if(obj.parent.groupType == "geometry" && ugol2 != NaN){
|
||
let lines_coords = calcLineAngle(obj, e);
|
||
if(obj.name == "arrow" || obj.name == "arrow2"){
|
||
let rotate_obj = obj.parent.line_part2;
|
||
if(!obj.parent.added){ // фигура geometry не создана, растягивается бъект parent
|
||
r2 = rotate_obj.length;
|
||
x2 = rotate_obj.x1 - 1 * r2 * Math.cos(ugol2);
|
||
y2 = rotate_obj.y1 - 1 * r2 * Math.sin(ugol2);
|
||
|
||
obj.parent.line_part1.set('x1', lines_coords.x1);
|
||
obj.parent.line_part1.set('y1', lines_coords.y1);
|
||
obj.parent.line_part2.set('x2', x2);
|
||
obj.parent.line_part2.set('y2', y2);
|
||
|
||
obj.parent.arrow2.set('left', x2);
|
||
obj.parent.arrow2.set('top', y2);
|
||
|
||
obj.parent.arrow_part1.set('left', lines_coords.x1);
|
||
obj.parent.arrow_part1.set('top', lines_coords.y1);
|
||
obj.parent.arrow_part2.set('left', lines_coords.x2);
|
||
obj.parent.arrow_part2.set('top', lines_coords.y2);
|
||
|
||
obj.parent.arrow_part1.setCoords();
|
||
obj.parent.arrow_part2.setCoords();
|
||
|
||
obj.parent.line_part1.length = obj.parent.line_part2.length = calcLineLength({x1: obj.parent.line_part2.x1, y1: obj.parent.line_part2.y1, x2: obj.parent.line_part2.x2, y2: obj.parent.line_part2.y2});
|
||
}
|
||
else{
|
||
// нижняя точка боковой линии
|
||
side_line1.set('x1', lines_coords["x" + param1]);
|
||
side_line1.set('y1', lines_coords["y" + param1]);
|
||
|
||
// элемент arrow (тут пустой круг), нижняя точка боковой линии
|
||
obj.parent.arrow_part1.set('left', lines_coords.x1);
|
||
obj.parent.arrow_part1.set('top', lines_coords.y1);
|
||
// элемент arrow (тут пустой круг), нижняя точка боковой линии
|
||
obj.parent.arrow_part2.set('left', lines_coords.x2);
|
||
obj.parent.arrow_part2.set('top', lines_coords.y2);
|
||
|
||
}
|
||
}
|
||
textRotate(obj.parent);
|
||
// Если тянем за стрелки
|
||
if(canvas.getActiveObject()){
|
||
var active_obj = canvas.getActiveObject().name;
|
||
if(active_obj != "line_part1" && active_obj != "line_part2"){
|
||
// верхняя точка боковой линии у той стрелки, за которую тянем
|
||
side_line1.set('x2', obj.parent["x" + param1]);
|
||
side_line1.set('y2', obj.parent["y" + param1]);
|
||
// верхняя точка противоположной боковой линии
|
||
var side_ang = calcArrowAngle(side_line1.x1, side_line1.y1, side_line1.x2, side_line1.y2, true)
|
||
var side_top_x = side_line2.x1 + 1 * side_line1.length * Math.cos(side_ang);
|
||
var side_top_y = side_line2.y1 + 1 * side_line1.length * Math.sin(side_ang);
|
||
|
||
side_line2.set('x2', side_top_x);
|
||
side_line2.set('y2', side_top_y);
|
||
|
||
if(obj.parent.groupType == "geometry"){
|
||
if(!obj.parent.border && obj.parent.added){
|
||
obj.line.set("x" + param2, side_top_x);
|
||
obj.line.set("y" + param2, side_top_y);
|
||
}
|
||
obj.parent["arrow" + param3].set('left', obj.parent["x" + param2]);
|
||
obj.parent["arrow" + param3].set('top', obj.parent["y" + param2]);
|
||
}
|
||
}
|
||
// if(stick_flag){
|
||
// // stick(e, side_line1);
|
||
// // stick(e, side_line2);
|
||
// }
|
||
}
|
||
if(testgo){
|
||
side_line1.set('x2', obj.parent["x" + param1]);
|
||
side_line1.set('y2', obj.parent["y" + param1]);
|
||
side_line2.set('x2', obj.parent["x" + param2]);
|
||
side_line2.set('y2', obj.parent["y" + param2]);
|
||
}
|
||
}
|
||
}
|
||
obj.line.lastX1 = obj.line.x1;
|
||
obj.line.lastX2 = obj.line.x2;
|
||
obj.line.lastY1 = obj.line.y1;
|
||
obj.line.lastY2 = obj.line.y2;
|
||
if(!obj.parent.added){
|
||
//иначе при создании стрелки рисуются с опозданием
|
||
canvas.renderAll();
|
||
}
|
||
}
|
||
|
||
function moveLine(e, line) {
|
||
if(line.parent.arrow_part1 != undefined && line.parent.groupType != "socket"){ // Объет geometry
|
||
if(line.name != "line_part1" && line.name != "line_part2"){
|
||
line.parent.line_part1.length = line.parent.line_part2.length = calcLineLength({x1: line.parent.line_part1.x1, y1: line.parent.line_part1.y1, x2: line.parent.line_part1.x2, y2: line.parent.line_part1.y2});
|
||
}
|
||
|
||
let x0 = line.first_click.x;
|
||
let y0 = line.first_click.y;
|
||
|
||
let beta = calcArrowAngle(line.parent.line.x1, line.parent.line.y1, line.parent.line.x2, line.parent.line.y2, true);
|
||
|
||
// let alpha = beta + Math.PI/2;
|
||
|
||
if ((beta > Math.PI / 2 - 0.1 && beta < Math.PI / 2 + 0.1) ||
|
||
(beta > Math.PI * 3 / 2 - 0.1 && beta < Math.PI * 3 / 2 + 0.1)){
|
||
var x = canvas.getPointer(e.e).x;
|
||
var y = y0 - (x - x0) * 1 / Math.tan(beta);
|
||
}
|
||
else{
|
||
var y = canvas.getPointer(e.e).y;
|
||
var x = x0 - (y - y0) * Math.tan(beta);
|
||
}
|
||
var delta_first_clickX = x - x0;
|
||
var delta_first_clickY = y - y0;
|
||
if(line.name != "line_part1" && line.name != "line_part2"){
|
||
line.set({
|
||
'left': line.first_center.x + delta_first_clickX,
|
||
'top': line.first_center.y + delta_first_clickY
|
||
});
|
||
// canvas.renderAll();
|
||
}
|
||
if(line == line.parent){
|
||
if(Math.sign(line.parent.line_part1.y2 - line.parent.line_part1.y1) < 0){
|
||
line.parent.text2.originY = 'bottom';
|
||
if(beta * 180 / Math.PI >= 90 && beta * 180 / Math.PI <= 270){
|
||
line.parent.direction = 1; // устанавливаем направление относительно начального положения — требуется,
|
||
// чтобы понять, с какой стороны от основной линии рисовать боковые линии
|
||
}
|
||
else{
|
||
line.parent.direction = -1; // устанавливаем направлени относительно начального положенияе — требуется,
|
||
// чтобы понять, с какой стороны от основной линии рисовать боковые линии
|
||
}
|
||
}
|
||
else{
|
||
line.parent.text2.originY = 'top';
|
||
if(beta * 180 / Math.PI >= 90 && beta * 180 / Math.PI <= 270){
|
||
line.parent.direction = -1;
|
||
}
|
||
else{
|
||
line.parent.direction = 1;
|
||
}
|
||
}
|
||
}
|
||
if(line.name != "line_part2"){
|
||
line.parent.line_part2.set('x2', line.parent.x2);
|
||
line.parent.line_part2.set('y2', line.parent.y2);
|
||
line.parent.line_part2.setCoords();
|
||
}
|
||
if(line.name != "line_part1"){
|
||
line.parent.line_part1.set('x2', line.parent.x1);
|
||
line.parent.line_part1.set('y2', line.parent.y1);
|
||
line.parent.line_part1.setCoords();
|
||
}
|
||
if(line.name == "line_part1"){
|
||
line.parent.arrow.set('left', line.parent.line_part1.x2);
|
||
line.parent.arrow.set('top', line.parent.line_part1.y2);
|
||
line.parent.arrow_part1.set('left', line.parent.line_part1.x1);
|
||
line.parent.arrow_part1.set('top', line.parent.line_part1.y1);
|
||
}
|
||
if(line.name == "line_part2"){
|
||
line.parent.arrow2.set('left', line.parent.line_part2.x2);
|
||
line.parent.arrow2.set('top', line.parent.line_part2.y2);
|
||
line.parent.arrow_part2.set('left', line.parent.line_part2.x1);
|
||
line.parent.arrow_part2.set('top', line.parent.line_part2.y1);
|
||
}
|
||
if(line.name != "line_part1" && line.name != "line_part2"){
|
||
line.parent.diag_length = calcLineLength({x1: line.parent.line_part2.x1, y1: line.parent.line_part2.y1, x2: line.line.x1, y2: line.line.y1});
|
||
}
|
||
}
|
||
line.setCoords();
|
||
angle = calcArrowAngle(line.x1, line.y1, line.x2, line.y2);
|
||
var oldCenterX = (line.x1 + line.x2) / 2,
|
||
oldCenterY = (line.y1 + line.y2) / 2,
|
||
deltaX = Math.round(line.left - oldCenterX),
|
||
deltaY = Math.round(line.top - oldCenterY);
|
||
line.arrow.set({
|
||
'left': line.x1 + deltaX,
|
||
'top': line.y1 + deltaY
|
||
}).setCoords();
|
||
if(line.arrow2 != undefined){
|
||
line.arrow2.set({
|
||
'left': line.x2 + deltaX,
|
||
'top': line.y2 + deltaY
|
||
}).setCoords();
|
||
}
|
||
line.set({
|
||
'x1': line.x1 + deltaX,
|
||
'y1': line.y1 + deltaY,
|
||
'x2': line.x2 + deltaX,
|
||
'y2': line.y2 + deltaY
|
||
});
|
||
line.set({
|
||
'left': (line.x1 + line.x2) / 2,
|
||
'top': (line.y1 + line.y2) / 2
|
||
});
|
||
|
||
if(line.text2 != undefined && line.parent.groupType != "cap"){
|
||
textRotate(line);
|
||
}
|
||
|
||
var key = line.groupName;
|
||
if(stick_array[key]){
|
||
stick_array[key].x1 = line.get('x1');
|
||
stick_array[key].y1 = line.get('y1');
|
||
stick_array[key].x2 = line.get('x2');
|
||
stick_array[key].y2 = line.get('y2');
|
||
}
|
||
if(line.parent.groupType == "geometry"){
|
||
// Иначе стрелки рисуются с опозданием
|
||
canvas.renderAll();
|
||
}
|
||
}
|
||
|
||
function calcLineLength(line){
|
||
let a = line.x2 - line.x1;
|
||
let b = line.y2 - line.y1;
|
||
let length = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
|
||
return length;
|
||
}
|
||
|
||
function calcLineAngle(obj, e){
|
||
// здесь высчитываются координаты концов боковых линий в зависимости от угла основной линии к горизонтали
|
||
if(obj.angleDelta == undefined){
|
||
obj.angleDelta = 0;
|
||
}
|
||
var beta = calcArrowAngle(obj.parent.x1, obj.parent.y1, obj.parent.x2, obj.parent.y2, true);
|
||
|
||
if(obj.name == "arrow" || obj.name == "arrow_part1" || obj.name == "line_part1"){
|
||
var line_main = {
|
||
x1: obj.parent.line.x1,
|
||
y1: obj.parent.line.y1,
|
||
x2: obj.parent.line.x2,
|
||
y2: obj.parent.line.y2
|
||
}
|
||
}
|
||
else{
|
||
var line_main = {
|
||
x1: obj.parent.line.x2,
|
||
y1: obj.parent.line.y2,
|
||
x2: obj.parent.line.x1,
|
||
y2: obj.parent.line.y1
|
||
}
|
||
}
|
||
|
||
var beta_deg = beta * 180 / Math.PI;
|
||
if((beta_deg > 135 && beta_deg < 225) || (beta_deg > 315 && beta_deg < 360) || (beta_deg < 45)){
|
||
//console.log("Под 45!");
|
||
if(Math.sign(line_main.x2 - obj.parent.line.oldX) == -Math.sign(line_main.x2 - line_main.x1)){
|
||
//console.log("Сменили знак!");
|
||
if(obj.angleDelta == 0){
|
||
obj.angleDelta = Math.PI;
|
||
}
|
||
else{
|
||
obj.angleDelta = 0;
|
||
}
|
||
}
|
||
}
|
||
else{
|
||
if(Math.sign(line_main.y2 - obj.parent.line.oldY) == -Math.sign(line_main.y2 - line_main.y1)){
|
||
if(obj.angleDelta == 0){
|
||
obj.angleDelta = Math.PI;
|
||
}
|
||
else{
|
||
obj.angleDelta = 0;
|
||
}
|
||
beta += Math.PI;
|
||
}
|
||
}
|
||
|
||
beta += obj.angleDelta; // угол основной линии
|
||
//console.log(beta * 180 / Math.PI);
|
||
// боковая линия рисуется под углом девянсото градусов к основной с учетом направления:
|
||
if(obj.name == "arrow" || obj.name == "line_part1"){ // в зависимости от того, за какую часть деформируем
|
||
if(obj.parent.direction == -1){
|
||
var alpha = beta + Math.PI/2;
|
||
}
|
||
else{
|
||
var alpha = beta - Math.PI/2;
|
||
}
|
||
}
|
||
if(obj.name == "arrow2" || obj.name == "line_part2"){ // в зависимости от того, за какую часть деформируем
|
||
if(obj.parent.direction == 1){
|
||
var alpha = beta - Math.PI/2;
|
||
}
|
||
else{
|
||
var alpha = beta + Math.PI/2;
|
||
}
|
||
}
|
||
|
||
let r2 = obj.parent.line_part2.length; // длина боковой линии
|
||
|
||
if(obj.name == "arrow" || obj.name == "arrow2"){
|
||
sign = 1;
|
||
}
|
||
else{
|
||
sign = -1;
|
||
}
|
||
|
||
if(obj.name == "arrow" || obj.name == "arrow2"){
|
||
var x0 = obj.parent.x1;
|
||
var y0 = obj.parent.y1;
|
||
}
|
||
else{
|
||
var x0 = obj.parent.line_part1.x1;
|
||
var y0 = obj.parent.line_part1.y1;
|
||
}
|
||
|
||
// нижняя точка первой линии
|
||
let x1 = x0 + sign * r2 * Math.cos(alpha);
|
||
let y1 = y0 + sign * r2 * Math.sin(alpha);
|
||
|
||
if(obj.name == "arrow" || obj.name == "arrow2"){
|
||
var x0 = obj.parent.x2;
|
||
var y0 = obj.parent.y2;
|
||
}
|
||
else{
|
||
var x0 = obj.parent.line_part2.x1;
|
||
var y0 = obj.parent.line_part2.y1;
|
||
}
|
||
|
||
// нижняя точка второй линии
|
||
let x2 = x0 + sign * r2 * Math.cos(alpha);
|
||
let y2 = y0 + sign * r2 * Math.sin(alpha);
|
||
|
||
return {x1: x1, y1: y1, x2: x2, y2: y2, parent_ang: beta_deg};
|
||
}
|
||
|
||
function calcArrowAngle(x1, y1, x2, y2, rad = false) {
|
||
let r = calcLineLength({x1: x1, y1: y1, x2: x2, y2: y2}); // длинна линии
|
||
let beta = Math.acos((x2 - x1) / r); // угол между линией и осью абсцисс
|
||
|
||
beta = beta + (Math.PI - beta) * 2 * -1 * Math.sign(-1 + Math.sign(y2 - y1));
|
||
let angle = beta * 180 / Math.PI;
|
||
if(rad){
|
||
return beta;
|
||
}
|
||
else{
|
||
return angle;
|
||
}
|
||
}
|
||
|
||
function textRotate(obj){
|
||
if(obj.text2 != undefined && obj.parent.groupType != "cap"){
|
||
let param = text2Angle(obj.line.x1, obj.line.y1, obj.line.x2, obj.line.y2);
|
||
let alpha = param.ang;
|
||
if(alpha != 360){
|
||
obj.text2.angle = alpha - 180*Math.floor(Math.cos(alpha*Math.PI/180));
|
||
}
|
||
else{
|
||
obj.text2.angle = alpha;
|
||
}
|
||
|
||
obj.text2.setCoords();
|
||
|
||
// центрирование текста
|
||
|
||
obj.text2.left = param.x - (obj.text2.width/2)*Math.cos(alpha*Math.PI/180)*Math.sign(Math.cos(alpha*Math.PI/180));
|
||
obj.text2.top = param.y - (obj.text2.width/2)*Math.sin(alpha*Math.PI/180)*Math.sign(Math.cos(alpha*Math.PI/180));
|
||
}
|
||
}
|
||
|
||
function text2Angle(x1, y1, x2, y2){
|
||
let ang = calcArrowAngle(x1, y1, x2, y2);
|
||
|
||
let x3 = (x2 - x1) / 2 + x1;
|
||
let y3 = (y2 - y1) / 2 + y1;
|
||
let coords = {
|
||
ang: ang,
|
||
x: x3,
|
||
y: y3
|
||
};
|
||
|
||
return coords;
|
||
}
|
||
|
||
function getRadiusCoords(x0 = 0, y0 = 0, radius = 10, angle){
|
||
// x = Math.ceil(x0 + radius * Math.cos(angle));
|
||
// y = Math.ceil(y0 + radius * Math.sin(angle));
|
||
var x = x0 + radius * Math.cos(angle);
|
||
var y = y0 + radius * Math.sin(angle);
|
||
return {x: x, y: y, angle: angle}
|
||
}
|
||
|
||
function gof(){
|
||
|
||
// shape[0].line.set("y1", shape[0].line.y2);
|
||
shape[0].line.set("x2", 300);
|
||
shape[0].line.set("y2", 200);
|
||
shape[0].line.set("x1", 600);
|
||
shape[0].line.set("y1", 200);
|
||
shape[0].line_part1.set("y1", shape[0].line.y1);
|
||
shape[0].line_part1.set("x1", shape[0].line.x1);
|
||
shape[0].line_part1.set("x2", shape[0].line.x1);
|
||
shape[0].line_part1.set("y2", shape[0].line.y1 + 100);
|
||
|
||
shape[0].line_part2.set("y1", shape[0].line.y2);
|
||
shape[0].line_part2.set("x1", shape[0].line.x2);
|
||
shape[0].line_part2.set("x2", shape[0].line.x2);
|
||
shape[0].line_part2.set("y2", shape[0].line.y2 + 100);
|
||
shape[0].arrow.set("left", shape[0].line.x1);
|
||
shape[0].arrow2.set("left", shape[0].line.x2);
|
||
shape[0].arrow.set("top", shape[0].line.y1);
|
||
shape[0].arrow2.set("top", shape[0].line.y2);
|
||
canvas.renderAll();
|
||
}
|
||
var shag = -60;
|
||
var testgo = false;
|
||
function go(){
|
||
testgo = true;
|
||
shape[0].line.arrow2.set("left", shape[0].line.arrow2.left - shag);
|
||
moveEnd({e: {clientX: shape[0].line.arrow2.left, clientY: shape[0].line.arrow2.top}}, shape[0].line.arrow2);
|
||
// testgo = true;
|
||
// shape[1].line_part1.arrow.set("left", shape[1].line_part1.arrow.left - shag);
|
||
// moveEnd({pointer: {x: shape[1].line_part1.arrow.left, y: shape[1].line_part1.arrow.top}}, shape[1].line_part1.arrow);
|
||
canvas.renderAll()
|
||
}
|
||
|
||
function moveByStep(stepX, stepY){
|
||
item = canvas.getActiveObject();
|
||
var move_obj;
|
||
if(item){
|
||
|
||
if(group.cloneOne){ // __onMouseDown в fabric.js, там установлен getActiveObject().setCoords()
|
||
let item = canvas.getActiveObject();
|
||
editor_obj.setClone(item);
|
||
canvas.renderAll();
|
||
element_cursor();
|
||
}
|
||
else{
|
||
oldParam(item);
|
||
}
|
||
|
||
if( (item.parent.objects || item.parent._objects != undefined) ){ // если не примтив,
|
||
//проходимся по всем частям составного объекта
|
||
if(item.parent.objects != undefined){
|
||
for(let i of item.parent.objects){
|
||
move_obj = item.parent[i];
|
||
move_obj.left += stepX;
|
||
move_obj.top += stepY;
|
||
}
|
||
}
|
||
if(item.parent._objects != undefined){ // выделение или группа и не часть другого объекта
|
||
for(let obj of item.parent._objects){
|
||
move_obj = obj;
|
||
move_obj.left += stepX;
|
||
move_obj.top += stepY;
|
||
}
|
||
}
|
||
}else{
|
||
move_obj = item;
|
||
move_obj.left += stepX;
|
||
move_obj.top += stepY;
|
||
}
|
||
|
||
changes(item, "12");
|
||
|
||
poupup.classList.add("mfp-hide");
|
||
var ctx = canvas.contextTop;
|
||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||
canvas.renderAll();
|
||
}
|
||
} |