| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980 |
- document.querySelector('#lin').addEventListener("mouseup", _MOUSEUP);
- document.querySelector('#lin').addEventListener("mousemove", throttle(function (event) { _MOUSEMOVE(event); }, 30));
- document.querySelector('#lin').addEventListener("mousedown", _MOUSEDOWN, true);
- $(document).on('click', '#lin', function (event) {
- event.preventDefault();
- });
- document.querySelector('#panel').addEventListener('mousemove', function (event) {
- if ((mode == 'line_mode' || mode == 'partition_mode') && action == 1) {
- action = 0;
- if (typeof (binder) != 'undefined') {
- binder.remove();
- delete binder;
- }
- $('#linetemp').remove();
- $('#line_construc').remove();
- lengthTemp.remove();
- delete lengthTemp;
- }
- });
- window.addEventListener('resize', function (event) {
- width_viewbox = $('#lin').width();
- height_viewbox = $('#lin').height();
- document.querySelector('#lin').setAttribute('viewBox', originX_viewbox + ' ' + originY_viewbox + ' ' + width_viewbox + ' ' + height_viewbox)
- });
- // *****************************************************************************************************
- // ****************************** KEYPRESS on KEYBOARD *********************************
- // *****************************************************************************************************
- document.addEventListener("keydown", function (event) {
- if (mode != "text_mode") {
- if (event.keyCode == '37') {
- //LEFT
- zoom_maker('zoomleft', 100, 30);
- }
- if (event.keyCode == '38') {
- //UP
- zoom_maker('zoomtop', 100, 30);
- }
- if (event.keyCode == '39') {
- //RIGHT
- zoom_maker('zoomright', 100, 30);
- }
- if (event.keyCode == '40') {
- //DOWN
- zoom_maker('zoombottom', 100, 30);
- }
- if (event.keyCode == '107') {
- //+
- zoom_maker('zoomin', 20, 50);
- }
- if (event.keyCode == '109') {
- //-
- zoom_maker('zoomout', 20, 50);
- }
- }
- // else {
- // if (action == 1) {
- // binder.textContent = binder.textContent + event.key;
- // console.log(field.value);
- // }
- // }
- });
- // *****************************************************************************************************
- // ****************************** MOUSE MOVE *******************************************
- // *****************************************************************************************************
- function _MOUSEMOVE(event) {
- event.preventDefault();
- $('.sub').hide(100);
- // Cleanup debug markers so they don't linger when moving away from key points
- $('#boxDebug').empty();
- // In floorplan mode, do not show hover highlights over walls/nodes (binder visuals)
- if (window.__floorplanMode && mode === 'select_mode') {
- try {
- if (typeof (binder) !== 'undefined') {
- if (binder.remove) binder.remove();
- else if (binder.graph && binder.graph.remove) binder.graph.remove();
- delete binder;
- }
- } catch (_) { /* no-op */ }
- // Also ensure the binder container is clear
- try { $('#boxbind').empty(); } catch (_) { /* no-op */ }
- // Stop processing to avoid recreating highlights
- return;
- }
- //**************************************************************************
- //******************** TEXTE MODE **************************************
- //**************************************************************************
- if (mode == 'text_mode') {
- snap = calcul_snap(event, grid_snap);
- if (action == 0) cursor('text');
- else {
- cursor('none');
- }
- }
- //**************************************************************************
- //************** OBJECT MODE **************************************
- //**************************************************************************
- if (mode == 'object_mode') {
- snap = calcul_snap(event, grid_snap);
- if (typeof (binder) == 'undefined') {
- $('#object_list').hide(200);
- if (modeOption == 'simpleStair') binder = new editor.obj2D("free", "stair", "simpleStair", snap, 0, 0, 0, "normal", 0, 15);
- else {
- var typeObj = modeOption;
- binder = new editor.obj2D("free", "energy", typeObj, snap, 0, 0, 0, "normal", 0);
- }
- $('#boxbind').append(binder.graph);
- }
- else {
- if ((binder.family != 'stick' && binder.family != 'collision') || WALLS.length == 0) {
- binder.x = snap.x;
- binder.y = snap.y;
- binder.oldX = binder.x;
- binder.oldY = binder.y;
- binder.update();
- }
- if (binder.family == 'collision') {
- var found = false;
- if (editor.rayCastingWalls({ x: binder.bbox.left, y: binder.bbox.top })) found = true;
- if (!found && editor.rayCastingWalls({ x: binder.bbox.left, y: binder.bbox.bottom })) found = true;
- if (!found && editor.rayCastingWalls({ x: binder.bbox.right, y: binder.bbox.top })) found = true;
- if (!found && editor.rayCastingWalls({ x: binder.bbox.right, y: binder.bbox.bottom })) found = true;
- if (!found) {
- binder.x = snap.x;
- binder.y = snap.y;
- binder.oldX = binder.x;
- binder.oldY = binder.y;
- binder.update();
- }
- else {
- binder.x = binder.oldX;
- binder.y = binder.oldY;
- binder.update();
- }
- }
- if (binder.family == 'stick') {
- pos = editor.stickOnWall(snap);
- binder.oldX = pos.x;
- binder.oldY = pos.y;
- var angleWall = qSVG.angleDeg(pos.wall.start.x, pos.wall.start.y, pos.wall.end.x, pos.wall.end.y);
- var v1 = qSVG.vectorXY({ x: pos.wall.start.x, y: pos.wall.start.y }, { x: pos.wall.end.x, y: pos.wall.end.y });
- var v2 = qSVG.vectorXY({ x: pos.wall.end.x, y: pos.wall.end.y }, snap);
- binder.x = pos.x - Math.sin(pos.wall.angle * (360 / 2 * Math.PI)) * binder.thick / 2;
- binder.y = pos.y - Math.cos(pos.wall.angle * (360 / 2 * Math.PI)) * binder.thick / 2;
- var newAngle = qSVG.vectorDeter(v1, v2);
- if (Math.sign(newAngle) == 1) {
- angleWall += 180;
- binder.x = pos.x + Math.sin(pos.wall.angle * (360 / 2 * Math.PI)) * binder.thick / 2;
- binder.y = pos.y + Math.cos(pos.wall.angle * (360 / 2 * Math.PI)) * binder.thick / 2;
- }
- binder.angle = angleWall;
- binder.update();
- }
- }
- }
- //**************************************************************************
- //************** DISTANCE MODE **************************************
- //**************************************************************************
- if (mode == 'distance_mode') {
- snap = calcul_snap(event, grid_snap);
- if (typeof (binder) == 'undefined') {
- cross = qSVG.create("boxbind", "path", {
- d: "M-3000,0 L3000,0 M0,-3000 L0,3000",
- "stroke-width": 0.5,
- "stroke-opacity": "0.8",
- stroke: "#e2b653",
- fill: "#e2b653"
- });
- binder = new editor.obj2D("free", "measure", "", { x: 0, y: 0 }, 0, 0, 0, "normal", 0, "");
- labelMeasure = qSVG.create("none", "text", {
- x: 0,
- y: - 10,
- 'font-size': '1.2em',
- stroke: "#ffffff",
- "stroke-width": "0.4px",
- 'font-family': 'roboto',
- 'text-anchor': 'middle',
- fill: "#3672d9"
- });
- binder.graph.append(labelMeasure);
- $('#boxbind').append(binder.graph);
- }
- else {
- x = snap.x;
- y = snap.y;
- cross.attr({
- "transform": "translate(" + (snap.x) + "," + (snap.y) + ")"
- });
- if (action == 1) {
- var startText = qSVG.middle(pox, poy, x, y);
- var angleText = qSVG.angle(pox, poy, x, y);
- var valueText = qSVG.measure({
- x: pox,
- y: poy
- }, {
- x: x,
- y: y
- });
- binder.size = valueText;
- binder.x = startText.x;
- binder.y = startText.y;
- binder.angle = angleText.deg;
- valueText = (valueText / meter).toFixed(2) + ' m';
- //labelMeasure.context.textContent = valueText;
- labelMeasure[0].textContent = valueText;
- binder.update();
- }
- }
- }
- //**************************************************************************
- //************** ROOM MODE *****************************************
- //**************************************************************************
- if (mode == 'room_mode') {
- snap = calcul_snap(event, grid_snap);
- var roomTarget;
- if (roomTarget = editor.rayCastingRoom(snap)) {
- if (typeof (binder) != 'undefined') {
- binder.remove();
- delete binder;
- }
- var pathSurface = roomTarget.coords;
- var pathCreate = "M" + pathSurface[0].x + "," + pathSurface[0].y;
- for (var p = 1; p < pathSurface.length - 1; p++) {
- pathCreate = pathCreate + " " + "L" + pathSurface[p].x + "," + pathSurface[p].y;
- }
- pathCreate = pathCreate + "Z";
- if (roomTarget.inside.length > 0) {
- for (var ins = 0; ins < roomTarget.inside.length; ins++) {
- pathCreate = pathCreate + " M" + Rooms.polygons[roomTarget.inside[ins]].coords[Rooms.polygons[roomTarget.inside[ins]].coords.length - 1].x + "," + Rooms.polygons[roomTarget.inside[ins]].coords[Rooms.polygons[roomTarget.inside[ins]].coords.length - 1].y;
- for (var free = Rooms.polygons[roomTarget.inside[ins]].coords.length - 2; free > -1; free--) {
- pathCreate = pathCreate + " L" + Rooms.polygons[roomTarget.inside[ins]].coords[free].x + "," + Rooms.polygons[roomTarget.inside[ins]].coords[free].y;
- }
- }
- }
- binder = qSVG.create('boxbind', 'path', {
- id: 'roomSelected',
- d: pathCreate,
- fill: '#c9c14c',
- 'fill-opacity': 0.5,
- stroke: '#c9c14c',
- 'fill-rule': 'evenodd',
- 'stroke-width': 3
- });
- binder.type = 'room';
- binder.area = roomTarget.area;
- binder.id = ROOM.indexOf(roomTarget);
- }
- else {
- if (typeof (binder) != 'undefined') {
- binder.remove();
- delete binder;
- }
- }
- }
- //**************************************************************************
- //************** DOOR/WINDOW MODE *********************************
- //**************************************************************************
- if (mode == 'door_mode') {
- snap = calcul_snap(event, grid_snap);
- if (wallSelect = editor.nearWall(snap)) {
- var wall = wallSelect.wall;
- if (wall.type != 'separate') {
- if (typeof (binder) == 'undefined') {
- // family, classe, type, pos, angle, angleSign, size, hinge, thick
- binder = new editor.obj2D("inWall", "doorWindow", modeOption, wallSelect, 0, 0, 60, "normal", wall.thick);
- var angleWall = qSVG.angleDeg(wall.start.x, wall.start.y, wall.end.x, wall.end.y);
- var v1 = qSVG.vectorXY({ x: wall.start.x, y: wall.start.y }, { x: wall.end.x, y: wall.end.y });
- var v2 = qSVG.vectorXY({ x: wall.end.x, y: wall.end.y }, snap);
- var newAngle = qSVG.vectorDeter(v1, v2);
- if (Math.sign(newAngle) == 1) {
- angleWall += 180;
- binder.angleSign = 1;
- }
- var startCoords = qSVG.middle(wall.start.x, wall.start.y, wall.end.x, wall.end.y);
- binder.x = startCoords.x;
- binder.y = startCoords.y;
- binder.angle = angleWall;
- binder.update();
- $('#boxbind').append(binder.graph);
- }
- else {
- var angleWall = qSVG.angleDeg(wall.start.x, wall.start.y, wall.end.x, wall.end.y);
- var v1 = qSVG.vectorXY({ x: wall.start.x, y: wall.start.y }, { x: wall.end.x, y: wall.end.y });
- var v2 = qSVG.vectorXY({ x: wall.end.x, y: wall.end.y }, snap);
- var newAngle = qSVG.vectorDeter(v1, v2);
- binder.angleSign = 0;
- if (Math.sign(newAngle) == 1) {
- binder.angleSign = 1;
- angleWall += 180;
- }
- var limits = limitObj(wall.equations.base, binder.size, wallSelect);
- if (qSVG.btwn(limits[0].x, wall.start.x, wall.end.x) && qSVG.btwn(limits[0].y, wall.start.y, wall.end.y) && qSVG.btwn(limits[1].x, wall.start.x, wall.end.x) && qSVG.btwn(limits[1].y, wall.start.y, wall.end.y)) {
- binder.x = wallSelect.x;
- binder.y = wallSelect.y;
- binder.angle = angleWall;
- binder.thick = wall.thick;
- binder.limit = limits;
- binder.update();
- }
- if ((wallSelect.x == wall.start.x && wallSelect.y == wall.start.y) || (wallSelect.x == wall.end.x && wallSelect.y == wall.end.y)) {
- if (qSVG.btwn(limits[0].x, wall.start.x, wall.end.x) && qSVG.btwn(limits[0].y, wall.start.y, wall.end.y)) {
- binder.x = limits[0].x;
- binder.y = limits[0].y;
- }
- if (qSVG.btwn(limits[1].x, wall.start.x, wall.end.x) && qSVG.btwn(limits[1].y, wall.start.y, wall.end.y)) {
- binder.x = limits[1].x;
- binder.y = limits[1].y;
- }
- binder.limit = limits;
- binder.angle = angleWall;
- binder.thick = wall.thick;
- binder.update();
- }
- }
- }
- }
- else {
- if (typeof (binder) != 'undefined') {
- binder.graph.remove();
- delete binder;
- }
- }
- } // END DOOR MODE
- //**************************************************************************
- //************** NODE MODE *****************************************
- //**************************************************************************
- if (mode == 'node_mode') {
- snap = calcul_snap(event, grid_snap);
- if (typeof (binder) == 'undefined') {
- if (addNode = editor.nearWall(snap, 30)) {
- var x2 = addNode.wall.end.x;
- var y2 = addNode.wall.end.y;
- var x1 = addNode.wall.start.x;
- var y1 = addNode.wall.start.y;
- angleWall = qSVG.angle(x1, y1, x2, y2);
- binder = qSVG.create('boxbind', 'path', {
- id: "circlebinder",
- d: "M-20,-10 L-13,0 L-20,10 Z M-13,0 L13,0 M13,0 L20,-10 L20,10 Z",
- stroke: "#5cba79",
- fill: "#5cba79",
- "stroke-width": "1.5px"
- });
- binder.attr({
- "transform": "translate(" + (addNode.x) + "," + (addNode.y) + ") rotate(" + (angleWall.deg + 90) + ",0,0)"
- });
- binder.data = addNode;
- binder.x1 = x1;
- binder.x2 = x2;
- binder.y1 = y1;
- binder.y2 = y2;
- }
- } else {
- if (addNode = editor.nearWall(snap, 30)) {
- if (addNode) {
- var x2 = addNode.wall.end.x;
- var y2 = addNode.wall.end.y;
- var x1 = addNode.wall.start.x;
- var y1 = addNode.wall.start.y;
- angleWall = qSVG.angle(x1, y1, x2, y2);
- binder.attr({
- "transform": "translate(" + (addNode.x) + "," + (addNode.y) + ") rotate(" + (angleWall.deg + 90) + ",0,0)"
- });
- binder.data = addNode;
- }
- else {
- binder.remove();
- delete binder;
- }
- } else {
- binder.remove();
- delete binder;
- }
- }
- } // END NODE MODE
- //********************************** SELECT MODE ***************************************************************
- if (mode == 'select_mode' && drag == 'off') { // FIRST TEST ON SELECT MODE (and drag OFF) to detect MOUSEOVER DOOR
- snap = calcul_snap(event, 'off');
- var objTarget = false;
- for (var i = 0; i < OBJDATA.length; i++) {
- var objX1 = OBJDATA[i].bbox.left;
- var objX2 = OBJDATA[i].bbox.right;
- var objY1 = OBJDATA[i].bbox.top;
- var objY2 = OBJDATA[i].bbox.bottom;
- var realBboxCoords = OBJDATA[i].realBbox;
- if (qSVG.rayCasting(snap, realBboxCoords)) {
- objTarget = OBJDATA[i];
- }
- }
- if (objTarget !== false) {
- if (typeof (binder) != 'undefined' && (binder.type == 'segment')) {
- binder.graph.remove();
- delete binder;
- cursor('default');
- }
- if (objTarget.params.bindBox) { // OBJ -> BOUNDINGBOX TOOL
- if (typeof (binder) == 'undefined') {
- binder = new editor.obj2D("free", "boundingBox", "", objTarget.bbox.origin, objTarget.angle, 0, objTarget.size, "normal", objTarget.thick, objTarget.realBbox);
- binder.update();
- binder.obj = objTarget;
- binder.type = 'boundingBox';
- binder.oldX = binder.x;
- binder.oldY = binder.y;
- $('#boxbind').append(binder.graph);
- if (!objTarget.params.move) cursor('trash'); // LIKE MEASURE ON PLAN
- if (objTarget.params.move) cursor('move');
- }
- }
- else { // DOOR, WINDOW, APERTURE.. -- OBJ WITHOUT BINDBOX (params.bindBox = False) -- !!!!
- if (typeof (binder) == 'undefined') {
- var wallList = editor.rayCastingWall(objTarget);
- if (wallList.length > 1) wallList = wallList[0];
- inWallRib(wallList);
- var thickObj = wallList.thick;
- var sizeObj = objTarget.size;
- binder = new editor.obj2D("inWall", "socle", "", objTarget, objTarget.angle, 0, sizeObj, "normal", thickObj);
- binder.update();
- binder.oldXY = { x: objTarget.x, y: objTarget.y }; // FOR OBJECT MENU
- $('#boxbind').append(binder.graph);
- }
- else {
- // Guard against cases where binder may not have a graph (e.g., binder is a simple SVG element from other modes)
- var hasBinderGraph = (typeof binder.graph !== 'undefined') &&
- (typeof binder.graph.get === 'function') &&
- binder.graph.get(0) &&
- binder.graph.get(0).firstChild;
- if (hasBinderGraph && event.target == binder.graph.get(0).firstChild) {
- cursor('move');
- binder.graph.get(0).firstChild.setAttribute("class", "circle_css_2");
- binder.type = "obj";
- binder.obj = objTarget;
- }
- else {
- cursor('default');
- if (hasBinderGraph) {
- binder.graph.get(0).firstChild.setAttribute("class", "circle_css_1");
- }
- binder.type = false;
- }
- }
- }
- }
- else {
- if (typeof (binder) != 'undefined') {
- if (typeof (binder.graph) != 'undefined') binder.graph.remove();
- if (binder.type == 'node') binder.remove();
- delete binder;
- cursor('default');
- rib();
- }
- }
- // BIND CIRCLE IF nearNode and GROUP ALL SAME XY SEG POINTS
- if (wallNode = editor.nearWallNode(snap, 20)) {
- if (typeof (binder) == 'undefined' || binder.type == 'segment') {
- binder = qSVG.create('boxbind', 'circle', {
- id: "circlebinder",
- class: "circle_css_2",
- cx: wallNode.x,
- cy: wallNode.y,
- r: Rcirclebinder
- });
- binder.data = wallNode;
- binder.type = "node";
- if ($('#linebinder').length) $('#linebinder').remove();
- } else {
- // REMAKE CIRCLE_CSS ON BINDER AND TAKE DATA SEG GROUP
- // if (typeof(binder) != 'undefined') {
- // binder.attr({
- // class: "circle_css_2"
- // });
- // }
- }
- cursor('move');
- } else {
- if (typeof (binder) != "undefined" && binder.type == 'node') {
- binder.remove();
- delete binder;
- hideAllSize();
- cursor('default');
- rib();
- }
- }
- // BIND WALL WITH NEARPOINT function ---> WALL BINDER CREATION
- if (wallBind = editor.rayCastingWalls(snap, WALLS)) {
- if (wallBind.length > 1) wallBind = wallBind[wallBind.length - 1];
- if (wallBind && typeof (binder) == 'undefined') {
- var objWall = editor.objFromWall(wallBind);
- if (objWall.length > 0) editor.inWallRib2(wallBind);
- binder = {};
- binder.wall = wallBind;
- inWallRib(binder.wall);
- var line = qSVG.create('none', 'line', {
- x1: binder.wall.start.x, y1: binder.wall.start.y, x2: binder.wall.end.x, y2: binder.wall.end.y,
- "stroke-width": 5,
- stroke: "#5cba79"
- });
- var ball1 = qSVG.create('none', 'circle', {
- class: "circle_css",
- cx: binder.wall.start.x, cy: binder.wall.start.y,
- r: Rcirclebinder / 1.8
- });
- var ball2 = qSVG.create('none', 'circle', {
- class: "circle_css",
- cx: binder.wall.end.x, cy: binder.wall.end.y,
- r: Rcirclebinder / 1.8
- });
- binder.graph = qSVG.create('none', 'g');
- binder.graph.append(line);
- binder.graph.append(ball1);
- binder.graph.append(ball2);
- $('#boxbind').append(binder.graph);
- binder.type = "segment";
- cursor('pointer');
- }
- } else {
- if (wallBind = editor.nearWall(snap, 6)) {
- if (wallBind && typeof (binder) == 'undefined') {
- wallBind = wallBind.wall;
- var objWall = editor.objFromWall(wallBind);
- if (objWall.length > 0) editor.inWallRib2(wallBind);
- binder = {};
- binder.wall = wallBind;
- inWallRib(binder.wall);
- var line = qSVG.create('none', 'line', {
- x1: binder.wall.start.x, y1: binder.wall.start.y, x2: binder.wall.end.x, y2: binder.wall.end.y,
- "stroke-width": 5,
- stroke: "#5cba79"
- });
- var ball1 = qSVG.create('none', 'circle', {
- class: "circle_css",
- cx: binder.wall.start.x, cy: binder.wall.start.y,
- r: Rcirclebinder / 1.8
- });
- var ball2 = qSVG.create('none', 'circle', {
- class: "circle_css",
- cx: binder.wall.end.x, cy: binder.wall.end.y,
- r: Rcirclebinder / 1.8
- });
- binder.graph = qSVG.create('none', 'g');
- binder.graph.append(line);
- binder.graph.append(ball1);
- binder.graph.append(ball2);
- $('#boxbind').append(binder.graph);
- binder.type = "segment";
- cursor('pointer');
- }
- }
- else {
- if (typeof (binder) != "undefined" && binder.type == 'segment') {
- binder.graph.remove();
- delete binder;
- hideAllSize();
- cursor('default');
- rib();
- }
- }
- }
- } // END mode == 'select_mode' && drag == 'off'
- //**************************************************************************
- //************** FURNITURE PLACEMENT MODE ***************************
- //**************************************************************************
-
- if (mode == 'furniture_placement_mode') {
- snap = calcul_snap(event, grid_snap);
- updateFurnitureCursor(snap.x, snap.y);
- cursor('none');
- }
- // ------------------------------ LINE MODE ------------------------------------------------------
- if ((mode == 'line_mode' || mode == 'partition_mode') && action == 0) {
- snap = calcul_snap(event, 'off');
- cursor('grab');
- pox = snap.x;
- poy = snap.y;
- if (helpConstruc = intersection(snap, 25)) {
- if (helpConstruc.distance < 10) {
- pox = helpConstruc.x;
- poy = helpConstruc.y;
- cursor('grab');
- } else {
- cursor('crosshair');
- }
- }
- if (wallNode = editor.nearWallNode(snap, 20)) {
- pox = wallNode.x;
- poy = wallNode.y;
- cursor('grab');
- if (typeof (binder) == 'undefined') {
- binder = qSVG.create('boxbind', 'circle', {
- id: "circlebinder",
- class: "circle_css_2",
- cx: wallNode.x,
- cy: wallNode.y,
- r: Rcirclebinder / 1.5
- });
- }
- intersectionOff();
- } else {
- if (!helpConstruc) cursor('crosshair');
- if (typeof (binder) != "undefined") {
- if (binder.graph) binder.graph.remove();
- else binder.remove();
- delete binder;
- }
- }
- }
- // ******************************************************************************************************
- // ************************** ACTION = 1 LINE MODE => WALL CREATE *********************
- // ******************************************************************************************************
- if (action == 1 && (mode == 'line_mode' || mode == 'partition_mode')) {
- snap = calcul_snap(event, grid_snap);
- x = snap.x;
- y = snap.y;
- starter = minMoveGrid(snap);
- if (!$('#line_construc').length) {
- if (wallNode = editor.nearWallNode(snap, 20)) {
- pox = wallNode.x;
- poy = wallNode.y;
- wallStartConstruc = false;
- if (wallNode.bestWall == WALLS.length - 1) {
- cursor('validation');
- }
- else {
- cursor('grab');
- }
- } else {
- cursor('crosshair');
- }
- }
- if (starter > grid) {
- if (!$('#line_construc').length) {
- var ws = 20;
- if (mode == 'partition_mode') ws = 10;
- lineconstruc = qSVG.create("boxbind", "line", {
- id: "line_construc",
- x1: pox,
- y1: poy,
- x2: x,
- y2: y,
- "stroke-width": ws,
- "stroke-linecap": "butt",
- "stroke-opacity": 0.7,
- stroke: "#9fb2e2"
- });
- svgadd = qSVG.create("boxbind", "line", { // ORANGE TEMP LINE FOR ANGLE 0 90 45 -+
- id: "linetemp",
- x1: pox,
- y1: poy,
- x2: x,
- y2: y,
- "stroke": "transparent",
- "stroke-width": 0.5,
- "stroke-opacity": "0.9"
- });
- } else { // THE LINES AND BINDER ARE CREATED
- $('#linetemp').attr({
- x2: x,
- y2: y
- });
- if (helpConstrucEnd = intersection(snap, 10)) {
- x = helpConstrucEnd.x;
- y = helpConstrucEnd.y;
- }
- if (wallEndConstruc = editor.nearWall(snap, 12)) { // TO SNAP SEGMENT TO FINALIZE X2Y2
- x = wallEndConstruc.x;
- y = wallEndConstruc.y;
- cursor('grab');
- } else {
- cursor('crosshair');
- }
- // nearNode helped to attach the end of the construc line
- if (wallNode = editor.nearWallNode(snap, 20)) {
- if (typeof (binder) == 'undefined') {
- binder = qSVG.create('boxbind', 'circle', {
- id: "circlebinder",
- class: "circle_css_2",
- cx: wallNode.x,
- cy: wallNode.y,
- r: Rcirclebinder / 1.5
- });
- }
- $('#line_construc').attr({
- x2: wallNode.x,
- y2: wallNode.y
- });
- x = wallNode.x;
- y = wallNode.y;
- wallEndConstruc = true;
- intersectionOff();
- if (wallNode.bestWall == WALLS.length - 1 && document.getElementById("multi").checked) {
- cursor('validation');
- }
- else {
- cursor('grab');
- }
- } else {
- if (typeof (binder) != "undefined") {
- binder.remove();
- delete binder;
- }
- if (wallEndConstruc === false) cursor('crosshair');
- }
- // LINETEMP AND LITLLE SNAPPING FOR HELP TO CONSTRUC ANGLE 0 90 45 *****************************************
- var fltt = qSVG.angle(pox, poy, x, y);
- var flt = Math.abs(fltt.deg);
- var coeff = fltt.deg / flt; // -45 -> -1 45 -> 1
- var phi = poy - (coeff * pox);
- var Xdiag = (y - phi) / coeff;
- if (typeof (binder) == 'undefined') {
- // HELP FOR H LINE
- var found = false;
- if (flt < 15 && Math.abs(poy - y) < 25) {
- y = poy;
- found = true;
- } // HELP FOR V LINE
- if (flt > 75 && Math.abs(pox - x) < 25) {
- x = pox;
- found = true;
- } // HELP FOR DIAG LINE
- if (flt < 55 && flt > 35 && Math.abs(Xdiag - x) < 20) {
- x = Xdiag;
- found = true;
- }
- if (found) $('#line_construc').attr({ "stroke-opacity": 1 });
- else $('#line_construc').attr({ "stroke-opacity": 0.7 });
- }
- $('#line_construc').attr({
- x2: x,
- y2: y
- });
- // SHOW WALL SIZE -------------------------------------------------------------------------
- var startText = qSVG.middle(pox, poy, x, y);
- var angleText = qSVG.angle(pox, poy, x, y);
- var valueText = ((qSVG.measure({
- x: pox,
- y: poy
- }, {
- x: x,
- y: y
- })) / 60).toFixed(2);
- if (typeof (lengthTemp) == 'undefined') {
- lengthTemp = document.createElementNS('http://www.w3.org/2000/svg', 'text');
- lengthTemp.setAttributeNS(null, 'x', startText.x);
- lengthTemp.setAttributeNS(null, 'y', (startText.y) - 15);
- lengthTemp.setAttributeNS(null, 'text-anchor', 'middle');
- lengthTemp.setAttributeNS(null, 'stroke', 'none');
- lengthTemp.setAttributeNS(null, 'stroke-width', '0.6px');
- lengthTemp.setAttributeNS(null, 'fill', '#777777');
- lengthTemp.textContent = valueText + 'm';
- $('#boxbind').append(lengthTemp);
- }
- if (typeof (lengthTemp) != 'undefined' && valueText > 0.1) {
- lengthTemp.setAttributeNS(null, 'x', startText.x);
- lengthTemp.setAttributeNS(null, 'y', (startText.y) - 15);
- lengthTemp.setAttribute("transform", "rotate(" + angleText.deg + " " + startText.x + "," + startText.y + ")");
- lengthTemp.textContent = valueText + ' m';
- }
- if (typeof (lengthTemp) != 'undefined' && valueText < 0.1) {
- lengthTemp.textContent = "";
- }
- }
- }
- } // END LINE MODE DETECT && ACTION = 1
- //ONMOVE
- // **************************************************************************************************
- // ____ ___ _ _ ____ _____ ____
- // | __ )_ _| \ | | _ \| ____| _ \
- // | _ \| || \| | | | | _| | |_) |
- // | |_) | || |\ | |_| | |___| _ <
- // |____/___|_| \_|____/|_____|_| \_\
- //
- // **************************************************************************************************
- if (mode == 'bind_mode') {
- snap = calcul_snap(event, grid_snap);
- if (binder.type == 'node') {
- var coords = snap;
- var magnetic = false;
- for (var k in wallListRun) {
- if (isObjectsEquals(wallListRun[k].end, binder.data)) {
- if (Math.abs(wallListRun[k].start.x - snap.x) < 20) { coords.x = wallListRun[k].start.x; magnetic = "H"; }
- if (Math.abs(wallListRun[k].start.y - snap.y) < 20) { coords.y = wallListRun[k].start.y; magnetic = "V"; }
- }
- if (isObjectsEquals(wallListRun[k].start, binder.data)) {
- if (Math.abs(wallListRun[k].end.x - snap.x) < 20) { coords.x = wallListRun[k].end.x; magnetic = "H"; }
- if (Math.abs(wallListRun[k].end.y - snap.y) < 20) { coords.y = wallListRun[k].end.y; magnetic = "V"; }
- }
- }
- if (nodeMove = editor.nearWallNode(snap, 15, wallListRun)) {
- coords.x = nodeMove.x;
- coords.y = nodeMove.y;
- $('#circlebinder').attr({ "class": "circleGum", cx: coords.x, cy: coords.y });
- cursor('grab');
- } else {
- if (magnetic != false) {
- if (magnetic == "H") snap.x = coords.x;
- else snap.y = coords.y;
- }
- if (helpConstruc = intersection(snap, 10, wallListRun)) {
- coords.x = helpConstruc.x;
- coords.y = helpConstruc.y;
- snap.x = helpConstruc.x;
- snap.y = helpConstruc.y;
- if (magnetic != false) {
- if (magnetic == "H") snap.x = coords.x;
- else snap.y = coords.y;
- }
- cursor('grab');
- } else {
- cursor('move');
- }
- binder.remove()
- //$('#circlebinder').attr({"class": "circle_css", cx: coords.x, cy: coords.y});
- }
- for (var k in wallListRun) {
- if (isObjectsEquals(wallListRun[k].start, binder.data)) {
- wallListRun[k].start.x = coords.x;
- wallListRun[k].start.y = coords.y;
- }
- if (isObjectsEquals(wallListRun[k].end, binder.data)) {
- wallListRun[k].end.x = coords.x;
- wallListRun[k].end.y = coords.y;
- }
- }
- binder.data = coords;
- editor.wallsComputing(WALLS, false); // UPDATE FALSE
- for (var k in wallListObj) {
- var wall = wallListObj[k].wall;
- var objTarget = wallListObj[k].obj;
- var angleWall = qSVG.angleDeg(wall.start.x, wall.start.y, wall.end.x, wall.end.y);
- var limits = limitObj(wall.equations.base, 2 * wallListObj[k].distance, wallListObj[k].from); // COORDS OBJ AFTER ROTATION
- var indexLimits = 0;
- if (qSVG.btwn(limits[1].x, wall.start.x, wall.end.x) && qSVG.btwn(limits[1].y, wall.start.y, wall.end.y)) indexLimits = 1;
- // NEW COORDS OBJDATA[obj]
- objTarget.x = limits[indexLimits].x;
- objTarget.y = limits[indexLimits].y;
- objTarget.angle = angleWall;
- if (objTarget.angleSign == 1) objTarget.angle = angleWall + 180;
- var limitBtwn = limitObj(wall.equations.base, objTarget.size, objTarget); // OBJ SIZE OK BTWN xy1/xy2
- if (qSVG.btwn(limitBtwn[0].x, wall.start.x, wall.end.x) && qSVG.btwn(limitBtwn[0].y, wall.start.y, wall.end.y) && qSVG.btwn(limitBtwn[1].x, wall.start.x, wall.end.x) && qSVG.btwn(limitBtwn[1].y, wall.start.y, wall.end.y)) {
- objTarget.limit = limitBtwn;
- objTarget.update();
- }
- else {
- objTarget.graph.remove();
- delete objTarget;
- OBJDATA.splice(wall.indexObj, 1);
- wallListObj.splice(k, 1);
- }
- }
- // for (k in toClean)
- $('#boxRoom').empty();
- $('#boxSurface').empty();
- Rooms = qSVG.polygonize(WALLS);
- editor.roomMaker(Rooms);
- }
- // WALL MOVING ----BINDER TYPE SEGMENT-------- FUNCTION FOR H,V and Calculate Vectorial Translation
- if (binder.type == 'segment' && action == 1) {
- rib();
- if (equation2.A == 'v') { equation2.B = snap.x; }
- else if (equation2.A == 'h') { equation2.B = snap.y; }
- else { equation2.B = snap.y - (snap.x * equation2.A); }
- var intersection1 = qSVG.intersectionOfEquations(equation1, equation2, "obj");
- var intersection2 = qSVG.intersectionOfEquations(equation2, equation3, "obj");
- var intersection3 = qSVG.intersectionOfEquations(equation1, equation3, "obj");
- if (binder.wall.parent != null) {
- if (isObjectsEquals(binder.wall.parent.end, binder.wall.start)) binder.wall.parent.end = intersection1;
- else if (isObjectsEquals(binder.wall.parent.start, binder.wall.start)) binder.wall.parent.start = intersection1;
- else binder.wall.parent.end = intersection1;
- }
- if (binder.wall.child != null) {
- if (isObjectsEquals(binder.wall.child.start, binder.wall.end)) binder.wall.child.start = intersection2;
- else if (isObjectsEquals(binder.wall.child.end, binder.wall.end)) binder.wall.child.end = intersection2;
- else binder.wall.child.start = intersection2;
- }
- binder.wall.start = intersection1;
- binder.wall.end = intersection2;
- binder.graph.remove()
- // binder.graph[0].children[0].setAttribute("x1",intersection1.x);
- // binder.graph[0].children[0].setAttribute("x2",intersection2.x);
- // binder.graph[0].children[0].setAttribute("y1",intersection1.y);
- // binder.graph[0].children[0].setAttribute("y2",intersection2.y);
- // binder.graph[0].children[1].setAttribute("cx",intersection1.x);
- // binder.graph[0].children[1].setAttribute("cy",intersection1.y);
- // binder.graph[0].children[2].setAttribute("cx",intersection2.x);
- // binder.graph[0].children[2].setAttribute("cy",intersection2.y);
- // THE EQ FOLLOWED BY eq (PARENT EQ1 --- CHILD EQ3)
- if (equation1.follow != undefined) {
- if (!qSVG.rayCasting(intersection1, equation1.backUp.coords)) { // IF OUT OF WALL FOLLOWED
- var distanceFromStart = qSVG.gap(equation1.backUp.start, intersection1);
- var distanceFromEnd = qSVG.gap(equation1.backUp.end, intersection1);
- if (distanceFromStart > distanceFromEnd) { // NEAR FROM End
- equation1.follow.end = intersection1;
- }
- else {
- equation1.follow.start = intersection1;
- }
- }
- else {
- equation1.follow.end = equation1.backUp.end;
- equation1.follow.start = equation1.backUp.start;
- }
- }
- if (equation3.follow != undefined) {
- if (!qSVG.rayCasting(intersection2, equation3.backUp.coords)) { // IF OUT OF WALL FOLLOWED
- var distanceFromStart = qSVG.gap(equation3.backUp.start, intersection2);
- var distanceFromEnd = qSVG.gap(equation3.backUp.end, intersection2);
- if (distanceFromStart > distanceFromEnd) { // NEAR FROM End
- equation3.follow.end = intersection2;
- }
- else {
- equation3.follow.start = intersection2;
- }
- }
- else {
- equation3.follow.end = equation3.backUp.end;
- equation3.follow.start = equation3.backUp.start;
- }
- }
- // EQ FOLLOWERS WALL MOVING
- for (var i = 0; i < equationFollowers.length; i++) {
- var intersectionFollowers = qSVG.intersectionOfEquations(equationFollowers[i].eq, equation2, "obj");
- if (qSVG.btwn(intersectionFollowers.x, binder.wall.start.x, binder.wall.end.x, 'round') && qSVG.btwn(intersectionFollowers.y, binder.wall.start.y, binder.wall.end.y, 'round')) {
- var size = qSVG.measure(equationFollowers[i].wall.start, equationFollowers[i].wall.end);
- if (equationFollowers[i].type == "start") {
- equationFollowers[i].wall.start = intersectionFollowers;
- }
- if (equationFollowers[i].type == "end") {
- equationFollowers[i].wall.end = intersectionFollowers;
- // Note: Wall deletion is now deferred until mouse release to prevent premature deletion
- }
- }
- }
- // WALL COMPUTING, BLOCK FAMILY OF BINDERWALL IF NULL (START OR END) !!!!!
- editor.wallsComputing(WALLS, "move");
- Rooms = qSVG.polygonize(WALLS);
-
- // Re-append all door/window objects to ensure they stay in boxcarpentry after wall computing
- for (var objIdx = 0; objIdx < OBJDATA.length; objIdx++) {
- var obj = OBJDATA[objIdx];
- if (obj && obj.graph && obj.family === 'inWall') {
- obj.graph.remove();
- $('#boxcarpentry').append(obj.graph);
- }
- }
- // OBJDATA(s) FOLLOW 90° EDGE SELECTED
- for (var rp = 0; rp < equationsObj.length; rp++) {
- var objTarget = equationsObj[rp].obj;
- var intersectionObj = qSVG.intersectionOfEquations(equationsObj[rp].eq, equation2);
- // NEW COORDS OBJDATA[o]
- objTarget.x = intersectionObj[0];
- objTarget.y = intersectionObj[1];
- var limits = limitObj(equation2, objTarget.size, objTarget);
- if (qSVG.btwn(limits[0].x, binder.wall.start.x, binder.wall.end.x) && qSVG.btwn(limits[0].y, binder.wall.start.y, binder.wall.end.y) && qSVG.btwn(limits[1].x, binder.wall.start.x, binder.wall.end.x) && qSVG.btwn(limits[1].y, binder.wall.start.y, binder.wall.end.y)) {
- objTarget.limit = limits;
- objTarget.update();
- // Re-append to ensure doors/windows stay on top after wall movement
- if (objTarget.graph) {
- objTarget.graph.remove();
- $('#boxcarpentry').append(objTarget.graph);
- }
- }
- }
- // HANDLE ALL INWALL OBJECTS - INCLUDING DETACHED ONES
- // First pass: handle objects currently attached to walls
- for (var k in WALLS) {
- var objWall = editor.objFromWall(WALLS[k]); // LIST OBJ ON EDGE
- for (var ob in objWall) {
- var objTarget = objWall[ob];
- var eq = editor.createEquationFromWall(WALLS[k]);
- var limits = limitObj(eq, objTarget.size, objTarget);
- if (!qSVG.btwn(limits[0].x, WALLS[k].start.x, WALLS[k].end.x) || !qSVG.btwn(limits[0].y, WALLS[k].start.y, WALLS[k].end.y) || !qSVG.btwn(limits[1].x, WALLS[k].start.x, WALLS[k].end.x) || !qSVG.btwn(limits[1].y, WALLS[k].start.y, WALLS[k].end.y)) {
- // Try to resize the door/window to fit the wall instead of deleting it
- var wallLength = qSVG.measure(WALLS[k].start, WALLS[k].end);
- var maxObjectSize = wallLength - 20; // Leave some margin
-
- if (maxObjectSize > 20) { // Minimum viable size for door/window
- objTarget.size = maxObjectSize;
- var newLimits = limitObj(eq, objTarget.size, objTarget);
-
- // Check if resized object fits
- if (qSVG.btwn(newLimits[0].x, WALLS[k].start.x, WALLS[k].end.x) && qSVG.btwn(newLimits[0].y, WALLS[k].start.y, WALLS[k].end.y) && qSVG.btwn(newLimits[1].x, WALLS[k].start.x, WALLS[k].end.x) && qSVG.btwn(newLimits[1].y, WALLS[k].start.y, WALLS[k].end.y)) {
- objTarget.limit = newLimits;
- objTarget.update();
- // Re-append to maintain proper layering
- if (objTarget.graph) {
- objTarget.graph.remove();
- $('#boxcarpentry').append(objTarget.graph);
- }
- } else {
- // If resizing doesn't work, delete the object
- var indexObj = OBJDATA.indexOf(objTarget);
- objTarget.graph.remove();
- if (indexObj !== -1) {
- OBJDATA.splice(indexObj, 1);
- }
- }
- } else {
- // Wall too small, delete the object
- var indexObj = OBJDATA.indexOf(objTarget);
- objTarget.graph.remove();
- if (indexObj !== -1) {
- OBJDATA.splice(indexObj, 1);
- }
- }
- }
- }
- }
-
- // Second pass: handle detached inWall objects (not found by objFromWall)
- var objectsToRemove = [];
- for (var objIdx = 0; objIdx < OBJDATA.length; objIdx++) {
- var obj = OBJDATA[objIdx];
- if (obj && obj.family === 'inWall') {
- var isAttachedToWall = false;
- var bestWall = null;
- var bestDistance = Infinity;
- var bestPosition = null;
-
- // Check if object is attached to any wall
- for (var wallIdx in WALLS) {
- var wall = WALLS[wallIdx];
- var eq = qSVG.createEquation(wall.start.x, wall.start.y, wall.end.x, wall.end.y);
- var nearPoint = qSVG.nearPointOnEquation(eq, obj);
-
- if (nearPoint.distance < 0.01 && qSVG.btwn(obj.x, wall.start.x, wall.end.x) && qSVG.btwn(obj.y, wall.start.y, wall.end.y)) {
- isAttachedToWall = true;
- break;
- }
-
- // Track closest wall for potential re-attachment
- if (nearPoint.distance < bestDistance && qSVG.btwn(nearPoint.x, wall.start.x, wall.end.x) && qSVG.btwn(nearPoint.y, wall.start.y, wall.end.y)) {
- bestDistance = nearPoint.distance;
- bestWall = wall;
- bestPosition = { x: nearPoint.x, y: nearPoint.y };
- }
- }
-
- // If object is detached, try to re-attach or remove it
- if (!isAttachedToWall) {
- if (bestWall && bestDistance < 50) { // Within 50px of a wall
- var wallLength = qSVG.measure(bestWall.start, bestWall.end);
- var maxObjectSize = wallLength - 20;
-
- // Check if there's enough space on the wall
- if (maxObjectSize >= obj.size || (maxObjectSize > 20 && obj.size > maxObjectSize)) {
- // Re-attach to the closest wall
- obj.x = bestPosition.x;
- obj.y = bestPosition.y;
-
- // Resize if necessary
- if (obj.size > maxObjectSize && maxObjectSize > 20) {
- obj.size = maxObjectSize;
- }
-
- // Update object position and limits
- var eq = editor.createEquationFromWall(bestWall);
- var limits = limitObj(eq, obj.size, obj);
- obj.limit = limits;
- obj.update();
-
- // Re-append to maintain proper layering
- if (obj.graph) {
- obj.graph.remove();
- $('#boxcarpentry').append(obj.graph);
- }
- } else {
- // Wall too small, mark for removal
- objectsToRemove.push(objIdx);
- }
- } else {
- // No suitable wall found, mark for removal
- objectsToRemove.push(objIdx);
- }
- }
- }
- }
-
- // Remove objects that couldn't be re-attached (in reverse order to maintain indices)
- for (var i = objectsToRemove.length - 1; i >= 0; i--) {
- var objIndex = objectsToRemove[i];
- if (OBJDATA[objIndex] && OBJDATA[objIndex].graph) {
- OBJDATA[objIndex].graph.remove();
- }
- OBJDATA.splice(objIndex, 1);
- }
- equationsObj = []; // REINIT eqObj -> MAYBE ONE OR PLUS OF OBJDATA REMOVED !!!!
- var objWall = editor.objFromWall(binder.wall); // LIST OBJ ON EDGE
- for (var ob = 0; ob < objWall.length; ob++) {
- var objTarget = objWall[ob];
- equationsObj.push({ obj: objTarget, wall: binder.wall, eq: qSVG.perpendicularEquation(equation2, objTarget.x, objTarget.y) });
- }
- $('#boxRoom').empty();
- $('#boxSurface').empty();
- editor.roomMaker(Rooms);
- $('#lin').css('cursor', 'pointer');
- }
- // **********************************************************************
- // ---------------------- BOUNDING BOX ------------------------------
- // **********************************************************************
- // binder.obj.params.move ---> FOR MEASURE DONT MOVE
- if (binder.type == 'boundingBox' && action == 1 && binder.obj.params.move) {
- binder.x = snap.x;
- binder.y = snap.y;
- binder.obj.x = snap.x;
- binder.obj.y = snap.y;
- binder.obj.update();
- binder.update();
- }
- // **********************************************************************
- // OBJ MOVING
- // **********************************************************************
- if (binder.type == 'obj' && action == 1) {
- if (wallSelect = editor.nearWall(snap)) {
- if (wallSelect.wall.type != 'separate') {
- inWallRib(wallSelect.wall);
- var objTarget = binder.obj;
- var wall = wallSelect.wall;
- var angleWall = qSVG.angleDeg(wall.start.x, wall.start.y, wall.end.x, wall.end.y);
- var v1 = qSVG.vectorXY({ x: wall.start.x, y: wall.start.y }, { x: wall.end.x, y: wall.end.y });
- var v2 = qSVG.vectorXY({ x: wall.end.x, y: wall.end.y }, snap);
- var newAngle = qSVG.vectorDeter(v1, v2);
- binder.angleSign = 0;
- objTarget.angleSign = 0;
- if (Math.sign(newAngle) == 1) {
- angleWall += 180;
- binder.angleSign = 1;
- objTarget.angleSign = 1;
- }
- var limits = limitObj(wall.equations.base, binder.size, wallSelect);
- if (qSVG.btwn(limits[0].x, wall.start.x, wall.end.x) && qSVG.btwn(limits[0].y, wall.start.y, wall.end.y) && qSVG.btwn(limits[1].x, wall.start.x, wall.end.x) && qSVG.btwn(limits[1].y, wall.start.y, wall.end.y)) {
- binder.x = wallSelect.x;
- binder.y = wallSelect.y;
- binder.angle = angleWall;
- binder.thick = wall.thick;
- objTarget.x = wallSelect.x;
- objTarget.y = wallSelect.y;
- objTarget.angle = angleWall;
- objTarget.thick = wall.thick;
- objTarget.limit = limits;
- binder.update();
- objTarget.update();
- }
- if ((wallSelect.x == wall.start.x && wallSelect.y == wall.start.y) || (wallSelect.x == wall.end.x && wallSelect.y == wall.end.y)) {
- if (qSVG.btwn(limits[0].x, wall.start.x, wall.end.x) && qSVG.btwn(limits[0].y, wall.start.y, wall.end.y)) {
- binder.x = limits[0].x;
- binder.y = limits[0].y;
- objTarget.x = limits[0].x;
- objTarget.y = limits[0].y;
- objTarget.limit = limits;
- }
- if (qSVG.btwn(limits[1].x, wall.start.x, wall.end.x) && qSVG.btwn(limits[1].y, wall.start.y, wall.end.y)) {
- binder.x = limits[1].x;
- binder.y = limits[1].y;
- objTarget.x = limits[1].x;
- objTarget.y = limits[1].y;
- objTarget.limit = limits;
- }
- binder.angle = angleWall;
- binder.thick = wall.thick;
- objTarget.angle = angleWall;
- objTarget.thick = wall.thick;
- binder.update();
- objTarget.update();
- }
- }
- }
- } // END OBJ MOVE
- if (binder.type != 'obj' && binder.type != 'segment') rib();
- }
- // ENDBIND ACTION MOVE **************************************************************************
- // ---DRAG VIEWBOX PANNING -------------------------------------------------------
- // Check if background image tools are open - if so, disable global panning
- const backgroundImageToolsOpen = document.getElementById('backgroundImageTools') &&
- document.getElementById('backgroundImageTools').style.display !== 'none' &&
- window.getComputedStyle(document.getElementById('backgroundImageTools')).display !== 'none';
- // Permit panning when floorplan mode is active even if background image tools are open
- const floorplanMode = !!window.__floorplanMode;
- if ((mode == 'select_mode' || mode == 'furniture_placement_mode' || mode == 'furniture_mode') && drag == 'on' && (!backgroundImageToolsOpen || floorplanMode) && !window.draggingFurnitureItem && !window.draggingBackgroundImage) {
- snap = calcul_snap(event, grid_snap);
- $('#lin').css('cursor', 'move');
- distX = (snap.xMouse - pox) * factor;
- distY = (snap.yMouse - poy) * factor;
- // pox = event.pageX;
- // poy = event.pageY;
- zoom_maker('zoomdrag', distX, distY);
- }
- } // END MOUSEMOVE
- // *****************************************************************************************************
- // *****************************************************************************************************
- // *****************************************************************************************************
- // ****************************** MOUSE DOWN *****************************************
- // *****************************************************************************************************
- // *****************************************************************************************************
- // *****************************************************************************************************
- function _MOUSEDOWN(event) {
- event.preventDefault();
- // In floorplan mode, block edits in select mode entirely
- if (window.__floorplanMode && mode === 'select_mode') {
- // Ensure no binder remains
- try {
- if (typeof (binder) !== 'undefined') {
- if (binder.remove) binder.remove();
- else if (binder.graph && binder.graph.remove) binder.graph.remove();
- delete binder;
- }
- $('#boxbind').empty();
- } catch (_) { /* no-op */ }
- return;
- }
- // *******************************************************************
- // ************************** DISTANCE MODE **********************
- // *******************************************************************
- if (mode == 'distance_mode') {
- if (action == 0) {
- action = 1;
- snap = calcul_snap(event, grid_snap);
- pox = snap.x;
- poy = snap.y;
- }
- }
- // *******************************************************************
- // ************************* LINE/WALL MODE **********************
- // *******************************************************************
- if (mode == 'line_mode' || mode == 'partition_mode') {
- if (action == 0) {
- snap = calcul_snap(event, grid_snap);
- pox = snap.x;
- poy = snap.y;
- if (wallStartConstruc = editor.nearWall(snap, 12)) { // TO SNAP SEGMENT TO FINALIZE X2Y2
- pox = wallStartConstruc.x;
- poy = wallStartConstruc.y;
- }
- }
- else {
- // FINALIZE LINE_++
- construc = 1;
- }
- action = 1;
- }
- if (mode == 'edit_door_mode') { // ACTION 1 ACTIVATE EDITION OF THE DOOR
- action = 1;
- $('#lin').css('cursor', 'pointer');
- }
- // *******************************************************************
- // ******************** FURNITURE PLACEMENT MODE ****************
- // *******************************************************************
- if (mode == 'furniture_placement_mode') {
- snap = calcul_snap(event, grid_snap);
- // Begin potential panning; defer placement to mouseup if it's a click (not a drag)
- drag = 'on';
- pox = snap.xMouse;
- poy = snap.yMouse;
- // Remember initial position for click detection
- window._pendingFurniturePlacement = { x: snap.x, y: snap.y, xMouse: snap.xMouse, yMouse: snap.yMouse };
- event.stopPropagation();
- return;
- }
- // *******************************************************************
- // ******************** FURNITURE MODE (PAN) ********************
- // *******************************************************************
- if (mode == 'furniture_mode') {
- // Start panning on mousedown in furniture mode (unless background tools block)
- const bgTools = document.getElementById('backgroundImageTools') &&
- document.getElementById('backgroundImageTools').style.display !== 'none' &&
- window.getComputedStyle(document.getElementById('backgroundImageTools')).display !== 'none';
- // Avoid starting pan when clicking on a furniture item (drag is handled in furniture.js)
- const overFurniture = event.target && (event.target.closest && event.target.closest('.furniture-item'));
- if (!bgTools && !overFurniture) {
- snap = calcul_snap(event, grid_snap);
- drag = 'on';
- pox = snap.xMouse;
- poy = snap.yMouse;
- }
- }
- // *******************************************************************
- // ********************** SELECT MODE + BIND *********************
- // *******************************************************************
- if (mode == 'select_mode') {
- if (typeof (binder) != 'undefined' && (binder.type == 'segment' || binder.type == 'node' || binder.type == 'obj' || binder.type == 'boundingBox')) {
- // In floorplan mode: disable wall/object editing interactions
- if (window.__floorplanMode) {
- // Do not enter bind mode or start edits when aligning to image
- if (typeof $ !== 'undefined') $('#boxinfo').html('Floorplan mode: editing disabled');
- return; // prevent switching to bind_mode
- }
- mode = 'bind_mode';
- if (binder.type == 'obj') {
- action = 1;
- }
- if (binder.type == 'boundingBox') {
- action = 1;
- }
- // INIT FOR HELP BINDER NODE MOVING H V (MOUSE DOWN)
- if (binder.type == 'node') {
- $('#boxScale').hide(100);
- var node = binder.data;
- pox = node.x;
- poy = node.y;
- var nodeControl = { x: pox, y: poy };
- // DETERMINATE DISTANCE OF OPPOSED NODE ON EDGE(s) PARENT(s) OF THIS NODE !!!! NODE 1 -- NODE 2 SYSTE% :-(
- wallListObj = []; // SUPER VAR -- WARNING
- var objWall;
- wallListRun = [];
- for (var ee = WALLS.length - 1; ee > -1; ee--) { // SEARCH MOST YOUNG WALL COORDS IN NODE BINDER
- if (isObjectsEquals(WALLS[ee].start, nodeControl) || isObjectsEquals(WALLS[ee].end, nodeControl)) {
- wallListRun.push(WALLS[ee]);
- break;
- }
- }
- if (wallListRun[0].child != null) {
- if (isObjectsEquals(wallListRun[0].child.start, nodeControl) || isObjectsEquals(wallListRun[0].child.end, nodeControl)) wallListRun.push(wallListRun[0].child);
- }
- if (wallListRun[0].parent != null) {
- if (isObjectsEquals(wallListRun[0].parent.start, nodeControl) || isObjectsEquals(wallListRun[0].parent.end, nodeControl)) wallListRun.push(wallListRun[0].parent);
- }
- for (var k in wallListRun) {
- if (isObjectsEquals(wallListRun[k].start, nodeControl) || isObjectsEquals(wallListRun[k].end, nodeControl)) {
- var nodeTarget = wallListRun[k].start;
- if (isObjectsEquals(wallListRun[k].start, nodeControl)) {
- nodeTarget = wallListRun[k].end;
- }
- objWall = editor.objFromWall(wallListRun[k]); // LIST OBJ ON EDGE -- NOT INDEX !!!
- wall = wallListRun[k];
- for (var ob = 0; ob < objWall.length; ob++) {
- var objTarget = objWall[ob];
- var distance = qSVG.measure(objTarget, nodeTarget);
- wallListObj.push({ wall: wall, from: nodeTarget, distance: distance, obj: objTarget, indexObj: ob });
- }
- }
- }
- magnetic = 0;
- action = 1;
- }
- if (binder.type == 'segment') {
- $('#boxScale').hide(100);
- var wall = binder.wall;
- binder.before = binder.wall.start;
- equation2 = editor.createEquationFromWall(wall);
- if (wall.parent != null) {
- equation1 = editor.createEquationFromWall(wall.parent);
- var angle12 = qSVG.angleBetweenEquations(equation1.A, equation2.A);
- if (angle12 < 20 || angle12 > 160) {
- var found = true;
- for (var k in WALLS) {
- if (qSVG.rayCasting(wall.start, WALLS[k].coords) && !isObjectsEquals(WALLS[k], wall.parent) && !isObjectsEquals(WALLS[k], wall)) {
- if (wall.parent.parent != null && isObjectsEquals(wall, wall.parent.parent)) wall.parent.parent = null;
- if (wall.parent.child != null && isObjectsEquals(wall, wall.parent.child)) wall.parent.child = null;
- wall.parent = null;
- found = false;
- break;
- }
- }
- if (found) {
- var newWall;
- if (isObjectsEquals(wall.parent.end, wall.start, "1")) {
- newWall = new editor.wall(wall.parent.end, wall.start, "normal", wall.thick);
- WALLS.push(newWall);
- newWall.parent = wall.parent;
- newWall.child = wall;
- wall.parent.child = newWall;
- wall.parent = newWall;
- equation1 = qSVG.perpendicularEquation(equation2, wall.start.x, wall.start.y);
- }
- else if (isObjectsEquals(wall.parent.start, wall.start, "2")) {
- newWall = new editor.wall(wall.parent.start, wall.start, "normal", wall.thick);
- WALLS.push(newWall);
- newWall.parent = wall.parent;
- newWall.child = wall;
- wall.parent.parent = newWall;
- wall.parent = newWall;
- equation1 = qSVG.perpendicularEquation(equation2, wall.start.x, wall.start.y);
- }
- // CREATE NEW WALL
- }
- }
- }
- if (wall.parent == null) {
- var foundEq = false;
- for (var k in WALLS) {
- if (qSVG.rayCasting(wall.start, WALLS[k].coords) && !isObjectsEquals(WALLS[k].coords, wall.coords)) {
- var angleFollow = qSVG.angleBetweenEquations(WALLS[k].equations.base.A, equation2.A);
- if (angleFollow < 20 || angleFollow > 160) break;
- equation1 = editor.createEquationFromWall(WALLS[k]);
- equation1.follow = WALLS[k];
- equation1.backUp = {
- coords: WALLS[k].coords,
- start: WALLS[k].start,
- end: WALLS[k].end,
- child: WALLS[k].child,
- parent: WALLS[k].parent
- };
- foundEq = true;
- break;
- }
- }
- if (!foundEq) equation1 = qSVG.perpendicularEquation(equation2, wall.start.x, wall.start.y);
- }
- if (wall.child != null) {
- equation3 = editor.createEquationFromWall(wall.child);
- var angle23 = qSVG.angleBetweenEquations(equation3.A, equation2.A);
- if (angle23 < 20 || angle23 > 160) {
- var found = true;
- for (var k in WALLS) {
- if (qSVG.rayCasting(wall.end, WALLS[k].coords) && !isObjectsEquals(WALLS[k], wall.child) && !isObjectsEquals(WALLS[k], wall)) {
- if (wall.child.parent != null && isObjectsEquals(wall, wall.child.parent)) wall.child.parent = null;
- if (wall.child.child != null && isObjectsEquals(wall, wall.child.child)) wall.child.child = null;
- wall.child = null;
- found = false;
- break;
- }
- }
- if (found) {
- if (isObjectsEquals(wall.child.start, wall.end)) {
- var newWall = new editor.wall(wall.end, wall.child.start, "new", wall.thick);
- WALLS.push(newWall);
- newWall.parent = wall;
- newWall.child = wall.child;
- wall.child.parent = newWall;
- wall.child = newWall;
- equation3 = qSVG.perpendicularEquation(equation2, wall.end.x, wall.end.y);
- }
- else if (isObjectsEquals(wall.child.end, wall.end)) {
- var newWall = new editor.wall(wall.end, wall.child.end, "normal", wall.thick);
- WALLS.push(newWall);
- newWall.parent = wall;
- newWall.child = wall.child;
- wall.child.child = newWall;
- wall.child = newWall;
- equation3 = qSVG.perpendicularEquation(equation2, wall.end.x, wall.end.y);
- }
- // CREATE NEW WALL
- }
- }
- }
- if (wall.child == null) {
- var foundEq = false;
- for (var k in WALLS) {
- if (qSVG.rayCasting(wall.end, WALLS[k].coords) && !isObjectsEquals(WALLS[k].coords, wall.coords, "4")) {
- var angleFollow = qSVG.angleBetweenEquations(WALLS[k].equations.base.A, equation2.A);
- if (angleFollow < 20 || angleFollow > 160) break;
- equation3 = editor.createEquationFromWall(WALLS[k]);
- equation3.follow = WALLS[k];
- equation3.backUp = {
- coords: WALLS[k].coords,
- start: WALLS[k].start,
- end: WALLS[k].end,
- child: WALLS[k].child,
- parent: WALLS[k].parent
- };
- foundEq = true;
- break;
- }
- }
- if (!foundEq) equation3 = qSVG.perpendicularEquation(equation2, wall.end.x, wall.end.y);
- }
- equationFollowers = [];
- for (var k in WALLS) {
- if (WALLS[k].child == null && qSVG.rayCasting(WALLS[k].end, wall.coords) && !isObjectsEquals(wall, WALLS[k])) {
- equationFollowers.push({
- wall: WALLS[k],
- eq: editor.createEquationFromWall(WALLS[k]),
- type: "end"
- });
- }
- if (WALLS[k].parent == null && qSVG.rayCasting(WALLS[k].start, wall.coords) && !isObjectsEquals(wall, WALLS[k])) {
- equationFollowers.push({
- wall: WALLS[k],
- eq: editor.createEquationFromWall(WALLS[k]),
- type: "start"
- });
- }
- }
- equationsObj = [];
- var objWall = editor.objFromWall(wall); // LIST OBJ ON EDGE
- for (var ob = 0; ob < objWall.length; ob++) {
- var objTarget = objWall[ob];
- equationsObj.push({ obj: objTarget, wall: wall, eq: qSVG.perpendicularEquation(equation2, objTarget.x, objTarget.y) });
- }
- action = 1;
- }
- }
- else {
- action = 0;
- drag = 'on';
- snap = calcul_snap(event, grid_snap);
- pox = snap.xMouse;
- poy = snap.yMouse;
- }
- }
- }
- //******************************************************************************************************
- //******************* ***** ****** ************************************************************
- //******************* ***** ****** **** ************************************************************
- //******************* ***** ****** **** ************************************************************
- //******************* ***** ****** ************************************************************
- //******************* ****** ******************************************************************
- //********************************** ******************************************************************
- function _MOUSEUP(event) {
- if (showRib) $('#boxScale').show(200);
- drag = 'off';
- cursor('default');
- // Handle deferred placement from furniture_placement_mode
- if (window._pendingFurniturePlacement) {
- try {
- const snapUp = calcul_snap(event, grid_snap);
- const dx = Math.abs(snapUp.xMouse - window._pendingFurniturePlacement.xMouse);
- const dy = Math.abs(snapUp.yMouse - window._pendingFurniturePlacement.yMouse);
- const moved = Math.sqrt(dx*dx + dy*dy);
- if (moved < 5 && mode === 'furniture_placement_mode') {
- // Consider it a click: place furniture at original snapped coords
- placeFurnitureItem(window._pendingFurniturePlacement.x, window._pendingFurniturePlacement.y);
- }
- } catch (_) { /* no-op */ }
- window._pendingFurniturePlacement = null;
- }
- if (mode == 'select_mode') {
- if (typeof (binder) != 'undefined') {
- // Handle different binder types properly
- if (binder.type == 'node' && typeof binder.remove === 'function') {
- binder.remove();
- } else if (binder.graph && typeof binder.graph.remove === 'function') {
- binder.graph.remove();
- } else if (typeof binder.remove === 'function') {
- binder.remove();
- }
- delete binder;
- save();
- }
- }
- //**************************************************************************
- //******************** TEXTE MODE **************************************
- //**************************************************************************
- if (mode == 'text_mode') {
- if (action == 0) {
- action = 1;
- const textModal = new bootstrap.Modal($('#textToLayer'))
- textModal.show();
- mode == 'edit_text_mode';
- }
- }
- //**************************************************************************
- //************** OBJECT MODE **************************************
- //**************************************************************************
- if (mode == 'object_mode') {
- OBJDATA.push(binder);
- binder.graph.remove();
- var targetBox = 'boxcarpentry';
- if (OBJDATA[OBJDATA.length - 1].class == 'energy') targetBox = 'boxEnergy';
- if (OBJDATA[OBJDATA.length - 1].class == 'furniture') targetBox = 'boxFurniture';
- $('#' + targetBox).append(OBJDATA[OBJDATA.length - 1].graph);
- delete binder;
- $('#boxinfo').html('Object added');
- fonc_button('select_mode');
- save();
- }
- // *******************************************************************
- // ************************** DISTANCE MODE **********************
- // *******************************************************************
- if (mode == 'distance_mode') {
- if (action == 1) {
- action = 0;
- // MODIFY BBOX FOR BINDER ZONE (TXT)
- var bbox = labelMeasure.get(0).getBoundingClientRect();
- bbox.x = (bbox.x * factor) - (offset.left * factor) + originX_viewbox;
- bbox.y = (bbox.y * factor) - (offset.top * factor) + originY_viewbox;
- bbox.origin = { x: bbox.x + (bbox.width / 2), y: bbox.y + (bbox.height / 2) };
- binder.bbox = bbox;
- binder.realBbox = [
- { x: binder.bbox.x, y: binder.bbox.y }, { x: binder.bbox.x + binder.bbox.width, y: binder.bbox.y }, { x: binder.bbox.x + binder.bbox.width, y: binder.bbox.y + binder.bbox.height }, { x: binder.bbox.x, y: binder.bbox.y + binder.bbox.height }];
- binder.size = binder.bbox.width;
- binder.thick = binder.bbox.height;
- binder.graph.append(labelMeasure);
- OBJDATA.push(binder);
- binder.graph.remove();
- $('#boxcarpentry').append(OBJDATA[OBJDATA.length - 1].graph);
- delete binder;
- delete labelMeasure;
- cross.remove();
- delete cross;
- $('#boxinfo').html('Measure added');
- fonc_button('select_mode');
- save();
- }
- }
- // *******************************************************************
- // ************************** ROOM MODE **************************
- // *******************************************************************
- if (mode == 'room_mode') {
- if (typeof (binder) == "undefined") {
- return false;
- }
- var area = binder.area / 3600;
- binder.attr({ 'fill': 'none', 'stroke': '#ddf00a', 'stroke-width': 7 });
- $('.size').html(area.toFixed(2) + " m²");
- $('#roomIndex').val(binder.id);
- if (ROOM[binder.id].surface != '') $('#roomSurface').val(ROOM[binder.id].surface);
- else $('#roomSurface').val('');
- document.querySelector('#seeArea').checked = ROOM[binder.id].showSurface;
- document.querySelector('#roomBackground').value = ROOM[binder.id].color;
- var roomName = ROOM[binder.id].name;
- document.querySelector('#roomName').value = roomName;
- if (ROOM[binder.id].name != '') {
- document.querySelector('#roomLabel').innerHTML = roomName + ' <span class="caret"></span>';
- }
- else {
- document.querySelector('#roomLabel').innerHTML = 'None <span class="caret"></span>';
- }
- var actionToDo = ROOM[binder.id].action;
- document.querySelector('#' + actionToDo + 'Action').checked = true;
- $('#panel').hide(100);
- $('#roomTools').show('300')
- $('#lin').css('cursor', 'default');
- $('#boxinfo').html('Config. the room');
- mode = 'edit_room_mode';
- save();
- }
- // *******************************************************************
- // ************************** NODE MODE **************************
- // *******************************************************************
- if (mode == 'node_mode') {
- if (typeof (binder) != 'undefined') { // ALSO ON MOUSEUP WITH HAVE CIRCLEBINDER ON ADDPOINT
- var newWall = new editor.wall({ x: binder.data.x, y: binder.data.y }, binder.data.wall.end, "normal", binder.data.wall.thick);
- WALLS.push(newWall);
- binder.data.wall.end = { x: binder.data.x, y: binder.data.y };
- binder.remove();
- delete binder;
- editor.architect(WALLS);
- save();
- }
- fonc_button('select_mode');
- }
- // ******************************************************************* ***** **** ******* ****** ****** *****
- // ************************** OBJ MODE *************************** * * ******* ***** ****** ****** **
- // ******************************************************************* ***** **** ****** ****** ****** ***
- if (mode == 'door_mode') {
- if (typeof (binder) == "undefined") {
- $('#boxinfo').html('The plan currently contains no wall.');
- fonc_button('select_mode');
- return false;
- }
- OBJDATA.push(binder);
- binder.graph.remove();
- $('#boxcarpentry').append(OBJDATA[OBJDATA.length - 1].graph);
- delete binder;
- $('#boxinfo').html('Element added');
- fonc_button('select_mode');
- save();
- }
- // *******************************************************************
- // ******************** LINE MODE MOUSE UP ***********************
- // *******************************************************************
- if (mode == 'line_mode' || mode == 'partition_mode') {
- $('#linetemp').remove(); // DEL LINE HELP CONSTRUC 0 45 90
- intersectionOff();
- var sizeWall = qSVG.measure({ x: x, y: y }, { x: pox, y: poy });
- sizeWall = sizeWall / meter;
- if ($('#line_construc').length && sizeWall > 0.3) {
- var sizeWall = wallSize;
- if (mode == 'partition_mode') sizeWall = partitionSize;
- var wall = new editor.wall({ x: pox, y: poy }, { x: x, y: y }, "normal", sizeWall);
- WALLS.push(wall);
- editor.architect(WALLS);
- if (document.getElementById("multi").checked && !wallEndConstruc) {
- cursor('validation');
- action = 1;
- }
- else action = 0;
- $('#boxinfo').html('Wall added <span style=\'font-size:0.6em\'>Moy. ' + (qSVG.measure(
- { x: pox, y: poy }, { x: x, y: y }) / 60).toFixed(2) + ' m</span>');
- $('#line_construc').remove(); // DEL LINE CONSTRUC HELP TO VIEW NEW SEG PATH
- lengthTemp.remove();
- delete lengthTemp;
- construc = 0;
- if (wallEndConstruc) action = 0;
- delete wallEndConstruc;
- pox = x;
- poy = y;
- save();
- }
- else {
- action = 0;
- construc = 0;
- $('#boxinfo').html('Select mode');
- fonc_button('select_mode');
- if (typeof (binder) != 'undefined') {
- binder.remove();
- delete binder;
- }
- snap = calcul_snap(event, grid_snap);
- pox = snap.x;
- poy = snap.y;
- }
- }
- // **************************** END LINE MODE MOUSE UP **************************
- //**************************************************************************************
- //********************** BIND MODE MOUSE UP ************************************
- //**************************************************************************************
- if (mode == 'bind_mode') {
- action = 0;
- construc = 0; // CONSTRUC 0 TO FREE BINDER GROUP NODE WALL MOVING
- if (typeof (binder) != 'undefined') {
- fonc_button('select_mode');
- if (binder.type == 'node') {
- // Check for zero-length walls after node movement and clean them up
- var wallsToDelete = [];
- for (var k in WALLS) {
- var wallSize = qSVG.measure(WALLS[k].start, WALLS[k].end);
- if (wallSize < 1) {
- wallsToDelete.push(WALLS[k]);
- }
- }
-
- // Delete zero-length walls with proper cleanup
- for (var d = 0; d < wallsToDelete.length; d++) {
- var wallToDelete = wallsToDelete[d];
- // Clean up parent/child references before deletion
- for (var cleanK in WALLS) {
- if (isObjectsEquals(WALLS[cleanK].child, wallToDelete)) WALLS[cleanK].child = null;
- if (isObjectsEquals(WALLS[cleanK].parent, wallToDelete)) WALLS[cleanK].parent = null;
- }
- // Remove the wall's visual representation
- if (wallToDelete.graph) wallToDelete.graph.remove();
- // Remove from WALLS array
- WALLS.splice(WALLS.indexOf(wallToDelete), 1);
- }
-
- // Clean up any lingering UI elements
- $('#circlebinder').remove();
- $('#boxbind').empty();
-
- // Rebuild architecture if walls were deleted
- if (wallsToDelete.length > 0) {
- editor.architect(WALLS);
- }
- } // END BINDER NODE
- if (binder.type == 'segment') {
- var found = false;
- if (binder.wall.start == binder.before) {
- found = true;
- }
- if (found) {
- $('#panel').hide(100);
- var objWall = editor.objFromWall(wallBind);
- $('#boxinfo').html('Modify a wall<br/><span style="font-size:0.7em;color:#de9b43">This wall can\'t become a separation (contains doors or windows) !</span>');
- if (objWall.length > 0) $('#separate').hide();
- else if (binder.wall.type == 'separate') {
- $('#separate').hide();
- $('#rangeThick').hide();
- $('#recombine').show();
- $('#cutWall').hide();
- document.getElementById('titleWallTools').textContent = "Modify the separation";
- }
- else {
- $('#cutWall').show();
- $('#separate').show();
- $('#rangeThick').show();
- $('#recombine').hide();
- document.getElementById('titleWallTools').textContent = "Modify the wall";
- $('#boxinfo').html('Modify the wall');
- }
- $('#wallTools').show(200);
- document.getElementById('wallWidth').setAttribute('min', 7);
- document.getElementById('wallWidth').setAttribute('max', 50);
- document.getElementById('wallWidthScale').textContent = "7-50";
- document.getElementById("wallWidth").value = binder.wall.thick;
- document.getElementById("wallWidthVal").textContent = binder.wall.thick;
- mode = 'edit_wall_mode';
- }
- delete equation1;
- delete equation2;
- delete equation3;
- delete intersectionFollowers;
- }
- if (binder.type == 'obj') {
- var moveObj = Math.abs(binder.oldXY.x - binder.x) + Math.abs(binder.oldXY.y - binder.y);
- if (moveObj < 1) {
- $('#panel').hide(100);
- $('#objTools').show('200')
- $('#lin').css('cursor', 'default');
- $('#boxinfo').html('Config. the door/window');
- console.log('obj ??')
- document.getElementById('doorWindowWidth').setAttribute('min', binder.obj.params.resizeLimit.width.min);
- document.getElementById('doorWindowWidth').setAttribute('max', binder.obj.params.resizeLimit.width.max);
- document.getElementById('doorWindowWidthScale').textContent = binder.obj.params.resizeLimit.width.min + "-" + binder.obj.params.resizeLimit.width.max;
- document.getElementById("doorWindowWidth").value = binder.obj.size;
- document.getElementById("doorWindowWidthVal").textContent = binder.obj.size;
- mode = 'edit_door_mode';
- }
- else {
- mode = "select_mode";
- action = 0;
- binder.graph.remove();
- delete binder;
- }
- }
- if (typeof (binder) != 'undefined' && binder.type == 'boundingBox') {
- var moveObj = Math.abs(binder.oldX - binder.x) + Math.abs(binder.oldY - binder.y);
- var objTarget = binder.obj;
- if (!objTarget.params.move) {
- // TO REMOVE MEASURE ON PLAN
- objTarget.graph.remove();
- OBJDATA.splice(OBJDATA.indexOf(objTarget), 1);
- $('#boxinfo').html('Measure deleted !');
- }
- if (moveObj < 1 && objTarget.params.move) {
- if (!objTarget.params.resize) $('#objBoundingBoxScale').hide();
- else $('#objBoundingBoxScale').show();
- if (!objTarget.params.rotate) $('#objBoundingBoxRotation').hide();
- else $('#objBoundingBoxRotation').show();
- $('#panel').hide(100);
- console.log(objTarget.params.resizeLimit.width.min)
- $('#objBoundingBox').show('200')
- $('#lin').css('cursor', 'default');
- $('#boxinfo').html('Modify the object');
- console.log(objTarget)
- document.getElementById('bboxWidth').setAttribute('min', objTarget.params.resizeLimit.width.min);
- document.getElementById('bboxWidth').setAttribute('max', objTarget.params.resizeLimit.width.max);
- document.getElementById('bboxWidthScale').textContent = objTarget.params.resizeLimit.width.min + "-" + objTarget.params.resizeLimit.height.max;
- document.getElementById('bboxHeight').setAttribute('min', objTarget.params.resizeLimit.height.min);
- document.getElementById('bboxHeight').setAttribute('max', objTarget.params.resizeLimit.height.max);
- document.getElementById('bboxHeightScale').textContent = objTarget.params.resizeLimit.height.min + "-" + objTarget.params.resizeLimit.height.max;
- $('#stepsCounter').hide();
- if (objTarget.class == 'stair') {
- document.getElementById("bboxStepsVal").textContent = objTarget.value;
- $('#stepsCounter').show();
- }
- document.getElementById("bboxWidth").value = objTarget.width * 100;
- document.getElementById("bboxWidthVal").textContent = objTarget.width * 100;
- document.getElementById("bboxHeight").value = objTarget.height * 100;
- document.getElementById("bboxHeightVal").textContent = objTarget.height * 100;
- document.getElementById("bboxRotation").value = objTarget.angle;
- document.getElementById("bboxRotationVal").textContent = objTarget.angle;
- mode = 'edit_boundingBox_mode';
- }
- else {
- mode = "select_mode";
- action = 0;
- binder.graph.remove();
- delete binder;
- }
- }
- if (mode == 'bind_mode') {
- binder.remove();
- delete binder;
- }
- } // END BIND IS DEFINED
- save();
- } // END BIND MODE
- if (mode != 'edit_room_mode') {
- editor.showScaleBox();
- rib();
- }
- }
|