modified: db.js

modified:   index.js
	modified:   object.js
	modified:   public/lib/fn.js
	new file:   public/lib/inter_group_object.js
	modified:   templates.js
	new file:   views/admin/objects/group_object copy.ejs
	new file:   views/admin/objects/group_object.ejs
	modified:   views/admin/objects/object_creation.ejs
	modified:   views/admin/objects/object_edit.ejs
	modified:   views/project.ejs
This commit is contained in:
n0rdye 2023-11-15 23:05:33 +00:00
parent 7c9f9226d1
commit 029ba9b1c3
11 changed files with 1723 additions and 13 deletions

2
db.js
View File

@ -1,6 +1,6 @@
const mysql = require('mysql');
const vars = require('./vars');
const db_host = "db";
const db_host = "localhost";
const admin = mysql.createConnection({
host: db_host,

View File

@ -203,6 +203,14 @@ app.get("/admin", (req,res) =>{try {
},true,true)
} catch (error) {route_err({req:req,error:error});}
});
app.get("/admin/group_object", (req,res) =>{try {
let inp = req.body;
let cook = req.cookies;
func.sid(cook,res,(rights)=>{
res.render('admin/objects/group_object');
},true,true)
} catch (error) {route_err({req:req,error:error});}
});
app.get("/admin/:type", (req,res) =>{try {
let inp = req.body;
let cook = req.cookies;
@ -213,7 +221,7 @@ app.get("/admin/:type", (req,res) =>{try {
else if ((req.params["type"] == "users") && (rights == 2 || rights == 3)){
res.render('admin/users');
}
else{res.redirect('/admin');}
// else{res.redirect('/admin');}
},true,true)
} catch (error) {route_err({req:req,error:error});}
});
@ -221,6 +229,26 @@ app.get("/get_logs", (req,res) => {
try{let cook = req.cookies;func.sid(cook,res,()=>{func.logs_file(res);})}
catch (error) {route_err({req:req,error:error});}
})
app.post("/admin/object/grouped/save", (req,res) => {
try{
let inp = req.body;
let cook = req.cookies;
// func.log(inp["name"]);
func.sid(cook,res,()=>{
obj.save_grouped(inp,cook,res);
},true,true)
} catch (error) {route_err({req:req,error:error});}
})
app.post("/admin/object/grouped/load", (req,res) => {
try{
let inp = req.body;
let cook = req.cookies;
// func.log(inp["name"]);
func.sid(cook,res,()=>{
obj.load_grouped(inp,cook,res);
},true,true)
} catch (error) {route_err({req:req,error:error});}
})
app.post("/admin/colors/new", (req,res) => {try{
let inp = req.body;
let cook = req.cookies;

View File

@ -11,7 +11,7 @@ module.exports.loads = (inp,cook,res)=>{
let gin
if (typeof inp["gid"] == 'undefined' || inp["gid"] == null) gin = "1 OR 1=1"
else gin = inp["gid"]
db.ggv("objects","`name`,`id`,`height`,`width`,`cost`,`gid`,`colors`,`pid`,`img`","gid",`${gin}`,(odata)=>{
db.ggv("objects","`name`,`id`,`height`,`width`,`cost`,`gid`,`colors`,`grouped`,`pid`,`img`","gid",`${gin}`,(odata)=>{
// func.log(odata);
res.send({out:"good",body:odata});
})
@ -35,6 +35,7 @@ module.exports.load = (inp,cook,res)=>{
module.exports.new = (inp,cook,res)=>{
try {
if (typeof inp["colors"] != 'undefined'){inp["colors"] = (inp["colors"] == "false")? 0:1;}
if (typeof inp["grouped"] != 'undefined'){inp["grouped"] = (inp["grouped"] == "false")? 0:1;}
db.gv("object_groups","id",`'${inp["gid"]}'`,(gname)=>{gname = gname[0]
db.gv("object_partition","id",`'${gname["pid"]}'`,(pname)=>{pname = pname[0]
save_img(inp["img"],`${inp["name"]}~g~${gname["name"]}~p~${pname["name"]}`,(img_path)=>{
@ -43,7 +44,7 @@ module.exports.new = (inp,cook,res)=>{
res.send({out:"bad",err:"name"});
}
else if (db_name[0] == null){
db.nr("objects","`cost`,`name`,`img`,`height`,`width`,`gid`,`colors`,`pid`",`'${inp["cost"]}','${inp["name"]}~g~${gname["name"]}~p~${pname["name"]}','${img_path}','${inp["height"]}','${inp["width"]}','${inp["gid"]}','${inp["colors"]}','${gname["pid"]}'`,true);
db.nr("objects","`cost`,`name`,`img`,`height`,`width`,`gid`,`colors`,`grouped`,`pid`",`'${inp["cost"]}','${inp["name"]}~g~${gname["name"]}~p~${pname["name"]}','${img_path}','${inp["height"]}','${inp["width"]}','${inp["gid"]}','${inp["colors"]}','${inp["grouped"]}','${gname["pid"]}'`,true);
db.sv("object_groups","count",`(count + 1)`,"id",inp["gid"],()=>{},true,true)
func.log(`admin object created name:${inp["name"]} group:${gname["name"]}`);
res.send({out:"good"});
@ -105,12 +106,37 @@ module.exports.load_colors = (inp,cook,res)=>{
}
}
module.exports.save_grouped = (inp,cook,res)=>{
try {
db.sv("objects","group_obj",inp["json"],"id",inp["id"],()=>{
let img = imageDataURI.decode(inp["data"]);
if (!fs.existsSync(`public/img/object/${inp["name"]}`)){fs.mkdirSync(`public/img/object/${inp["name"]}`);}
fs.writeFile(`public/img/object/${inp["name"]}/main.${img.imageType.split("/").at(-1)}`, img.dataBuffer,()=>{
res.send({body:"good"})
});
},true)
} catch (error) {
func.log("backend object creating error - "+error);
}
}
module.exports.load_grouped = (inp,cook,res)=>{
try {
db.ggv("objects","group_obj","id",`'${inp["id"]}'`,(odata)=>{
// func.log(odata);
res.send({out:"good",body:odata[0]});
},true)
} catch (error) {
func.log("backend object creating error - "+error);
}
}
module.exports.save = (inp,cook,res)=>{
try {
// let changed = [];
let changes = JSON.parse(inp["changes"]);
let taken_name = false;
if (typeof changes["colors"] != 'undefined'){changes["colors"] = (changes["colors"] == "false")? 0:1;}
if (typeof changes["grouped"] != 'undefined'){changes["grouped"] = (changes["grouped"] == "false")? 0:1;}
// console.log(changes);
Object.entries(changes).forEach(([key,value]) => {
// console.log(key,value);

View File

@ -363,6 +363,7 @@ async function removeImageBackground(image) {
// $.post( "/get_objs")
// .done(function( res ) {
// let wait_msg = msg("загрузка изображений",{type:"wait"})
// if(res["out"] == "good"){
// // console.log(res["body"]);
// let sources = [];
@ -373,6 +374,7 @@ async function removeImageBackground(image) {
// preloadImages(sources,()=>{
// // console.log("cached");
// callback();
// msg_del(wait_msg.id)
// // sources.forEach(element => {
// // console.log(element,is_cached(element));
// // });

View File

@ -0,0 +1,443 @@
window.dragMoveListener = dragMoveListener;
let root = document.getElementById("drags");
let objs = { height:"2",width:"4",color:"#FFFFFF"};
let objs_store = {};
let proj_from = "cloud";
let cur_obj;
let objs_back = [];
let objs_forw = [];
let proj_state = "loading";
let cm_mod = 2;
function create(clas,x,y,color = null,id,size,layer = 0){
let main_clas = clas.split(" ")[0];
// if (body == null || body == "") body = "[]";
let obj = document.createElement("img");
obj.id = id;
obj.alt = id;
clas= clas.split(" ");
clas.forEach(cl => {
obj.classList.add(cl);
});
get_obj(main_clas,(db_data)=>{
// console.log(db_data);
// console.log(db_data);
// db_data.forEach(db_data => {
// });
if (db_data == null) {
delete objs[main_clas];
reload();
// if(proj_from == "cloud"){
// // save(()=>{
// // // goto("/proj/load/"+proj_name);
// // },false);
// }
// else if (proj_from == "local"){
// save_local();
// load_proj_local();
// }
}
else if (db_data != null){
make(objs_store[main_clas]["img"])
}
function make(img){
// console.log(db_data);
obj.src = img;
obj.title = `${db_data["name"].replaceAll("$"," ").split("~g")[0]}\nцена:${db_data["cost"]}\nширина:${db_data["width"]}см высота:${db_data["height"]}см`;
obj.setAttribute("cost",db_data["cost"])
obj.setAttribute("colors",Boolean(db_data["colors"]))
obj.setAttribute("data-img",img)
obj.setAttribute("gid",db_data["gid"])
obj.setAttribute("pid",db_data["pid"])
obj.setAttribute("color",color)
// drag.transform = `translate(${drag.getAttribute("data-y")}px, ${drag.getAttribute("data-y")}px) scale(${db_data["width"] * cm_mod} ${db_data["height"] * cm_mod})`;
if(size){
obj.style.width = `${db_data["width"] * cm_mod}px`;
obj.style.height = `${db_data["height"] * cm_mod}px`;
}
if (color != null){
obj_color_change(color,obj)
}
}
calc_total();
})
obj.setAttribute("decoding","async");
obj.setAttribute("loading","lazy");
if(id != "none"){obj.setAttribute("onclick",`obj_click("${id}")`);}
// console.log(main_clas);
if(main_clas.split("~p~").at(-1) == "Бизиборды"){
obj.setAttribute("layer",9999);
obj.style.zIndex = 9999;
}
else{
obj.setAttribute("layer",layer);
obj.style.zIndex = layer;
}
root.append(obj);
set_pos(obj,x,y);
}
function obj_click(id){
if (cur_obj != id){
let obj = document.getElementById(id);
let cur_layer = obj.style.zIndex;
cur_obj = id;
if(cur_layer=="9999"){
document.getElementsByClassName("layer_changer")[0].style.pointerEvents = "none";
document.getElementById("layer_inp").value = "-";
}
else{
document.getElementsByClassName("layer_changer")[0].style.pointerEvents = "all";
document.getElementById("layer_inp").value = cur_layer;
}
if (obj.getAttribute("colors") == "true"){
clear_palette();
obj_colors_load(()=>{
document.getElementById("obj_color_div").style.display = "flex";
if( document.getElementById(`color_${obj.getAttribute("color")}`) != null){
document.getElementById(`color_${obj.getAttribute("color")}`).style.border = "1px blue solid"
}
});
}
else{
document.getElementById("obj_color_div").style.display = "none";
}
obj_selection();
// console.log(obj.);
}
}
function obj_selection(clear = false){
cur_obj = (clear == true)? null:cur_obj;
let drags = document.getElementsByClassName("drag");
Object.values(drags).forEach(element => {
// console.log(element.id,cur_obj);
if (element.id != cur_obj){
element.style.border = "0px";
}
else{
element.style.border = "2px black solid";
element.style.borderRadius = "0.2vw";
}
});
}
function resize_drags(){
document.getElementById('drags').setAttribute("data-x",document.getElementsByClassName("wall")[0].getBoundingClientRect().left.toString()+"px");
document.getElementById('drags').style.left = document.getElementsByClassName("wall")[0].getBoundingClientRect().left.toString()+"px";
document.getElementById('drags').style.width = document.getElementsByClassName("wall")[0].style.width;
document.getElementsByClassName("zones")[0].style.height = document.getElementsByClassName("wall")[0].style.height;
drag_start();
}
function wall_size_change(type,value = null){
if (proj_state == "loaded"){objs_back.push(JSON.parse(JSON.stringify(objs)));}
let wall = document.getElementsByClassName("wall")[0];
let drags = document.getElementById("drags");
let scroll;
if(type != null && type == "width") {
if (value == null) scroll = parseFloat(document.getElementById("wall_width").value);
else if (value != null) scroll = value;
// document.getElementById("wall_width_value").innerHTML = (Math.ceil((parseFloat(scroll)+0.1)*10)/ 10);
// document.getElementById("wall_width_value").innerHTML = `${scroll}м`;
// console.log(scroll);
wall.style.width = `${(scroll * 100) * cm_mod}px`;
wall.style.left = drags.getBoundingClientRect().left;
objs["width"] = scroll;
}
if(type != null && type == "height") {
if (value == null) scroll = parseFloat(document.getElementById("wall_height").value);
else if (value != null) scroll = value;
// document.getElementById("wall_height_value").innerHTML = (Math.ceil((parseFloat(scroll)+0.1)*10)/ 10);
// document.getElementById("wall_height_value").innerHTML = `${scroll}м`;
// console.log(scroll);
wall.style.height = `${(scroll * 100) * cm_mod}px`;
objs["height"] = scroll;
}
}
function calc_total(start = false){
document.getElementById("cost_list").innerHTML = ""
if (start) {
document.getElementById("proj_cost_text").innerText = `Стоимость: ${objs["total"]} руб.`;
return;
}
let total=0;
Object.entries(objs).forEach(([key,value]) => {
// console.log(key);
if(key != "height"&&key!="width"&key!="total"){
// console.log(Object.keys(value).length);
// console.log(objs_store[key]);
if(objs_store[key] != null && objs_store[key]["cost"] > 0 && JSON.parse(document.getElementById(`group_drop-${objs_store[key]["pid"]}`).getAttribute("no-cost")) == false){
// console.log(key,value);
total += parseInt(parseInt(objs_store[key]["cost"]) * Object.keys(value).length);
let obj_cost_div = document.createElement("li");
obj_cost_div.innerHTML =
`<div style="display:flex;"> ` +
`<div id='obj_cost_name' style='font-size:calc(var(--main-font-size)/1);'>${key.split("~g~")[0].replaceAll("$"," ")}`+
`<div id='obj_cost_count'>&nbsp${Object.keys(value).length}X</div> </div>`+
`</div>`+
`<div id='obj_cost'>${parseInt(parseInt(objs_store[key]["cost"]) * Object.keys(value).length)}</div>`;
document.getElementById("cost_list").append(obj_cost_div);
}
}
// console.log(Object.keys(objs).at(-1));
});
// return total;
objs["total"] = total;
document.getElementById("proj_cost_text").innerText = `стоимость: ${total} руб.`;
}
function load(objss){
proj_state = "loading";
// objs = JSON.parse($.cookie("objs"));
// console.log(objs);
objs = objss;
Object.entries(objs).forEach(([keys, values]) => {
// console.log(keys,values);
if (keys != "width" && keys != "height" && keys != "color" && keys != "grided"){
Object.entries(values).forEach(([key, value]) => {
if(key != "class"){
// console.log(key,keys);
// console.log(keys,value["x"],value["y"],value["body"]);
// let count = Object.keys(objs[keys]).length;
// console.log(count);
create(keys+" drag",value["x"],value["y"],value["color"],key,true,value["layer"]);
}
})
}
else {
document.getElementById(`wall_${keys}`).value = values;
wall_size_change(keys,values);
// document.getElementById("drags").style.left = $(".dropzone")[0].getBoundingClientRect().x;
}
if (keys == "color"){
document.getElementById("wall").style.backgroundColor = values;
}
if (keys == Object.keys(objs).at(-1)){
proj_state = "loaded";
loaded();
}
});
resize_drags();
}
function reload(save = false){
// objs = JSON.parse($.cookie("objs"));
// console.log(objs);
document.getElementById("drags").innerHTML = "";
load(objs);
if(save){save(()=>{},false)}
}
// function load_proj_cloud(){
// proj_from = "cloud";
// document.getElementById("drags").innerHTML = "";
// // document.getElementById("top_panel_center").innerText = `загрузка ${proj_name} из облака`;
// $.post( "/load_proj",{name:proj_name})
// .done(function( res ) {
// if(res["out"] == "good"){
// // console.log("good");
// // console.log(JSON.parse(`'${res["body"]}'`));
// // console.log(JSON.parse(res["body"]));
// // $.cookie("objs",res["body"]);
// load(JSON.parse(res["body"]));
// // document.getElementById("top_panel_center").innerText = `${proj_name} (облако)`;
// }
// else if(res["out"] == "bad proj"){
// // console.log("bad");
// save(()=>{
// goto("/proj/load/"+proj_name);
// },false);
// }
// })
// }
// function save(callback,with_pic = true){
// // console.log(objs);
// proj_from = "cloud";
// if(with_pic){
// proj_img((src)=>{
// make_save(src);
// })
// }
// else{
// make_save();
// }
// function make_save(src = "img/img_placeholder.webp"){
// $.post( "/save_proj", {proj:JSON.stringify(objs),name:proj_name,img:src})
// .done(function( res ) {
// if(res["out"] == "good"){
// // console.log(scr)
// // console.log("good");
// if(callback) callback(res);
// }
// })
// }
// }
function load_objs(callback,group){
// let select = document.getElementById("group_select");
// console.log(group);
$.post( "/get_objs",{gid:group})
.done(function( res ) {
if(res["out"] == "good"){
// console.log(res["body"]);
res["body"].forEach(element => {
objs_store[`${element["name"]}`] = {img:element["img"],height:element["height"],width:element["width"],id:element["id"],name:element["name"],cost:element["cost"],colors:element["colors"],gid:element["gid"],pid:element["pid"]}
});
callback(res["body"]);
}
});
}
function get_obj(clas,callback){
if(objs_store[clas] != null){
callback(objs_store[clas]);
}
else{
load_objs(()=>{
callback(objs_store[clas]);
})
}
}
function load_obj(name,key,callback){
$.post( "/get_obj",{name:name,key:key})
.done(function( res ) {
if(res["out"] == "good"){
// console.log(res["body"]);
callback(res["body"]);
}
});
}
function dragMoveListener (event) {
var drag = event.target
if(drag.id != "none"){obj_click(drag.id)}
var x = (parseFloat(drag.getAttribute('data-x')) || 0) + event.dx
var y = (parseFloat(drag.getAttribute('data-y')) || 0) + event.dy
set_pos(drag,x,y);
}
let dragzone = document.getElementsByClassName('wall')[0];
interact('.drag').draggable({
inertia: true,
modifiers: [
interact.modifiers.restrictRect({restriction: dragzone,endOnly: true,elementRect:{ left: 0.15, right: 0.85, top: 0, bottom: 1 }}),
interact.modifiers.snap({targets: [interact.snappers.grid({ x: cm_mod, y: cm_mod })],range: Infinity,relativePoints: [ { x: 0, y: 0 } ]}),
],
autoScroll: true,
listeners: {move: dragMoveListener, end (event) {}}
})
// interact('.trash').dropzone({
// accept: '.drag',
// overlap: 0.2,
// ondragenter: function (event) {var drag = event.relatedTarget;var zone = event.target;
// // console.log(drag.classList);
// if(objs[drag.classList[0]] != null&&objs[drag.classList[0]][drag.id] != null) {
// delete objs[drag.classList[0]][drag.id];
// }
// calc_total()
// zone.classList.add('drop-target');drag.classList.add('can-drop');
// drag.remove();
// },
// ondragleave: function (event) {var drag = event.relatedTarget;var zone = event.target;zone.classList.remove('drop-target');drag.classList.remove('in_zone');drag.classList.remove('can-drop');},
// ondrop: function (event) {var drag = event.relatedTarget;
// // console.log(drag.id);
// // console.log(objs);
// drag.classList.add('in_zone');drag.classList.remove('can-drop');
// },
// ondropdeactivate: function (event) {var zone = event.target;zone.classList.remove('drop-active');zone.classList.remove('drop-target');}
// })
interact('.dropzone').dropzone({
accept: '.drag',
overlap: 0.5,
ondragenter: function (event) {var drag = event.relatedTarget;var zone = event.target;
if (objs[drag.classList[0]] == null){
objs[drag.classList[0]] = {};
}
if(drag.id == "none") drag.id = get_id(drag.classList[0]);
if (objs[drag.classList[0]][drag.id] == null){
objs[drag.classList[0]][drag.id] = {};
drag.setAttribute("onclick",`obj_click("${drag.id}")`);
calc_total()
}
zone.classList.add('drop-target');drag.classList.add('can-drop');
},
ondragleave: function (event) {var drag = event.relatedTarget;var zone = event.target;zone.classList.remove('drop-target');drag.classList.remove('in_zone');drag.classList.remove('can-drop');},
ondrop: function (event) {var drag = event.relatedTarget
if (proj_state == "loaded"){objs_back.push(JSON.parse(JSON.stringify(objs)));}
objs[drag.classList[0]][drag.id] = {y:drag.getAttribute('data-y'),x:drag.getAttribute('data-x'),body:drag.innerHTML,color:drag.getAttribute("color"),layer:drag.getAttribute('layer')};
drag.classList.add('in_zone');drag.classList.remove('can-drop');
// console.log(objs["KeyBoard~g~не$основное"]["KeyBoard~g~не$основное_1"]);
},
ondropdeactivate: function (event) {var zone = event.target;zone.classList.remove('drop-active');zone.classList.remove('drop-target');}
})
interact('.createzone').dropzone({
accept: '.spawn',
overlap: 0.2,
ondragenter: function (event) {var drag = event.relatedTarget;var zone = event.target;
zone.classList.add('drop-target');drag.classList.add('can-drop');
},
ondragleave: function (event) {var drag = event.relatedTarget;var zone = event.target;
if(drag.classList[1] == "spawn" && drag.classList[0] == zone.classList[0]){
get_obj(drag.classList[0],(db_data)=>{
// drag.transform = `translate(${drag.getAttribute("data-y")}px, ${drag.getAttribute("data-y")}px) scale(${db_data["width"] * cm_mod} ${db_data["height"] * cm_mod})`;
drag.style.width = `${db_data["width"] * cm_mod}px`;
drag.style.height = `${db_data["height"] * cm_mod}px`;
// console.log(db_data);
})
let x = zone.getBoundingClientRect().left - document.getElementById("drags").getBoundingClientRect().left;
let y = zone.getBoundingClientRect().top - document.getElementById("drags").getBoundingClientRect().top;
create(`${zone.classList[0]} spawn drag`,x,y,null,`none`,false,0);
if (proj_state == "loaded"){objs_back.push(JSON.parse(JSON.stringify(objs)));}
drag.classList.remove('spawn');
}
zone.classList.remove('drop-target');
},
ondrop: function (event) {var drag = event.relatedTarget;
drag.classList.remove('in_zone');drag.classList.remove('can-drop');},
ondropdeactivate: function (event) {var zone = event.target;
zone.classList.remove('drop-active');zone.classList.remove('drop-target');}
})
function drag_start() {
let spawns = document.getElementsByClassName("spawn");
Object.entries(spawns).forEach(([key, spawn]) => {
spawn.parentElement.removeChild(spawn);
});
let zones = document.getElementsByClassName("createzone");
Object.entries(zones).forEach(([key, zone]) => {
let x = zone.getBoundingClientRect().left - document.getElementById("drags").getBoundingClientRect().left;
let y = zone.getBoundingClientRect().top - document.getElementById("drags").getBoundingClientRect().top;
create(`${zone.classList[0]} spawn drag`,x,y,null,`none`,false,0);
});
}
function get_id(clas){
if(objs[clas] == null){ return `${clas}_0`}
else{
let count = Object.keys(objs[clas]).length;
return `${clas}_${count}`;
}
}

View File

@ -6,7 +6,7 @@ const vars = require('./vars');
module.exports.load = (inp,cook,res)=>{
try {
db.gv("templates","name",`'${inp["name"]}'`,(pdata)=>{pdata = pdata[0];
console.log(pdata);
// console.log(pdata);
if (pdata != null){
res.send({out:"good",body:pdata["body"]});
}

View File

@ -0,0 +1,582 @@
<%- include('../../static/start.ejs',{name:"",async:true}) %>
<%- include('../../header.ejs') %>
<script src="/lib/interact.js"></script>
<script src="/lib/html2canvas.js"></script>
<style>
.drag{
height: 5vw;
width: 5vw;
position: absolute;
text-align: center;
margin: auto;
z-index: 10;
touch-action: none;
}
#drags{
position: absolute;
margin: auto;
}
.spawn{
object-fit: contain;
}
.zones{
margin-block: 10px;
}
.wall {
/* border: dashed 4px transparent; */
border-radius: 4px;
transition: background-color 0.3s;
position: absolute;
inset: 0px;
margin: 5px auto;
width: 400px;
height: 200px;
background-color: #fff;
/* background-image: url("/img/bg1red.png"); */
background-size: 200px;
background-repeat: repeat;
background-position: bottom 0px left 0px;
border: 2px solid black;
/* overflow: visible; */
z-index: -1;
}
.createzone {
background-color: #bfe4ff;
border: dashed 4px transparent;
border-radius: 0.4vw;
height: 3vw;
width: 3vw;
margin: 10px;
margin-top: 0px;
padding: 0.8vw;
transition: background-color 0.3s;
}
.trash {
background-color: #bfe4ff;
border: dashed 4px transparent;
border-radius: 4px;
/* margin: 10px auto 30px; */
/* padding: 10px; */
height: 50px;
width: 50px;
transition: background-color 0.3s;
text-align: center;
/* z-index: -1; */
}
.czones{
display: flex;
margin: 0px auto;
margin-top: 3vh;
/* justify-content: space-around; */
flex-wrap: wrap;
width: 75%;
height: 40vh;
/* overflow-x: auto; */
}
.drop-active {
border-color: #aaa;
}
/* .drop-target {
background-color: #29e;
border-color: #fff;
border-style: solid;
} */
#proj_top{
margin: auto;
width: 90%;
display: flex;
justify-content: space-around;
}
#proj_name{
background-color: #aaa;
border: 0px;
text-align: center;
}
.inputs{
display: flex;
width: 80vw;
margin: auto;
padding-block: 20px;
padding-bottom: 0px;
/* margin-top: 50px; */
}
#group{
display: none;
position: absolute;
padding: 0px;
margin: 0px;
}
</style>
<div id="project_menu" class="cmenu">
<button id='proj_csave_btn' onclick='save_proj()'>сохранить в облако</button> <br>
<!-- <button id='proj_cload_btn' onclick='load_proj_cloud()'>загрузить из облака</button> <br> -->
<!-- <button id='proj_lsave_btn' onclick='save_proj_local()'>сохранить на локальное хранилище</button> <br>
<button id='proj_lload_btn' onclick='load_proj_local()'>загрузить из локальное хранилище</button> <br> -->
<!-- <button id='proj_del_btn' onclick='del_proj()'>удалить проект</button> <br> -->
</div>
<!-- <div class="dropzone"></div> -->
<div class="inputs">
<div id="wall_input" style="display: flex;justify-content: space-between;width: 95%;margin-left: 20px;">
<div style="display: flex;width: 16vw;justify-content: space-between;">
<label for="wall_height" style="margin: auto;">Высота стены</label>
<input type="text" id="wall_height" style="width: 5vw; text-align: center; border-radius: 0.5vw; border: 1px solid gray;" value="2" oninput="this.value = this.value.replace(/[^0-9.]/g, '0').replace(/(\..*?)\..*/g, '$1').replace(/^0[^.]/, '0');wall_size_change('height');resize_drags();">
<label for="wall_width" style="margin: auto;">М.</label>
</div>
<div style="display: flex;width: 16vw;justify-content: space-between;">
<label for="wall_width" style="margin: auto;">Длина стены</label>
<input type="text" id="wall_width" style="width: 5vw; text-align: center; border-radius: 0.5vw; border: 1px solid gray;" value="4" oninput="this.value = this.value.replace(/[^0-9.]/g, '0').replace(/(\..*?)\..*/g, '$1').replace(/^0[^.]/, '0');wall_size_change('width');resize_drags();">
<label for="wall_width" style="margin: auto;">М.</label>
</div>
<div style="display: flex;width: 16vw;justify-content: space-between;">
<label for="wall_color" style="margin: auto;">Цвет стены</label>
<input type="color" id="wall_color" style="width: 5vw; border-radius: 0.5vw; border: 1px solid gray; min-height: 3.9vw;" value="#FFFFFF" onchange="wall_color_change()">
</div>
<div id="cost_div" style="display: flex;width: 15vw;justify-content: space-between;">
<button id="proj_cost" class="menu_btn" style="width: 100%;z-index: 3;">
<div id="proj_cost_text" style="pointer-events: none;">Расчет стоимости</div>
<img src="/img/drop.png" style="width: 1vw;height: 0.5vw;pointer-events: none;" alt="\/">
</button>
<style>
#cost_list li{
display: flex;
justify-content: space-between;
width: 14vw;
padding-block: 0.4vw;
}
#cost_list{
list-style-type: none;
padding-left: 0px;
margin-top: 59px;
position: absolute;
width: 14vw;
padding: 0.45vw;
}
</style>
<ul id="cost_list" class="cmenu">
</ul>
<!-- <div style="display: flex;"><div id="proj_cost"></div>&nbsp;руб.</div> -->
</div>
<!-- <div style="display: flex;width: 150px;justify-content: space-between;">
<label style="margin: auto;">Расчёт стоимости</label>
</div> -->
</div>
<!-- <img class="trash" style="height: 100px; width: 100px;" src="/img/shadow-energy.gif" alt="чёрная дыра"> -->
</div>
<div class="zones" style="position: relative;">
<div id="drags">
</div>
<div class="wall dropzone" id="wall"></div>
</div>
<div style="display:flex; justify-content: space-around;"></div>
<div class="inputs" style="display: flex;justify-content: space-between;height: 5vh;">
<div id="obj_color_div" style="justify-content: space-evenly; width: 50vw;display: none;transform: translateX(30%);">
<label for="obj_colors" style="min-width: 10vw;">цвет объекта</label>
<div id="obj_colors" style="display: flex; width: 30vw;overflow: auto;height: 50px;"></div>
<!-- <input id="obj_color" type="color" onchange="obj_color_change(event)"> -->
</div>
</div>
<div class="inputs" style="display: flex;justify-content: space-between;">
<style>
.btn_icon{
border: 1px solid gray;
border-radius: 0.5vw;
padding: 0.5vw;
height: 2vw;
width: 2vw;
cursor: pointer;
}
.btn_icon img{
height: 2vw;
width: 2vw;
}
</style>
<div style="display: flex;justify-content: space-between; width: 35vw;">
<div class="btn_icon"><img src="/img/icon/copy.png" alt="copy"></div>
<div class="btn_icon" onclick="go_back()"><img src="/img/icon/back.png" alt="back"></div>
<div class="btn_icon" onclick="go_forw()"><img src="/img/icon/forw.png" alt="forw"></div>
<div class="btn_icon" onclick="obj_del()"><img src="/img/icon/del.png" alt="del"></div>
<div class="layer_changer">
<div class="btn_icon layer_btn" onclick="obj_change_layer('up')"><img src="/img/icon/up.png" alt="up"></div>
<input id="layer_inp" type="number" oninput="obj_change_layer('inp')">
<div class="btn_icon layer_btn" onclick="obj_change_layer('down')"><img src="/img/icon/down.png" alt="down"></div>
</div>
<style>
#layer_inp{
width: 2vw;
appearance: textfield;
text-align: center;
border: 0px;
}
.layer_btn{
border: 0px;
}
.layer_changer{
display: flex;
background-color: white;
border: 1px gray solid;
border-radius: 0.5vw;
}
</style>
</div>
<div style="display: flex;justify-content: space-between; width: 15vw;">
<div><input type="checkbox" id="grid_checkbox" checked="true" onchange='grid_view(JSON.parse(event.target.checked));'><label for="grid_checkbox">Показывать сетку</label></div>
</div>
<div style="display: flex;justify-content: space-between; width: 7vw;">
<div id="save_btn_icon" class="btn_icon" onclick="save_proj()"><img src="/img/icon/save.png" alt="save"></div>
<div class="btn_icon" onclick="img_download()"><img src="/img/icon/download.png" alt="load"></div>
<!-- <div class="btn_icon" onclick="document.getElementById('import_file').click();"><img src="/img/icon/download.png" alt="load"></div> -->
<!-- <input type='file' id="import_file" style="display: none;" accept="application/JSON" onchange='openFile(event,load_file)'> -->
</div>
</div>
<div class="inputs" style="display: flex;justify-content: space-between;margin-top: 0px;">
<div id="obj_group" style="display: flex;justify-content:space-evenly; width: 100vw;">
<!-- <button name="" id="group_drop" >Помехи на стене</button> -->
<style>
.obj_group{
/* width: 100%; */
display: flex;
padding-block: 0.3vw;
}
.obj_group label{
width: 90%;
/* padding-inline: 0.3vw; */
}
.group_drop{
width: 15vw;
padding: 2px;
min-width: 15vw;
}
.group_drop *{
pointer-events: none;
overflow: auto;
}
.group_drop img{
width: 1vw;
height: 0.5vw;
}
</style>
<div id="obj_parts" style="min-width: 50vw;display: flex;justify-content: space-evenly;">
</div>
<style>
.group_inp{
height: 1vw;
width: 1vw;
border: 0px;
border-radius: 0.4vw;
overflow: auto;
}
</style>
<ul id="group" class="cmenu"></ul>
</div>
</div>
<div class="czones"></div>
<script src="/lib/inter_group_object.js"></script>
<script>
document.getElementById("layer_inp").value = 0;
img_cache(()=>{})
if ( $.cookie("grid") != null){
document.getElementById("grid_checkbox").checked = JSON.parse($.cookie("grid"));
grid_view(JSON.parse($.cookie("grid")))
}else{
$.cookie("grid",true)
document.getElementById("grid_checkbox").checked = true;
grid_view(true)
}
function grid_view(check){
let grid = document.getElementsByClassName("wall")[0]
console.log(check);
if (check == false) {
grid.style.backgroundImage = "";
$.cookie("grid",false);
}
else{
grid.style.backgroundImage = 'url("/img/bg1red.png")';
$.cookie("grid",true);
}
}
function img_download(){
msg("добавить на фото стоимость?",{type:"ask",res:(out)=>{
let wait_msg = msg("делаем фото",{type:"wait"})
proj_img((src)=>{
msg("изображение проекта готово",{time:3})
msg_del(wait_msg.id)
downloadImg(src,`${proj_name}.png`)
},out)
}})
}
function proj_img(callback,cost = false){
obj_selection(true)
let width = (parseInt(document.getElementById("wall").style.width))
document.getElementById("drags").append(document.getElementById("wall"));
document.getElementById("drags").style.height = document.getElementById("wall").style.height;
document.getElementById("cost_list").style.left = "";
Object.values(document.getElementsByClassName("spawn")).forEach((spawn)=>{
spawn.src = "";
})
if(cost == true){
width += document.getElementById("proj_cost").getBoundingClientRect().width;
document.getElementById("drags").append(document.getElementById("cost_div"));
document.getElementById("cost_div").style.marginLeft = `${parseInt(document.getElementById("wall").style.width) + 4}px`;
document.getElementById("cost_list").style.display = "block";
}
html2canvas(document.getElementById("drags"),{
y:7,
x:2,
width:width,
logging:false,
scale:5
}).then(canvas => {
if(cost == true){
document.getElementById("cost_div").style.marginLeft = `0`;
document.getElementById("cost_list").style.display = "none";
document.getElementById("wall_input").append(document.getElementById("cost_div"));
}
document.getElementsByClassName("zones")[0].append(document.getElementById("wall"));
let src = "";
src = canvas.toDataURL();
// console.log(src);
callback(src)
drag_start();
});
}
function obj_colors_load(callback) {
let div = document.getElementById("obj_colors");
div.innerHTML = "";
load_colors((colors)=>{
Object.entries(colors).forEach(([key,value]) => {
// console.log(value);
let color_div = document.createElement("div");
color_div.style = `background-color: #${value["color"]}; border-radius: 50%;height: 2vw;min-width: 2vw;margin-inline: 0.5vw;`;
color_div.classList.add("color_palette");
color_div.id=`color_${value["color"]}`;
color_div.setAttribute("color",`${value["color"]}`)
color_div.setAttribute("onclick",`clear_palette();document.getElementById('color_${value["color"]}').style.border = "1px blue solid";obj_color_change('${value["color"]}')`)
color_div.title = `#${value["color"]}`;
div.append(color_div);
if(key = Object.keys(colors).at(-1)){
if(callback)callback();
}
});
})
}
function obj_color_change(color,in_obj = null){
if(color != "null"){
if (proj_state == "loaded"){objs_back.push(JSON.parse(JSON.stringify(objs)));}
let obj = (in_obj == null)? document.getElementById(cur_obj):in_obj;
// console.log(color);
color_change(color,obj.getAttribute("data-img"),(img)=>{
obj.src = img;
obj.setAttribute("color",color)
objs[obj.classList[0]][obj.id]["color"] = color;
});
}
}
function go_back(){
if(objs_back.length > 0){
objs_forw.push(objs);
objs = objs_back.at(-1);
objs_back.pop();
reload();
calc_total();
}
}
function go_forw(){
if(objs_forw.length > 0){
objs_back.push(objs);
objs = objs_forw.at(-1);
objs_forw.pop();
reload();
calc_total();
}
}
function obj_change_layer(type) {
let obj = document.getElementById(cur_obj);
if(obj != null){
let cur_layer = obj.style.zIndex;
if (type == "up" && cur_layer < 10000){
let new_layer = parseInt(cur_layer) + 1;
objs[obj.classList[0]][obj.getAttribute("id")].layer = new_layer;
obj.style.zIndex = new_layer;
obj.setAttribute("layer",new_layer);
document.getElementById("layer_inp").value = new_layer;
} else if (type == "down" && cur_layer > 0){
let new_layer = parseInt(cur_layer) - 1;
objs[obj.classList[0]][obj.getAttribute("id")].layer = new_layer;
obj.style.zIndex = new_layer;
obj.setAttribute("layer",new_layer);
document.getElementById("layer_inp").value = new_layer;
}
else if ((type == "inp")){
let inp_val = parseInt(document.getElementById("layer_inp").value);
if(inp_val >= 0 && inp_val < 10000){
objs[obj.classList[0]][obj.getAttribute("id")].layer = inp_val;
obj.style.zIndex = inp_val;
}
else{
document.getElementById("layer_inp").value = cur_layer;
}
}
}
// console.log(objs[obj.classList[0]][obj.getAttribute("id")]);
}
function obj_del(){
if (proj_state == "loaded"){objs_back.push(JSON.parse(JSON.stringify(objs)));}
document.getElementById("layer_inp").value = 0;
try{
let drag = document.getElementById(cur_obj);
if(drag.id != "none"){
console.log(cur_obj);
// console.log(drag.classList);
if(objs[drag.classList[0]] != null&&objs[drag.classList[0]][drag.id] != null) {
console.log(objs[drag.classList[0]]);
delete objs[drag.classList[0]][drag.id];
if (Object.keys(objs[drag.classList[0]]).length < 1){
delete objs[drag.classList[0]];
}
}
calc_total()
drag.remove();
document.getElementById("obj_color_div").style.display = "none";
cur_obj = null;
}
}
catch{msg("объект не выбран")}
}
function group_drop(){
let e = document.getElementById("group_drop")
setTimeout(()=>{
document.getElementById("group").style.display = "block";
// document.getElementById("group").style.left = document.getElementById("group_drop").getBoundingClientRect().left;
let childs = document.getElementById("group").getElementsByTagName("input");
let i = 0;
Object.entries(childs).forEach(([key,value]) => {
console.log(key,value);
if(value.checked == true){
get_objs(value)
i++;
}
if (i==0){
// document.getElementsByClassName("czones")[0].innerHTML = "";
drag_start()
// e.removeChild(e.getElementsByClassName(value))
}
});
},1)
}
load_parts((db)=>{
let parts = document.getElementById("obj_parts");
Object.values(db).forEach((value)=>{
let part = document.createElement("button")
let part_text = document.createElement("div")
let part_drop = document.createElement("img")
part_drop.src = "/img/drop.png";
part_drop.alt = "\/";
part_text.innerText = `${value["name"].replaceAll("$", " ")}`;
part.id = `group_drop-${value["id"]}`;
part.classList.add("menu_btn")
part.classList.add("group_drop")
part.setAttribute("groups",`${value["groups"]}`)
part.setAttribute("count",`${value["count"]}`)
part.setAttribute("no-cost",`${value["no-cost"]}`)
part.setAttribute("pid",`${value["id"]}`)
part.append(part_text);
part.append(part_drop);
parts.append(part);
console.log(value);
})
})
function wall_color_change(){
if (proj_state == "loaded"){objs_back.push(JSON.parse(JSON.stringify(objs)));}
let wall = document.getElementById("wall")
let color = document.getElementById("wall_color")
wall.style.backgroundColor = color.value;
objs["color"] = color.value;
}
function gids_change(){
get_objs();
drag_start()
}
function get_groups(callback){
// let select = document.getElementById("group");
// let name = select.options[select.selectedIndex].text;
load_groups(callback(),gids);
}
// get_groups(()=>{
// get_objs();
// });
function get_objs(group_div){
document.getElementsByClassName("czones")[0].innerHTML = "";
gids.forEach(group => {
load_objs((data)=>{
data.forEach(value => {
let czones = document.getElementsByClassName("czones")[0];
let czone = document.createElement('div');
czone.classList.add(value["name"]);
czone.classList.add("createzone");
czones.append(czone)
});
drag_start()
},group)
});
drag_start()
}
// console.log(proj_name);
// let menu = document.getElementById("project_menu");
// document.getElementById("top_panel_left").innerHTML = `<div id='proj_menu' class="menu_btn">настройки проекта</div>`;
// drag_start();
// console.log(px_ratio);
$(window).resize(function(){isZooming();});
function isZooming(){
resize_drags();
}
setTimeout(()=>{loaded()},500);
</script>
<%- include('../../static/end.ejs',{soc:true}) %>

View File

@ -0,0 +1,595 @@
<%- include('../../static/start.ejs',{name:"",async:true}) %>
<%- include('../../header.ejs') %>
<script src="/lib/interact.js"></script>
<script src="/lib/html2canvas.js"></script>
<style>
.drag{
height: 5vw;
width: 5vw;
position: absolute;
text-align: center;
margin: auto;
z-index: 10;
touch-action: none;
}
#drags{
position: absolute;
margin: auto;
}
.spawn{
object-fit: contain;
}
.zones{
margin-block: 10px;
}
.wall {
/* border: dashed 4px transparent; */
border-radius: 4px;
transition: background-color 0.3s;
position: absolute;
inset: 0px;
margin: 5px auto;
width: 400px;
height: 200px;
background-color: #fff;
/* background-image: url("/img/bg1red.png"); */
background-size: 200px;
background-repeat: repeat;
background-position: bottom 0px left 0px;
border: 2px solid black;
/* overflow: visible; */
z-index: -1;
}
.createzone {
background-color: #bfe4ff;
border: dashed 4px transparent;
border-radius: 0.4vw;
height: 3vw;
width: 3vw;
margin: 10px;
margin-top: 0px;
padding: 0.8vw;
transition: background-color 0.3s;
}
.trash {
background-color: #bfe4ff;
border: dashed 4px transparent;
border-radius: 4px;
/* margin: 10px auto 30px; */
/* padding: 10px; */
height: 50px;
width: 50px;
transition: background-color 0.3s;
text-align: center;
/* z-index: -1; */
}
.czones{
display: flex;
margin: 0px auto;
margin-top: 3vh;
/* justify-content: space-around; */
flex-wrap: wrap;
width: 75%;
height: 40vh;
/* overflow-x: auto; */
}
.drop-active {
border-color: #aaa;
}
/* .drop-target {
background-color: #29e;
border-color: #fff;
border-style: solid;
} */
#proj_top{
margin: auto;
width: 90%;
display: flex;
justify-content: space-around;
}
#proj_name{
background-color: #aaa;
border: 0px;
text-align: center;
}
.inputs{
display: flex;
width: 80vw;
margin: auto;
padding-block: 20px;
padding-bottom: 0px;
/* margin-top: 50px; */
}
#group{
display: none;
position: absolute;
padding: 0px;
margin: 0px;
}
</style>
<div id="project_menu" class="cmenu">
<button id='proj_csave_btn' onclick='save_proj()'>сохранить в облако</button> <br>
<!-- <button id='proj_cload_btn' onclick='load_proj_cloud()'>загрузить из облака</button> <br> -->
<!-- <button id='proj_lsave_btn' onclick='save_proj_local()'>сохранить на локальное хранилище</button> <br>
<button id='proj_lload_btn' onclick='load_proj_local()'>загрузить из локальное хранилище</button> <br> -->
<!-- <button id='proj_del_btn' onclick='del_proj()'>удалить проект</button> <br> -->
</div>
<!-- <div class="dropzone"></div> -->
<div class="inputs">
<div id="wall_input" style="display: flex;justify-content: space-between;width: 95%;margin-left: 20px;">
<div style="display: flex;width: 16vw;justify-content: space-between;">
<label for="wall_height" style="margin: auto;">Высота стены</label>
<input type="text" id="wall_height" style="width: 5vw; text-align: center; border-radius: 0.5vw; border: 1px solid gray;" value="2" oninput="this.value = this.value.replace(/[^0-9.]/g, '0').replace(/(\..*?)\..*/g, '$1').replace(/^0[^.]/, '0');wall_size_change('height');resize_drags();">
<label for="wall_width" style="margin: auto;">М.</label>
</div>
<div style="display: flex;width: 16vw;justify-content: space-between;">
<label for="wall_width" style="margin: auto;">Длина стены</label>
<input type="text" id="wall_width" style="width: 5vw; text-align: center; border-radius: 0.5vw; border: 1px solid gray;" value="4" oninput="this.value = this.value.replace(/[^0-9.]/g, '0').replace(/(\..*?)\..*/g, '$1').replace(/^0[^.]/, '0');wall_size_change('width');resize_drags();">
<label for="wall_width" style="margin: auto;">М.</label>
</div>
<div style="display: flex;width: 16vw;justify-content: space-between;">
<label for="wall_color" style="margin: auto;">Цвет стены</label>
<input type="color" id="wall_color" style="width: 5vw; border-radius: 0.5vw; border: 1px solid gray; min-height: 3.9vw;" value="#FFFFFF" onchange="wall_color_change()">
</div>
<div id="cost_div" style="display: flex;width: 15vw;justify-content: space-between;">
<button id="proj_cost" class="menu_btn" style="width: 100%;z-index: 3;">
<div id="proj_cost_text" style="pointer-events: none;">Расчет стоимости</div>
<img src="/img/drop.png" style="width: 1vw;height: 0.5vw;pointer-events: none;" alt="\/">
</button>
<style>
#cost_list li{
display: flex;
justify-content: space-between;
width: 14vw;
padding-block: 0.4vw;
}
#cost_list{
list-style-type: none;
padding-left: 0px;
margin-top: 59px;
position: absolute;
width: 14vw;
padding: 0.45vw;
}
</style>
<ul id="cost_list" class="cmenu">
</ul>
<!-- <div style="display: flex;"><div id="proj_cost"></div>&nbsp;руб.</div> -->
</div>
<!-- <div style="display: flex;width: 150px;justify-content: space-between;">
<label style="margin: auto;">Расчёт стоимости</label>
</div> -->
</div>
<!-- <img class="trash" style="height: 100px; width: 100px;" src="/img/shadow-energy.gif" alt="чёрная дыра"> -->
</div>
<div class="zones" style="position: relative;">
<div id="drags">
</div>
<div class="wall dropzone" id="wall"></div>
</div>
<div style="display:flex; justify-content: space-around;"></div>
<div class="inputs" style="display: flex;justify-content: space-between;height: 5vh;">
<div id="obj_color_div" style="justify-content: space-evenly; width: 50vw;display: none;transform: translateX(30%);">
<label for="obj_colors" style="min-width: 10vw;">цвет объекта</label>
<div id="obj_colors" style="display: flex; width: 30vw;overflow: auto;height: 50px;"></div>
<!-- <input id="obj_color" type="color" onchange="obj_color_change(event)"> -->
</div>
</div>
<div class="inputs" style="display: flex;justify-content: space-between;">
<style>
.btn_icon{
border: 1px solid gray;
border-radius: 0.5vw;
padding: 0.5vw;
height: 2vw;
width: 2vw;
cursor: pointer;
}
.btn_icon img{
height: 2vw;
width: 2vw;
}
</style>
<div style="display: flex;justify-content: space-between; width: 35vw;">
<div class="btn_icon"><img src="/img/icon/copy.png" alt="copy"></div>
<div class="btn_icon" onclick="go_back()"><img src="/img/icon/back.png" alt="back"></div>
<div class="btn_icon" onclick="go_forw()"><img src="/img/icon/forw.png" alt="forw"></div>
<div class="btn_icon" onclick="obj_del()"><img src="/img/icon/del.png" alt="del"></div>
<div class="layer_changer">
<div class="btn_icon layer_btn" onclick="obj_change_layer('up')"><img src="/img/icon/up.png" alt="up"></div>
<input id="layer_inp" type="number" oninput="obj_change_layer('inp')">
<div class="btn_icon layer_btn" onclick="obj_change_layer('down')"><img src="/img/icon/down.png" alt="down"></div>
</div>
<style>
#layer_inp{
width: 2vw;
appearance: textfield;
text-align: center;
border: 0px;
}
.layer_btn{
border: 0px;
}
.layer_changer{
display: flex;
background-color: white;
border: 1px gray solid;
border-radius: 0.5vw;
}
</style>
</div>
<div style="display: flex;justify-content: space-between; width: 7vw;">
<div id="save_btn_icon" class="btn_icon" onclick="save()"><img src="/img/icon/save.png" alt="save"></div>
<!-- <div class="btn_icon" onclick="document.getElementById('import_file').click();"><img src="/img/icon/download.png" alt="load"></div> -->
<!-- <input type='file' id="import_file" style="display: none;" accept="application/JSON" onchange='openFile(event,load_file)'> -->
</div>
</div>
<div class="inputs" style="display: flex;justify-content: space-between;margin-top: 0px;">
<div id="obj_group" style="display: flex;justify-content:space-evenly; width: 100vw;">
<!-- <button name="" id="group_drop" >Помехи на стене</button> -->
<style>
.obj_group{
/* width: 100%; */
display: flex;
padding-block: 0.3vw;
}
.obj_group label{
width: 90%;
/* padding-inline: 0.3vw; */
}
.group_drop{
width: 15vw;
padding: 2px;
min-width: 15vw;
}
.group_drop *{
pointer-events: none;
overflow: auto;
}
.group_drop img{
width: 1vw;
height: 0.5vw;
}
</style>
<div id="obj_parts" style="min-width: 50vw;display: flex;justify-content: space-evenly;">
</div>
<style>
.group_inp{
height: 1vw;
width: 1vw;
border: 0px;
border-radius: 0.4vw;
overflow: auto;
}
</style>
<ul id="group" class="cmenu"></ul>
</div>
</div>
<div class="czones"></div>
<script src="/lib/inter_group_object.js"></script>
<script>
const get_object_id = new URL(window.location).searchParams.get("object_id");
document.getElementById("layer_inp").value = 0;
img_cache(()=>{})
wall_size_change('height');resize_drags();
wall_size_change('width');resize_drags();
function img_download(){
let wait_msg = msg("делаем фото",{type:"wait"})
proj_img((src)=>{
msg("изображение проекта готово",{time:3})
downloadImg(src,`${proj_name}.png`)
},false)
}
function get_data(id,callback) {
$.post( "/get_objs")
.done(function( res ) {
if(res["out"] == "good"){
Object.entries(res["body"]).forEach(([key,value]) => {
if(id == value["id"]){
callback(value)
}
});
}
});
}
function save() {
get_data(get_object_id,(data)=>{
proj_img((src)=>{
$.post( "/admin/object/grouped/save",{name:data["name"],data:src,json:JSON.stringify(objs),id:data["id"]})
.done(function( res ) {
goto(`/admin/objects?object_id=${data["id"]}`);
});
})
})
}
function proj_img(callback,cost = false){
obj_selection(true)
let width = (parseInt(document.getElementById("wall").style.width))
document.getElementById("drags").append(document.getElementById("wall"));
document.getElementById("drags").style.height = document.getElementById("wall").style.height;
document.getElementById("cost_list").style.left = "";
Object.values(document.getElementsByClassName("spawn")).forEach((spawn)=>{
spawn.src = "";
})
if(cost == true){
width += document.getElementById("proj_cost").getBoundingClientRect().width;
document.getElementById("drags").append(document.getElementById("cost_div"));
document.getElementById("cost_div").style.marginLeft = `${parseInt(document.getElementById("wall").style.width) + 4}px`;
document.getElementById("cost_list").style.display = "block";
}
html2canvas(document.getElementById("drags"),{
y:7,
x:2,
width:width,
logging:false,
scale:5
}).then(canvas => {
if(cost == true){
document.getElementById("cost_div").style.marginLeft = `0`;
document.getElementById("cost_list").style.display = "none";
document.getElementById("wall_input").append(document.getElementById("cost_div"));
}
document.getElementsByClassName("zones")[0].append(document.getElementById("wall"));
let src = "";
src = canvas.toDataURL();
// console.log(src);
callback(src)
drag_start();
});
}
function obj_colors_load(callback) {
let div = document.getElementById("obj_colors");
div.innerHTML = "";
load_colors((colors)=>{
Object.entries(colors).forEach(([key,value]) => {
// console.log(value);
let color_div = document.createElement("div");
color_div.style = `background-color: #${value["color"]}; border-radius: 50%;height: 2vw;min-width: 2vw;margin-inline: 0.5vw;`;
color_div.classList.add("color_palette");
color_div.id=`color_${value["color"]}`;
color_div.setAttribute("color",`${value["color"]}`)
color_div.setAttribute("onclick",`clear_palette();document.getElementById('color_${value["color"]}').style.border = "1px blue solid";obj_color_change('${value["color"]}')`)
color_div.title = `#${value["color"]}`;
div.append(color_div);
if(key = Object.keys(colors).at(-1)){
if(callback)callback();
}
});
})
}
function wall_color_change(){
if (proj_state == "loaded"){objs_back.push(JSON.parse(JSON.stringify(objs)));}
let wall = document.getElementById("wall")
let color = document.getElementById("wall_color")
wall.style.backgroundColor = color.value;
objs["color"] = color.value;
}
function obj_color_change(color,in_obj = null){
if(color != "null"){
if (proj_state == "loaded"){objs_back.push(JSON.parse(JSON.stringify(objs)));}
let obj = (in_obj == null)? document.getElementById(cur_obj):in_obj;
// console.log(color);
color_change(color,obj.getAttribute("data-img"),(img)=>{
obj.src = img;
obj.setAttribute("color",color)
objs[obj.classList[0]][obj.id]["color"] = color;
});
}
}
function go_back(){
if(objs_back.length > 0){
objs_forw.push(objs);
objs = objs_back.at(-1);
objs_back.pop();
reload();
calc_total();
}
}
function go_forw(){
if(objs_forw.length > 0){
objs_back.push(objs);
objs = objs_forw.at(-1);
objs_forw.pop();
reload();
calc_total();
}
}
function obj_change_layer(type) {
let obj = document.getElementById(cur_obj);
if(obj != null){
let cur_layer = obj.style.zIndex;
if (type == "up" && cur_layer < 10000){
let new_layer = parseInt(cur_layer) + 1;
objs[obj.classList[0]][obj.getAttribute("id")].layer = new_layer;
obj.style.zIndex = new_layer;
obj.setAttribute("layer",new_layer);
document.getElementById("layer_inp").value = new_layer;
} else if (type == "down" && cur_layer > 0){
let new_layer = parseInt(cur_layer) - 1;
objs[obj.classList[0]][obj.getAttribute("id")].layer = new_layer;
obj.style.zIndex = new_layer;
obj.setAttribute("layer",new_layer);
document.getElementById("layer_inp").value = new_layer;
}
else if ((type == "inp")){
let inp_val = parseInt(document.getElementById("layer_inp").value);
if(inp_val >= 0 && inp_val < 10000){
objs[obj.classList[0]][obj.getAttribute("id")].layer = inp_val;
obj.style.zIndex = inp_val;
}
else{
document.getElementById("layer_inp").value = cur_layer;
}
}
}
// console.log(objs[obj.classList[0]][obj.getAttribute("id")]);
}
function obj_del(){
if (proj_state == "loaded"){objs_back.push(JSON.parse(JSON.stringify(objs)));}
document.getElementById("layer_inp").value = 0;
try{
let drag = document.getElementById(cur_obj);
if(drag.id != "none"){
console.log(cur_obj);
// console.log(drag.classList);
if(objs[drag.classList[0]] != null&&objs[drag.classList[0]][drag.id] != null) {
console.log(objs[drag.classList[0]]);
delete objs[drag.classList[0]][drag.id];
if (Object.keys(objs[drag.classList[0]]).length < 1){
delete objs[drag.classList[0]];
}
}
calc_total()
drag.remove();
document.getElementById("obj_color_div").style.display = "none";
cur_obj = null;
}
}
catch{msg("объект не выбран")}
}
function group_drop(){
let e = document.getElementById("group_drop")
setTimeout(()=>{
document.getElementById("group").style.display = "block";
// document.getElementById("group").style.left = document.getElementById("group_drop").getBoundingClientRect().left;
let childs = document.getElementById("group").getElementsByTagName("input");
let i = 0;
Object.entries(childs).forEach(([key,value]) => {
console.log(key,value);
if(value.checked == true){
get_objs(value)
i++;
}
if (i==0){
// document.getElementsByClassName("czones")[0].innerHTML = "";
drag_start()
// e.removeChild(e.getElementsByClassName(value))
}
});
},1)
}
load_parts((db)=>{
let parts = document.getElementById("obj_parts");
Object.values(db).forEach((value)=>{
let part = document.createElement("button")
let part_text = document.createElement("div")
let part_drop = document.createElement("img")
part_drop.src = "/img/drop.png";
part_drop.alt = "\/";
part_text.innerText = `${value["name"].replaceAll("$", " ")}`;
part.id = `group_drop-${value["id"]}`;
part.classList.add("menu_btn")
part.classList.add("group_drop")
part.setAttribute("groups",`${value["groups"]}`)
part.setAttribute("count",`${value["count"]}`)
part.setAttribute("no-cost",`${value["no-cost"]}`)
part.setAttribute("pid",`${value["id"]}`)
part.append(part_text);
part.append(part_drop);
parts.append(part);
console.log(value);
})
})
function gids_change(){
get_objs();
drag_start()
}
function get_groups(callback){
// let select = document.getElementById("group");
// let name = select.options[select.selectedIndex].text;
load_groups(callback(),gids);
}
// get_groups(()=>{
// get_objs();
// });
function get_objs(group_div){
document.getElementsByClassName("czones")[0].innerHTML = "";
gids.forEach(group => {
load_objs((data)=>{
data.forEach(value => {
let czones = document.getElementsByClassName("czones")[0];
let czone = document.createElement('div');
czone.classList.add(value["name"]);
czone.classList.add("createzone");
czones.append(czone)
});
drag_start()
},group)
});
drag_start()
}
// console.log(proj_name);
// let menu = document.getElementById("project_menu");
// document.getElementById("top_panel_left").innerHTML = `<div id='proj_menu' class="menu_btn">настройки проекта</div>`;
// drag_start();
// console.log(px_ratio);
$(window).resize(function(){isZooming();});
function isZooming(){
resize_drags();
}
if(get_object_id != null){
$.post("/admin/object/grouped/load",{id:get_object_id})
.done(function( res ) {
if(res["out"] == "good"){
console.log(JSON.parse(res["body"]["group_obj"]));
if(res["body"]["group_obj"]!=null){
load(JSON.parse(res["body"]["group_obj"]));
}
else{
setTimeout(() => {
proj_state = "loaded";
loaded();
}, 1000);
}
}
});
}
</script>
<%- include('../../static/end.ejs',{soc:true}) %>

View File

@ -41,13 +41,13 @@
</div>
<div>
<input type="checkbox" id="obj_color_check" onchange="color_warning()">
<label for="obj_color_check">возможность менять цвет</label>
<label for="obj_color_check">возможность менять цвет</label><br>
<script>
function color_warning(){
let color_check = document.getElementById("obj_color_check");
let old_prev = document.getElementById("img_prev").getAttribute("img_static");
if(color_check.checked == true){
obj_colors_load();
// obj_colors_load();
removeImageBackground(document.getElementById("img_prev").src).then((out)=>{
document.getElementById("img_prev").src = out;
})
@ -59,6 +59,23 @@
}
</script>
<input type="checkbox" id="obj_group_check" onchange="group_object_check()">
<label for="obj_group_check">Сделать обьект группированным</label>
<script>
function group_object_check(){
let onc = `document.getElementById('img_file').click();msg('помните что граници обозначают элемент с которым можно взаимодействовать даже если он прозрачный',{time:10,type:'help'});msg('старайтесь не оставлять пустые/прозрачные отступы',{time:15,type:'help'})`
let group_check = document.getElementById("obj_group_check");
let img_div = document.getElementById("img_prev_div");
if(group_check.checked == true){
img_div.setAttribute("onclick",`save_edited_obj(${group_check.getAttribute("object_id")});goto('/admin/group_object?object_id=${group_check.getAttribute("object_id")}')`);
}
else{
img_div.setAttribute("onclick",onc);
}
}
</script>
</div>
</div>
<div>
@ -130,7 +147,7 @@
}
}
function set_obj_edit_params(img = "/img/placeholder.png",name = "",height = 100,width = 100,cost = 0,gid = 0,colors = false, id = null){
function set_obj_edit_params(img = "/img/placeholder.png",name = "",height = 100,width = 100,cost = 0,gid = 0,colors = false,grouped = false,id = null){
// поменять на if id == null усё
if(id == null){
obj_edit_type = "new";
@ -145,6 +162,7 @@
del_btn.innerText = "удалить товар";
del_btn.classList.add("btn_blue");
document.getElementById("object_edit_type").append(del_btn);
document.getElementById("obj_group_check").setAttribute("object_id",id)
document.getElementById("obj_apply_btn").value = "сохранить";
document.getElementById("obj_apply_btn").setAttribute("onclick",`save_edited_obj(${id})`);
// document.getElementById("group_select").selectedIndex = document.getElementById("group_select").options[`obj_group_${gid}`].index;
@ -161,6 +179,7 @@
let width_text = document.getElementById("obj_width_value");
let cost_text = document.getElementById("obj_cost");
let colors_div = document.getElementById("obj_color_check");
let grouped_div = document.getElementById("obj_group_check");
name_div.value = name;
img_file.value = null;
@ -171,11 +190,14 @@
img_prev.style.width = `${width* cm_mult}px`;
cost_text.value = cost;
colors_div.checked = JSON.parse(colors);
grouped_div.checked = JSON.parse(grouped);
height_slider.value = height;
width_slider.value = width;
height_text.value = `${height}`;
width_text.value = `${width}`;
group_object_check();
}
function previewFile() {

View File

@ -61,6 +61,7 @@
// edit_get_objs();
// });
function set_edit(id){
let menu = document.getElementById(`object_${id}`);
set_obj_edit_params(menu.getAttribute("src"),
@ -70,10 +71,11 @@
menu.getAttribute("cost"),
menu.getAttribute("gid"),
menu.getAttribute("colors"),
menu.getAttribute("grouped"),
menu.getAttribute("obj_id"));
window.scrollTo({
top: 0,
behavior: "smooth",
top: 0,
behavior: "smooth",
});
}
@ -90,6 +92,10 @@
if(data.at(-1)["id"] == value["id"]){
msg_del(wait_msg.id);
msg("Объекты загружены")
if(new URL(window.location).searchParams.get("object_id") != null){
const get_object_id = new URL(window.location).searchParams.get("object_id");
set_edit(new URL(window.location).searchParams.get("object_id"));
}
if(callback)callback(true);
}
})
@ -131,14 +137,15 @@
function save_edited_obj(id){
let gid = gids[0];
let menu = document.getElementById(`object_${id}`);
let attributes = ["name","img","height","width","cost","colors"];
let attributes = ["name","img","height","width","cost","colors","grouped"];
let cur_atts = {
name : document.getElementById("nobj_name").value,
height : document.getElementById("obj_height").value,
width : document.getElementById("obj_width").value,
img : document.getElementById('img_prev').getAttribute("src"),
cost : document.getElementById("obj_cost").value,
colors : String(document.getElementById("obj_color_check").checked)
colors : String(document.getElementById("obj_color_check").checked),
grouped : String(document.getElementById("obj_group_check").checked)
}
let changes = {}
attributes.forEach(element => {
@ -253,6 +260,7 @@
obj.setAttribute("obj_id",value["id"])
obj.setAttribute("cost",value["cost"])
obj.setAttribute("colors",Boolean(value["colors"]))
obj.setAttribute("grouped",Boolean(value["grouped"]))
obj.setAttribute("gid",value["gid"])
// // name_text.innerText = value["name"].split("~")[0].replaceAll("$"," ");
// img_elm.src = img;
@ -272,6 +280,7 @@
cost : value["cost"],
link : img,
color : Boolean(value["colors"]),
grouped : Boolean(value["grouped"]),
edit : `set_edit(${value["id"]})`
}
@ -283,6 +292,7 @@
cost : "Цена",
link : "Ссылка на изображение",
color : "Меняет цвет",
grouped : "группированный",
edit : "Радактировать"
}
@ -299,6 +309,7 @@
`<td>${labels["cost"]}</td>`+
`<td>${labels["link"]}</td>`+
`<td>${labels["color"]}</td>`+
`<td>${labels["grouped"]}</td>`+
`<td>${labels["edit"]}</td>`+
"</tr>"+
"<tr class='obj_table_divs'>"+
@ -309,6 +320,7 @@
`<td>${divs["cost"]}</td>`+
`<td><a href='${divs["link"]}'>${divs["link"]}</a></td>`+
`<td><input type='checkbox' id='obj_edit_color_check' ${(divs["color"] == true)? "checked":""} onclick='return false' onkeydown='return false'/></td>`+
`<td><input type='checkbox' id='obj_edit_group_check' ${(divs["grouped"] == true)? "checked":""} onclick='return false' onkeydown='return false'/></td>`+
`<td><button onclick='${divs["edit"]}' class='btn_blue'>Выбрать</button></td>`+
"</tr>";

View File

@ -190,7 +190,7 @@
<div class="inputs" style="display: flex;justify-content: space-between;height: 5vh;">
<div id="obj_color_div" style="justify-content: space-evenly; width: 50vw;display: none;transform: translateX(30%);">
<label for="obj_colors" style="min-width: 10vw;">цвет объекта</label>
<div id="obj_colors" style="display: flex; width: 30vw;overflow: auto;height: 4.5vh;"></div>
<div id="obj_colors" style="display: flex; width: 30vw;overflow: auto;height: 50px;"></div>
<!-- <input id="obj_color" type="color" onchange="obj_color_change(event)"> -->
</div>
</div>