var fieldcolor = "rgb(0, 0, 0)"; shape = []; var index = -1; var legend = {}; // объект с айтемами легенды var legend_img_margin_left = 5; var text_height; var element_ico_size = 16; var dimension = []; dimension["naprav"] = [[22, 10], [24, 13.33], [28, 15.56], [32, 17.78], [34, 18.89], [40, 22.22], [46, 25.56], [52, 28.89]]; dimension["petlya"] = [[16, 16], [18, 18], [20, 20], [24, 24], [28, 28], [32, 32], [36, 36], [40, 40]]; dimension["gazlift"] = [[16, 11.08], [18, 12.46], [20, 13.85], [24, 16.62], [28, 19.38], [32, 22.15], [36, 24.92], [40, 27.69]]; dimension["podyomnik"] = [[16, 16], [18, 16.88], [20, 18.75], [24, 22.5], [28, 26.25], [32, 30], [36, 33.75], [40, 37.5]]; dimension["sushka"] = [[16, 13], [18, 14.62], [20, 16.25], [24, 19.5], [28, 22.75], [32, 26], [36, 29.25], [40, 32.5]]; dimension["lotok"] = [[16, 16], [18, 18], [20, 20], [24, 24], [28, 28], [32, 32], [36, 36], [40, 40]]; dimension["vnutr-yaschik"] = [[16, 9], [18, 10.13], [20, 11.25], [26, 14.63], [30, 16.88], [34, 19.13], [38, 21.38], [42, 23.63]]; dimension["butilochnitsa"] = [[12, 18], [13.33,20], [14.67, 22], [17.33, 26], [20, 30], [22.67, 34], [25.33, 38], [28, 42]]; dimension["dampfer"] = [[16, 8], [18, 9], [22, 11], [26, 13], [30, 15], [34, 17], [38, 19], [42, 21]]; dimension["tip-on"] = [[16, 16], [18, 18], [20, 20], [24, 24], [28, 28], [32, 32], [36, 36], [40, 40]]; dimension["zamok"] = [[16, 16], [18, 18], [20, 20], [24, 24], [28, 28], [32, 32], [36, 36], [40, 40]]; dimension["skritiy-krepezh"] = [[18, 14.59], [22, 17.84], [24, 19.46], [30, 24.32], [32, 25.94], [36, 29.19], [44, 35.67], [50, 40.54]]; var text_item_width = 0; var biggest_legend_item_width; function changeTextWidth(item){ if(item.width < 10){ if(biggest_legend_item_width > 0 && /legend.*/.test(item.groupName)){ item.width = biggest_legend_item_width - (legend_back.margin * 2 + legend_img_margin_left); } else{ item.width = 10; } } canvas.renderAll(); } var editor_obj = { add_text: function(e={}, x=canvas.getPointer(e.e).x, y=canvas.getPointer(e.e).y, ang = 0, text = "Выделите и кликните, чтобы ввести текст", group_name="shape_text", flag=false, fill = fieldcolor){ if(group_name != 'legend'){ var font_size = text_dimension[zoom_size]; } else{ var font_size = 11; } let temp_shape; if(group_name == "shape_text"){ temp_shape = new fabric.Textbox(text, { selectable: true, lockMovementX: flag, lockMovementY: flag, fontSize: font_size, fontFamily: "Golos Text", fill: fill, backgroundColor: "rgba(0, 0, 0, 0)", left: x, top: y, width: 295, // height: 150, angle: ang, textAlign: 'left', perPixelTargetFind: flag, groupName: group_name + index, index: index }) } else{ temp_shape = new fabric.IText(text, { selectable: true, lockMovementX: flag, lockMovementY: flag, fontSize: font_size, fontFamily: "Golos Text", fill: fill, backgroundColor: "rgba(0, 0, 0, 0)", left: x, top: y, width: 500, height: 150, angle: ang, textAlign: 'center', perPixelTargetFind: flag, groupName: group_name + index, index: index }) } temp_shape.parent = temp_shape; if(group_name != 'legend'){ // canvas.setActiveObject(temp_shape); } else{ temp_shape.backgroundColor = legend_back.fill; } setTimeout(function(){ changeTextWidth(temp_shape); }, 100); temp_shape.on('changed', function () { changeTextWidth(temp_shape); }); canvas.add(temp_shape); return temp_shape; }, add_rect: function(e, flag=true, x=canvas.getPointer(e.e).x, y=canvas.getPointer(e.e).y, w=0, h=0, color='rgba(0, 0, 0, 0)', stroke=fieldcolor, group_name="shape_rect", ispart=false){ if(group_name == "socket"){ var stroke_width = 1; } else{ var stroke_width = zoom_size + 1; } let temp_shape = new fabric.Rect({ selectable: flag, left: x, top: y, stroke: stroke, strokeUniform: true, strokeWidth: stroke_width, fill: color, width: w, height: h, hasControls: flag, perPixelTargetFind: true, groupName: group_name + index, index: index }); temp_shape.parent = temp_shape; if(!ispart && group_name != "temp"){ if(group_name != "crop"){ canvas.setActiveObject(temp_shape); } canvas.add(temp_shape); } else{ temp_shape.originX = 'center'; temp_shape.originY = 'center'; } return temp_shape; }, add_circle: function(e, flag=true, x=canvas.getPointer(e.e).x, y=canvas.getPointer(e.e).y, r=1, color='rgba(0, 0, 0, 0)', stroke=fieldcolor, group_name="shape_circle", ispart=false, objects=undefined){ let temp_shape = new fabric.Circle({ selectable: flag, left: x, top: y, radius: r, stroke: stroke, strokeWidth: zoom_size + 1, strokeUniform: true, fill: color, objects: objects, perPixelTargetFind: true, groupName: group_name + index, index: index }); temp_shape.parent = temp_shape; if(!ispart){ canvas.setActiveObject(temp_shape); canvas.add(temp_shape); } else{ temp_shape.originX = 'center'; temp_shape.originY = 'center'; } return temp_shape; }, add_line: add_line, add_size: add_size, add_geometry: add_geometry, add_cap: add_cap, add_socket: add_socket, add_arrow: add_arrow, add_selection: function(){ element_cursor(); canvas.isDrawingMode = 0; }, add_image: function(img, not_from_url = false){ let original = new Image(); original.src = img; original.onload = function() { let scaleX, scaleY; scaleX = canvas.width*0.25 / this.width; scaleY = scaleX; if(!not_from_url){ new fabric.Image.fromURL(img, function(temp_shape){ temp_shape.groupName = "shape_img" + index; temp_shape.scaleX = scaleX; temp_shape.scaleY = scaleY; temp_shape.perPixelTargetFind = true, temp_shape.index = index; temp_shape.parent = temp_shape; canvas.add(temp_shape); temp_shape.sendToBack(); }); } else{ var temp_shape = new fabric.Image(original); temp_shape.groupName = "shape_img" + index; temp_shape.left = crop_selection.left; temp_shape.top = crop_selection.top; temp_shape.setCoords(); temp_shape.index = index; temp_shape.parent = temp_shape; canvas.add(temp_shape); temp_shape.sendToBack(); canvas.setActiveObject(temp_shape); } } }, add_svg: function(e, img = element_pos.src, x = e.pointer.x, y = e.pointer.y, groupName = "shape_svg", flag = true, fill = fieldcolor){ new fabric.loadSVGFromURL(img, function(objects, options) { let temp_shape = fabric.util.groupSVGElements(objects, options); temp_shape.set({ selectable: flag, fill: fill, centeredScaling: true, perPixelTargetFind: true, groupName: groupName + index, caption: elements[element_pos.i].getAttribute("value"), caption_type: elements[element_pos.i].id, hasControls: false, originX: "center", originY: "center", index: index }); temp_shape.parent = temp_shape; temp_shape.lockRotation = true; if(element_pos.width / element_pos.height > 1){ temp_shape.scaleToWidth(element_pos.width); } else{ temp_shape.scaleToHeight(element_pos.height); } temp_shape.scaleConstX = temp_shape.scaleX; temp_shape.scaleConstY = temp_shape.scaleY; if(element_pos.width / element_pos.height > 1){ temp_shape.scaleToWidth(dimension[element_pos.id][zoom_size][0]); } else{ temp_shape.scaleToHeight(dimension[element_pos.id][zoom_size][1]); } // temp_shape.left = canvas.getPointer(e.e).x - window.devicePixelRatio / 2; // temp_shape.top = canvas.getPointer(e.e).y + window.devicePixelRatio; temp_shape.left = canvas.getPointer(e.e).x; temp_shape.top = canvas.getPointer(e.e).y; temp_shape.stroke_colorable = false; canvas.add(temp_shape).renderAll(); endOfCreating(temp_shape); editor_obj.add_legend(); } ); }, add_legend: function(e, x = legend_back.left + legend_img_margin_left, y = legend_back.top){ biggest_legend_item_width = 0; let array = canvas.getObjects(); for(let i in array){ let shape_type = /legend.*/.test(array[i].groupName); if(shape_type){ let marker = array[i].caption_type + array[i].fill; delete legend[marker]; // удаляем айтемы с канваса canvas.remove(array[i]); } } canvas.renderAll(); // создаем айтемы legend_back.margin = 12; const margin_top = 10; const margin_bottom = 10; text_height = margin_top; for(let i in array){ let marker = array[i].caption_type + array[i].fill; let shape_type = /shape_svg.*/.test(array[i].groupName); // проверяем, есть ли айтем такого типа и цвета if(shape_type && array[i].visible && !legend[marker]){ legend[marker] = true; var img_item = fabric.util.object.clone(array[i]); img_item.originX = 'center'; img_item.originY = 'center'; img_item.set({ "left": x + legend_back.margin, "top": 0, // определено ниже "scaleX": array[i].scaleConstX, "scaleY": array[i].scaleConstY }); img_item.groupName = "legend"; img_item.group = undefined; img_item.selectable = false; var text_item = editor_obj.add_text(e, x + legend_back.margin + legend_img_margin_left * 3, y + text_height, 0, array[i].caption, "legend", true, "black"); text_item.originY = 'center'; text_item.hasControls = false; text_item.hasBorders = false; text_item.fontFamily = 'Golos Text'; text_item.fontSize = 11; text_item.textAlign = 'left'; text_item.index = array[i].index; img_item.top = text_item.top = text_item.top + text_item.height / 2; const outdent = img_item.left - legend_back.left; canvas.renderAll(); text_item_width = text_item.width + outdent * 2; if(text_item_width > biggest_legend_item_width){ biggest_legend_item_width = text_item_width; } text_height += text_item.height + margin_bottom; legend_back.scaleX = (legend_back.margin + biggest_legend_item_width) / legend_back.width; legend_back.scaleY = text_height / legend_back.height; legend_back.rx = legend_back.border_radius * (1 / legend_back.scaleX); legend_back.ry = legend_back.border_radius * (1 / legend_back.scaleY); canvas.add(img_item); text_item.on('changed', function () { text_height = margin_top; text_item_width = this.width + outdent * 2; shape[this.index].caption = this.text; if(text_item_width > biggest_legend_item_width){ biggest_legend_item_width = text_item_width; } if(legend_back.width * legend_back.scaleX < biggest_legend_item_width + legend_back.margin){ legend_back.scaleX = (legend_back.margin + biggest_legend_item_width) / legend_back.width; } let array = canvas.getObjects(); let array2 = []; for(var i = 0; i < array.length; i++){ let shape_type = /legend.*/.test(array[i].groupName); if(shape_type){ array2.push(array[i]); } } for(var i = 0; i < array2.length; i+=2){ var img_item = array2[i + 1]; var text_item = array2[i]; if(img_item != undefined){ var top = legend_back.top + text_height + text_item.height / 2; text_item.set("top", top); img_item.set("top", top); text_height += text_item.height + margin_bottom; } } legend_back.scaleY = text_height / legend_back.height; legend_back.rx = legend_back.border_radius * (1 / legend_back.scaleX); legend_back.ry = legend_back.border_radius * (1 / legend_back.scaleY); }); } } canvas.renderAll(); }, change_source: function(img){ let original = new Image(); original.src = img; editor_start = true; original.onload = function() { let scaleX, scaleY, left, top; if(canvas.width / canvas.height > this.width / this.height){ scaleY = canvas.height / this.height; scaleX = scaleY; } else{ scaleX = canvas.width / this.width; scaleY = scaleX; } let firstWidth = this.width * scaleX; let firstHeight = this.height * scaleY; let firstLeft = canvas.width / 2; let firstTop = canvas.height / 2; canvas.setBackgroundImage(img, function(){ canvas.backgroundImage.firstWidth = firstWidth; canvas.backgroundImage.firstHeight = firstHeight; canvas.backgroundImage.firstLeft = firstLeft; canvas.backgroundImage.firstTop = firstTop; canvas.renderAll() }, { scaleX: scaleX, scaleY: scaleY, left: firstLeft, top: firstTop, originX: 'center', originY: 'center' }); } }, clone: function(){ let item = canvas.getActiveObject(); if(item != undefined && !group.cloneOne && item.groupName != "crop-1"){ if(item.type == "activeSelection" || item.parent.objects){ if(item.type == "activeSelection"){ var array = item._objects; } else{ var array = []; for(let i of item.parent.objects){ array.push(item.parent[i]); } } let array_temp = []; canvas.discardActiveObject(); // let new_index = []; for(let i = 0; i < array.length; i++){ // let index_temp = [Number(/\-*[0-9]+/.exec(array[i].groupName))]; let obj_temp = fabric.util.object.clone(array[i]); obj_temp.clonned = true; canvas.add(obj_temp); let shape_type = /shape.*/.test(obj_temp.groupName); // если groupName не shape, то это примитив if(!shape_type){ // если не примитив obj_temp.groupName = obj_temp.groupName + "clone"; } array_temp.push(obj_temp); } loadObjects(array_temp); let selection_temp = new fabric.ActiveSelection(array_temp, { canvas: canvas, // originX: 'center', // originY: 'center' }); group = {groupName: undefined}; canvas.setActiveObject(selection_temp); selection_temp.parent = selection_temp; selection_temp.hasControls = false; canvas.renderAll(); } else{ let obj_temp = fabric.util.object.clone(item); obj_temp.hasControls = false; obj_temp.clonned = true; canvas.add(obj_temp); canvas.setActiveObject(shape[index]); canvas.renderAll(); } group.cloneOne = group.mousedown = true; } }, setClone: function(item){ // устанавливает клон в текущей позиции курсора, вызывается в undo_redo.js group.cloneOne = false; group.param_saved = false; oldParam(item); changes(item, "10"); actionsHist[actionsIndex].flag = 'add'; actionsHist.index = item.index; if(item.type == "image"){ canvas.sendToBack(item); } if(item.groupType == "shape_rect" || item.groupType == "shape_circle"){ setTimeout(function(){ canvas.setActiveObject(item); // в _setActiveObject в fabric.js }, 10); } group.param_saved = true; canvas.renderAll(); } }; var big_square_line_left = 0; var big_square_line_top = 0; class Cell{ constructor(scene, x, y, size, value, deltaX = 0, deltaY = 0, bg = true){ this.scene = scene; this.x = x; this.y = y; this.deltaX = deltaX; this.deltaY = deltaY; this.size = size; this.value = value; this.bg = bg; this._value; } set value(value){ this.scene.lineWidth = 0.4; this._value = value; this.scene.strokeStyle = value; if(this.bg){ this.scene.strokeStyle = "#374448"; this.scene.fillStyle = value; this.scene.fillRect(this.x * this.size + this.deltaX, this.y * this.size + this.deltaY, this.size, this.size); this.scene.strokeRect(this.x * this.size + this.deltaX, this.y * this.size + this.deltaY, this.size, this.size); } else{ this.scene.strokeRect(this.x * this.size + this.deltaX + big_square_line_left, this.y * this.size + this.deltaY + big_square_line_top, this.size, this.size); } } get value(){ return this._value; } }