GraphEditor/js/functions_geometry.js
2025-08-16 08:37:11 +00:00

2085 lines
92 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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();
}
}