// Event Listeners scrollBar.on('mouseover', function (evt) { document.body.style.cursor = 'pointer'; evt.target.fill(color.orange); scrollBar.draw(); }); scrollBar.on('mouseout', function (evt) { document.body.style.cursor = 'default'; evt.target.fill("#888"); scrollBar.draw(); }); scrollBar.on('dragmove', function() { const availableWidth = stage.width()-150 - slab_padding * 2 - scrollBar.width(); var delta = (scrollBar.x() - slab_padding) / availableWidth; slabs.x(-(slabs_width + slab_padding-stage.width()+150) * delta); batchDraw(slabs); }); // disable ios pinching document.addEventListener('touchmove', function (e) { if (e.scale !== 1){ e.preventDefault(); } }, false); // disable wheel /*window.addEventListener("wheel", function(e) { e.preventDefault(); }, {passive: false});*/ window.addEventListener("resize", function(e) { fit_to_screen(); gallery_open(undefined); stage.width(window.innerWidth); stage.height(window.innerHeight-head_height-foot_height); }); $('.no-zoom').bind('touchend', function(e) { var now = +(new Date()); if (doubleTouchStartTimestamp + 500 > now){ e.preventDefault(); }; doubleTouchStartTimestamp = now; }); // disable right click window.addEventListener("contextmenu", function(e) { e.preventDefault(); //global_mouseup(e); }); stage.on('mousemove touchmove', function(e) { // fix this fires always rotax_move(null); }); stage.on("mousedown mouseup touchstart touchmove touchend tap dbltap dragstart dragmove dragend wheel", function(e) { //console.log(e.evt.button); if(e.type == "touchstart") touchscreen = true; if(touchscreen) { if( e.type == "touchstart") { on_mousedown(e); } else if( e.type == "dragmove" ) { // pinch zoom if(e.evt.touches[0] && e.evt.touches[1]) { touch_zoom(e); } else { on_dragmove(e); } } else if(e.type == "tap" || e.type == "touchend") { /*var changedTouch = e.evt.changedTouches[0]; e.target = stage.getIntersection({x:changedTouch.clientX, y:changedTouch.clientY}); if(e.target == null) e.target = stage;*/ on_mouseup(e); } } else { // button 0 = left, button 1 = middle, button 2 = right if( e.type == "mousedown") { if( e.evt.button === 2 ) // right mouse { // Move Plan keep_plan = true; document.body.style.cursor = 'move'; $("#toggle_pan").css('color', color.red); on_mousedown(e); } if( e.evt.button === 0 ) // left mouse { on_mousedown(e); } } else if(e.type == "dragmove") { on_dragmove(e); } else if(e.type == "mouseup") { if( e.evt.button === 2 ) // right mouseup { // Stop Move Plan keep_plan = false; document.body.style.cursor = 'default'; $("#toggle_pan").css('color', "#eee"); on_mouseup(e); } if( e.evt.button === 0 ) { on_mouseup(e); } } else if(e.type == "mouseup" && e.evt.button === 2) { on_rightmouseup(e); } else if(e.type == "wheel" && !mouse_is_down) { mouse_zoom(e); } } }); //var hold_shift_before; document.addEventListener('keydown', function(e) // find keyboard { /*if(e.keyCode == 84) { console.log("TEST") var src = transformer._nodes[0]; src.x(src.x()+10); snap_source_position = src.position(); return; }*/ //console.log(e.keyCode); if($(".navi_input").is(':focus')) { if(e.keyCode == 13) //return { // TODO r45 rotate 45 var command = $(".navi_input").val().split(" "); if( (command[0] == "r" || command[0] == "rotate" || command[0] == "rotation" ) && command[1] != null) { if(transformer.attrs.visible) { var angle = command[1].replace(/,/g, '.')%360; if(angle < 0) // Angle Normalisation angle += 360; rotate_by_angle(angle); /*// input angle -180 > 180 last_rotationoffset = calculate_rotationoffset(); rotationoffset = last_rotationoffset; var handle = clip.findOne(node => {return node.attrs.name === "rotax"}); if(handle) { var angle = command[1].replace(/,/g, '.')%360; if(angle < 0) // Angle Normalisation angle += 360; if(hold_shift) { // disable snap when rotating from console hold_shift = false; rotax_move(angle); hold_shift = true; }else{ rotax_move(angle); } batchDraw(stage); rotationoffset = null; }*/ } } /*if(command[0] == "export") { console.log("trigger export"); }*/ } return; } // [S] Quick Save if(e.keyCode == 83) { //save_clones(); } // [E] Exchange Slab pressed if(e.keyCode == 69) { if(!transformer.attrs.visible) { print("Please select the slab you want to move"); return; } if(transformer.visible() && transformer._nodes[0]) { print("Please select the slab you want to exchange"); exchange_slab_pressed = true; } } // [H] Toggle Hide if(e.keyCode == 72) { toggle_hide(); } // [SHIFT] Hold Shift to activate Snapping if(e.keyCode == 16) { hold_shift = true; keep_target = true; $("#toggle_snap").css('color', color.red); } // [X] Hold / Apply last rotation from active target if(e.keyCode == 88) { if(!hold_rotation_pressed) { if(!transformer.attrs.visible) { print("Please select a slab to store its rotation"); return; } // get last angle from transformer handle var rotaxgroup = clip.findOne(node => {return node.attrs.name === "rotaxgroup"}); if(rotaxgroup) { var angle = rotaxgroup.rotation()%360; // Angle Normalisation if(angle < 0) angle += 360; hold_rotation = angle; hold_rotation_pressed = true; print("Rotation stored: "+(Math.round(hold_rotation*100)/100)+"°, Hold [X] and drag in or click another slab"); $("#toggle_rotation").css('color', color.red); } } } // [F] Fit to Screen if(e.keyCode == 70) { fit_to_screen(); } // [SPACE] Move Plan if(e.keyCode == 32) { keep_plan = true; document.body.style.cursor = 'move'; $("#toggle_pan").css('color', color.red); } // [+] Zoom in if(e.keyCode == 107 || e.keyCode == 187) { click_zoom(0.2); } // [-] Zoom out if(e.keyCode == 109 || e.keyCode == 189) { click_zoom(-0.2); } // [R] Rotate + 90 deg if(e.keyCode == 82) { if(!transformer.attrs.visible) { print("Please select a slab to rotate"); return; } var handle = clip.findOne(node => {return node.attrs.name === "rotax"}); if(handle) { var angle = handle.parent.attrs.rotation%360; if(angle < 0) // Angle Normalisation angle += 360; angle+=90; rotate_by_angle(angle); } /*hold_shift_before = hold_shift; hold_shift = false; // input angle -180 > 180 last_rotationoffset = calculate_rotationoffset(); rotationoffset = last_rotationoffset; var handle = clip.findOne(node => {return node.attrs.name === "rotax"}); if(handle) { var old_angle = handle.parent.attrs.rotation%360; if(old_angle < 0) // Angle Normalisation old_angle += 360; old_angle+=90; rotax_move(old_angle); // Add 90 deg to rotation batchDraw(stage); rotationoffset = null; }*/ } // [L] Rotate -90 deg if(e.keyCode == 76) { if(!transformer.attrs.visible) { print("Please select a slab to rotate"); return; } var handle = clip.findOne(node => {return node.attrs.name === "rotax"}); if(handle) { var angle = handle.parent.attrs.rotation%360; if(angle < 0) // Angle Normalisation angle += 360; angle-=90; rotate_by_angle(angle); } /*hold_shift_before = hold_shift; hold_shift = false; // input angle -180 > 180 last_rotationoffset = calculate_rotationoffset(); rotationoffset = last_rotationoffset; var handle = clip.findOne(node => {return node.attrs.name === "rotax"}); if(handle) { var old_angle = handle.parent.attrs.rotation%360; if(old_angle < 0) // Angle Normalisation old_angle += 360; old_angle-=90; rotax_move(old_angle); // Add 90 deg to rotation batchDraw(stage); rotationoffset = null; }*/ } // [DELETE] Remove active Slab from Target if(e.keyCode == 8) { if(!transformer.attrs.visible) { print("Please select a slab to delete"); return; } if(transformer._nodes[0]) { // delete used area slabs.find(node => { return transformer._nodes[0].attrs.id == node.attrs.slab && transformer._nodes[0].attrs.instance == node.attrs.inst;}).destroy(); plan.find(node => { return transformer._nodes[0].attrs.id == node.attrs.slab && transformer._nodes[0].attrs.instance == node.attrs.inst;}).destroy();; // delte clone transformer._nodes[0].destroy(); delete user.clones[transformer._nodes[0].attrs.id][transformer._nodes[0].attrs.instance-1]; if(Object.values(user.clones[transformer._nodes[0].attrs.id]).length == 0) delete user.clones[transformer._nodes[0].attrs.id]; intersection_check(); intersection_marker(); // hide transformer show_transformer(false); calculate_used_slab_area(); batchDraw(stage); } } // [Arrow keys] Move Slab in Target (1mm) // [SHIFT]+[Arrow keys] Move Slab in Target (10mm) if(e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 37 || e.keyCode == 39) // ARROW DOWN { if(!transformer.attrs.visible) { print("Please select a slab to move"); return; } if(transformer._nodes[0]) { var step = 0.1; if(hold_shift) step = 1; if(e.keyCode == 38) // up transformer._nodes[0].y(transformer._nodes[0].y()-step); if(e.keyCode == 40) // down transformer._nodes[0].y(transformer._nodes[0].y()+step); if(e.keyCode == 37) // left transformer._nodes[0].x(transformer._nodes[0].x()-step); if(e.keyCode == 39) // right transformer._nodes[0].x(transformer._nodes[0].x()+step); batchDraw(stage); } } // ESC if(e.keyCode == 27) { // disable panning keep_plan = false; $("#toggle_pan").css('color', "#eee"); $("#toggle_snap").css('color', "#eee"); // dsable rotation snap transformer.rotationSnaps([]); // hide transformer show_transformer(false); // hide Layers if($(".layers").is(":visible")) $(".layers").hide(); if($(".cheatsheet").is(":visible")) $(".cheatsheet").hide(); } }); document.addEventListener('keyup', function(e) { if($(".navi_input").is(':focus')) { } else { document.body.style.cursor = 'default'; // SHIFT if(e.keyCode == 16) { hold_shift = false; keep_target = false; $("#toggle_snap").css('color', "#eee"); } // SPACE if(e.keyCode == 32) { keep_plan = false; $("#toggle_pan").css('color', "#eee"); } // ARROWS UP if(e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 37 || e.keyCode == 39) { intersection_check(); intersection_marker(); undo(); } // [E] Exchange Slab released if(e.keyCode == 69) { print(""); exchange_slab_pressed = false; } // [X] Relesase hold_rotation if(e.keyCode == 88) { $("#toggle_rotation").css('color', "#eee"); hold_rotation = 0; hold_rotation_pressed = false; } find_changes(); } batchDraw(stage); }); var control_down = false; $(document).bind('keydown', function(e) { if( (e.metaKey || e.ctrlKey)) { control_down = true; e.preventDefault(); //console.log(e.which); /*if(e.which == 83) // command + s { save_clones(); // bug with planstosave array }*/ /*if(e.which == 85) // command + u { // write slabname into user object console.log(user); var user_map = {}; for(var slab_id in user.clones) { user_map = {}; for(var block_id in obj.slabs) { if(obj.slabs[block_id][slab_id]) { var bsname = obj.slabs[block_id][slab_id].block_name+" "+obj.slabs[block_id][slab_id].name; user_map[bsname] = user.clones[slab_id] } } } }*/ if(e.which == 73) // command + i { console.log("obj", obj); console.log("user", user); console.log("usage", usage); } /*if(e.which == 79) // command + o { console.log(obj); } */ if(e.which == 80) // command + p { setTimeout(function(){ export_plan(true); },200); } if(e.which == 90) // command + z { undo("undo"); } if(e.which == 89) // command + y { undo("redo"); } } }); $(document).bind('keyup', function(e) { control_down = false; }); $("[data-action]").on("click", function(e) { if($(this).attr("data-action") != undefined) { if($(this).attr("data-action") == "save") { save_clones(); } if($(this).attr("data-action") == "back") { window.history.back(); } } }); $(".cart .slab").on("click", function() { gallery_open($(this).attr("data-id"), true); }); $("#zoom_plus").on("click", function(e) { click_zoom( 0.2); }); $("#zoom_minus").on("click", function(e) { click_zoom(-0.2); }); $("#toggle_undo").on("click", function(e) { undo("undo"); }); $("#toggle_redo").on("click", function(e) { undo("redo"); }); $("#toggle_fit").on("click", function(e) { fit_to_screen(); }); $("#toggle_download").on("click", function(e) { print("Downloading Blending, please wait"); setTimeout(function(){ last_plan_position = plan.position(); last_plan_scale = plan.scale(); export_plan(true); },200); }); $("#toggle_hide").on("click", function(e) { toggle_hide(); }); function toggle_hide() { var line = plan.findOne(node => {return node.attrs.id === "line"}); if(line){ if( line.visible() ) { plan.find(node => {return node.attrs.id === "line"}).hide(); plan.find(node => {return node.attrs.id === "solid"}).hide(); plan.find(node => {return node.attrs.id === "text"}).hide(); $("#toggle_hide").css('color', color.red); } else { plan.find(node => {return node.attrs.id === "line"}).show(); plan.find(node => {return node.attrs.id === "solid"}).show(); plan.find(node => {return node.attrs.id === "text"}).show(); $("#toggle_hide").css('color', color.white); } batchDraw(plan); } } $("#toggle_layers").on("click", function(e) { if($(".layers").is(":visible")) { $(".layers").hide(); } else { var used_tickets = 0; for(var slab_id in user.clones) { for(var index in user.clones[slab_id]) { if(user.clones[slab_id][index] != null && available_targets.includes(user.clones[slab_id][index].target) ) { used_tickets++; } } } $( ".used_tickets" ).text(used_tickets); $(".layers").show(); } }); $("#toggle_cheatsheet").on("click", function(e) { if($(".cheatsheet").is(":visible")) { $(".cheatsheet").hide(); } else { $(".cheatsheet").show(); } }); $("#toggle_slabinfo").on("click", function(e) { if($(".slabinfo").is(":visible")) { $(".slabinfo").hide(); } else { $(".slabinfo").show(); } }); $(".layer").on("mousedown", function(e) { window.layer_drag_toggle = true; show_transformer(false); }); $(".layer").on("mouseup", function(e) { window.layer_drag_toggle = false; }); $("body").on("mousedown", function(e) { if($(e.target).parents(".layers, .navi, #toggle_layers").length == 0) { if($(".layers").is(":visible")) $(".layers").hide(); } if($(e.target).parents(".layers, .navi, #toggle_cheatsheet").length == 0) { if($(".cheatsheet").is(":visible")) { $(".cheatsheet").hide(); } } }); $(".layer").on("mouseenter mousedown", function(e) { if(e.type == "mousedown" || window.layer_drag_toggle) { if(!user.layer) user.layer = {}; if($(this).children(".fas").is(":visible")) user.layer[$(this).attr('id')] = false; else user.layer[$(this).attr('id')] = true; toggleLayers(); batchDraw(plan); } }); $("#toggle_pan").on("click", function(e) { if(keep_plan) { keep_plan = false; document.body.style.cursor = 'default'; $(this).css('color', "#eee"); } else { keep_plan = true; document.body.style.cursor = 'move'; $(this).css('color', color.red); } }); $("#toggle_rotation").on("click", function(e) { if(!transformer.attrs.visible) { print("Please select a slab to store its rotation"); } if(!hold_rotation_pressed) { // get last angle from transformer handle var rotaxgroup = clip.findOne(node => {return node.attrs.name === "rotaxgroup"}); if(rotaxgroup) { var angle = rotaxgroup.rotation()%360; // Angle Normalisation if(angle < 0) angle += 360; hold_rotation = angle; hold_rotation_pressed = true; print("Rotation stored: "+(Math.round(hold_rotation*100)/100)+"°, drag in or click another slab"); $("#toggle_rotation").css('color', color.red); } } else { hold_rotation = 0; hold_rotation_pressed = false; $(this).css('color', "#eee"); } }); $("#toggle_snap").on("click", function(e) { if(hold_shift) { hold_shift = false; //document.body.style.cursor = 'default'; $(this).css('color', "#eee"); } else { hold_shift = true; //document.body.style.cursor = 'move'; $(this).css('color', color.red); } }); $("#load_plan").on("change", function(e) { current_plan = e.target.value; load_plan(current_plan); reload_clones(); }); $("#scale").on("change", function(e) { var target_url = window.location.href; if(target_url.includes("&scale=")){ parts = target_url.split("&"); target_url = []; for (var i = parts.length - 1; i >= 0; i--) { if(parts[i].indexOf("scale=") == -1){ target_url.push(parts[i]); } } target_url = target_url.join("&"); } target_url += (target_url.includes("?")?"&":"?")+"scale="+$(this).val(); window.location.replace(target_url); }); $("html").bind('touchstart mousedown', function(e) { if(!undo_user) { undo_user = [];// init first undo point undo_user.push(JSON.stringify(user)); } }); $("html").bind('touchend mouseup', function(e) { global_mouseup(e); }); $("[data-done]").on("click", function(e) { if($(this).attr("data-action") == undefined) { eval_done(this); } }); $("#toggle_undo").css('color', "#161616"); $("#toggle_redo").css('color', "#161616");