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

369 lines
15 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 editor_multiplier = 1;
let auto_save_flag = true;
let file_loaded = true;
let board = document.querySelector("#intro-canvas");
var canvas = new fabric.Canvas('intro-canvas', {
targetFindTolerance: 2,
selectionBorderColor: "black",
selectionDashArray: [10, 10],
selectionLineWidth: 2,
selectionColor: "rgba(100, 100, 255, 0)",
cornerSize: 6
});
let state;
canvas.objectCaching = false;
fabric.Object.prototype.objectCaching = false;
// canvas.backgroundColor = 'rgba(256, 256, 256, 1)';
canvas.freeDrawingBrush.width = 1;
canvas.renderAll();
let btn_save = document.querySelector("#btnSave");
let btn_saveBitmap = document.querySelector("#btnSaveBitmap");
if(top_panel_display == "none"){
document.body.appendChild(btn_saveBitmap);
btn_saveBitmap.classList.add("save-btn-preview");
}
let input_filename = document.querySelector("#inputFilename");
function beforeSave(filename, callback, auto_save_flag){
array = canvas.getObjects();
for(i in array){
array[i].excludeFromExport = !array[i].visible;
let shape_type = /shape_group.*/.test(array[i].groupName)
if(shape_type){
array[i].excludeFromExport = false;
}
}
board.style.pointerEvents = "none";
canvas.backgroundImage.setCoords();
var coords = canvas.backgroundImage.oCoords;
let tl = coords.tl;
let bl = coords.bl;
let br = coords.br;
let x = tl.x;
let y = tl.y;
let w = br.x - bl.x;
let h = bl.y - tl.y;
editor_multiplier = 2;
let img = canvas.toDataURL({
format: 'png',
multiplier: editor_multiplier,
left: x,
top: y,
width: w,
height: h
}).replace(/^data:image\/[a-z]+;base64,/,'');
editor_multiplier = 1;
// img = img.replace(new RegExp("\n", "g"), ""); // убираем переносы
let canvas_obj = canvas.toJSON(['groupName', 'name', 'pointType', 'hasBorders', 'hasControls', 'originX', 'originY', 'lockScalingX', 'lockScalingY', 'fontWeight', 'perPixelTargetFind', 'visible', 'caption', 'caption_type', "scaleConstX", "scaleConstY", "length", "oldX", "oldY", "direction", "firstWidth", "firstHeight", "firstLeft", "firstTop", "zoom_size"]);
canvas_obj.width = canvas.width;
let data = JSON.stringify(canvas_obj);
data = data.replace(new RegExp("\\+", "g"), "%2B"); // заменяем на кодированный знак плюса,
//чтобы php скрипт не менял его на пробел
save(filename, data, img, callback, auto_save_flag);
}
function save(filename, data, img, callback, auto_save_flag){
formData = new FormData;
formData.append("data", data);
formData.append("filename", filename);
formData.append("img", img);
let sender = new XMLHttpRequest();
sender.open('POST', 'save.php', true);
sender.onreadystatechange = function() {
if(sender.readyState == 4)
{
if(sender.status == 200)
{
if(typeof window.connected != "undefined" && !window.connected){
alert("Соединение восстановлено");
}
if(callback != undefined){
callback();
}
else{
if(!auto_save_flag){
alert(sender.responseText);
}
else{
console.log("Сохранено");
}
let array = canvas.getObjects();
// board.style.cssText = "";
for(i in array){
array[i].excludeFromExport = !array[i].visible;
}
}
window.connected = true;
}
else{
if(typeof window.connected != "undefined" && window.connected){
alert("Соединение потеряно");
window.connected = false;
}
}
}
}
sender.send(formData);
}
// function checkState(destination_filename, callback, auto_save_flag)
// {
// if(destination_filename != filename){
// let sender = new XMLHttpRequest();
// sender.open('POST', 'check_state.php', true);
// sender.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// sender.onreadystatechange = function() {
// if(sender.readyState == 4)
// {
// if(sender.status == 200)
// {
// if(sender.responseText != 1){
// beforeSave(destination_filename, callback, auto_save_flag);
// }
// else{
// newName(destination_filename, function(result){doubleSource(result)});
// }
// }
// }
// }
// sender.send('filename=' + destination_filename);
// }
// else{
// beforeSave(destination_filename, callback, auto_save_flag);
// }
// }
// function newName(destination_filename, callback){
// let result = prompt("Файл с именем " + destination_filename + " редактируется другим пользователем. Введите другое имя (используйте буквы латинского и кириллического алфавита и знак подчеркивания)", "New_name");
// if (/[0-9A-Za-zА-Яа-я\_]+/.test(result) && result != null){
// callback(result);
// }
// else if(result != null){
// newName(destination_filename, callback);
// }
// }
// function saveBitmap(filename, img)
// {
// let sender = new XMLHttpRequest();
// sender.open('POST', 'saveBitmap.php', true);
// sender.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// sender.onreadystatechange = function() {
// if(sender.readyState == 4 )
// {
// if(sender.status == 200)
// {
// document.querySelector("#download").href=sender.responseText;
// document.querySelector("#download").click();
// }
// }
// }
// sender.send('img=' + img + '&filename=' + filename);
// }
function load(filename, data){
var form_data = new FormData();
form_data.append('filename', filename);
const promise = new Promise((resolve, reject) => {
sendData(form_data, address="load.php", resolve)
});
promise.then((response) => {
if(response != "Нет такого файла."){
let json = JSON.parse(response);
canvas.loadFromJSON(json, function(){
if(start_double_file){
doubleSource(input_filename.value + "_double", function(){
location.replace("editor.php?file_name="+filename+"_double");
});
}
file_loaded = true;
window.scene_loaded = true;
loadObjects();
shape_change_flag = false;
hideLens();
canvas.renderAll();
});
}
if(start_double_file){
board.style.display = "none";
}
})
}
if (editable_flag == 1){
file_loaded = false;
load(background_image);
}
else{
saveBackgroundImageToBase64(background_image);
}
async function saveBackgroundImageToBase64(background_image)
{
var res = await fetch(background_image, {})
var fileobj = await res.blob();
blobToBase64(fileobj).then(res => {
editor_obj.change_source(res);
if(top_panel_display != "none"){
add_legend_back(legend_back);
}
});
}
btn_save.addEventListener("click", function(){
var edited_path = input_filename.value;
edited_path = edited_path.replace(new RegExp("\\s", "g"), "_");
beforeSave(edited_path);
// checkState(edited_path);
});
setInterval(function(){
if(auto_save_flag){
var edited_path = input_filename.value;
edited_path = edited_path.replace(new RegExp("\\s", "g"), "_");
beforeSave(edited_path, undefined, auto_save_flag);
}
}, 20000);
// function saveInCicle(){
// checkState(input_filename.value, undefined, true);
// }
// setInterval(saveInCicle, 1000);
function doubleSource(filename, callback){
let double = true;
let array = canvas.getObjects();
for(var i = 0; i < array.length; i++){
array[i].excludeFromExport = true;
}
beforeSave(filename);
}
btn_saveBitmap.addEventListener("click", function(){//
if(top_panel_display != "none"){
let img = new Image();
canvas.backgroundImage.setCoords();
var coords = canvas.backgroundImage.oCoords;
let tl = coords.tl;
let bl = coords.bl;
let br = coords.br;
let x = tl.x;
let y = tl.y;
let w = br.x - bl.x;
let h = bl.y - tl.y;
editor_multiplier = 2;
img.src = canvas.toDataURL({
format: 'png',
multiplier: editor_multiplier,
left: x,
top: y,
width: w,
height: h
})
editor_multiplier = 1;
document.querySelector("#download").download = input_filename.value + ".png";
document.querySelector("#download").href = img.src;
document.querySelector("#download").click();
}
else{
document.querySelector("#download").download = input_filename.value.slice(0, -4) + ".png";
document.querySelector("#download").href = "images/preview/" + input_filename.value + ".png";
document.querySelector("#download").click();
}
});
let objects_arr = []; // массив составных объектов
// Составные объекты - это не группы fabric. Здесь каждый составной элемент перемещатся отдельно, либо вместе с ключевым,
// который записывается в массив shape
// Далее идет функция для создания составных объектов. Она сортирует все, что возвращает fabric по группам
// и создает составные объекты через методы editor_obj - это необходимо, потому что составной объект содержит в себе
// события, которые нельзя сохранить в файл и их нужно заново навешивать при создании объекта
function loadObjects(array){
let flag = false;
let legend_back;
if(array == undefined){
array = canvas.getObjects(); // получаем все объекты канваса
flag = true;
}
let param = [ // тип составных объектов, число объектов внутри составного объекта и метод, который его создает
{
regexp: /arrow.*/, // слово в названии группы составного объекта
amount: 3, // число объектов в составном объекте
event: add_arrow // метод, который его создаст и навесит события
},
{
regexp: /line.*/, // слово в названии группы составного объекта
amount: 3, // число объектов в составном объекте
event: add_line // метод, который его создаст и навесит события
},
{
regexp: /size.*/,
amount: 4,
event: add_size
},
{
regexp: /geometry.*/,
amount: 8,
event: add_geometry
},
{
regexp: /cap.*/,
amount: 3,
event: add_cap
},
{
regexp: /socket.*/,
amount: 8,
event: add_socket
}
]
// проверяем элементы массива array на соотвествие одному из типов param
let length = [];
for(let j = 0; j < param.length; j++){
for(let i = 0; i < array.length; i++){
setTimeout(function(){
array[i].setCoords();
}, 100)
if (array[i].groupName == "back-1"){
legend_back = array[i];
}
var id = param[j].regexp.exec(array[i].groupName); // узнаем имя группы объекта канваса - это будет id
if(length[id] == undefined){
length[id] = 0;
}
length[id]++;
if(Boolean(id)){ // если false, то объект не составной, а примитив fabric
if(objects_arr[id[0]] == undefined){ // делаем каждый элемент масссивом
objects_arr[id[0]] = []; // массив частей объекта, будет передаваться в метод отрисовки
// array[i].setCoords();
}
objects_arr[id[0]][array[i].name] = array[i]; // пушим найденный элемент в элмемент массива и называем его по id,
// дальше будем пушить туда все элементы array с тем же id
if(length[id] == param[j].amount){ // если набрали в массив столько элементов,
// сколько должно быть в составном объекте этого типа, создаем объект
let e = { // технический параметр с координатами мыши - нужен просто, чтобы вызвать метод
pointer: {
x: 0,
y: 0
}
};
param[j].event(e, objects_arr[id[0]]);
}
}
}
}
if(flag){
if(legend_back != undefined){
add_legend_back(legend_back);
}
else{
add_legend_back();
}
canvas.setWidth(canvas.width);
editor_obj.add_legend();
}
};