369 lines
15 KiB
JavaScript
369 lines
15 KiB
JavaScript
// 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();
|
||
}
|
||
}; |