'use strict'; scrollBar.on("mouseover", function(event) { document.body.style.cursor = "pointer"; event.target.fill(color.orange); scrollBar.draw(); }); scrollBar.on("mouseout", function(event) { document.body.style.cursor = "default"; event.target.fill("#888"); scrollBar.draw(); }); scrollBar.on("dragmove", function() { var maxScroll = stage.width() - 150 - 2 * slab_padding - scrollBar.width(); var scrollRatio = (scrollBar.x() - slab_padding) / maxScroll; slabs.x(-(slabs_width + slab_padding - stage.width() + 150) * scrollRatio); batchDraw(slabs); }); document.addEventListener("touchmove", function(event) { if (event.scale !== 1) { event.preventDefault(); } }, false); window.addEventListener("resize", function(event) { fit_to_screen(); gallery_open(undefined); stage.width(window.innerWidth); stage.height(window.innerHeight - head_height - foot_height); }); $(".no-zoom").bind("touchend", function(event) { var currentTime = +new Date(); if (doubleTouchStartTimestamp + 500 > currentTime) { event.preventDefault(); } doubleTouchStartTimestamp = currentTime; }); window.addEventListener("contextmenu", function(event) { event.preventDefault(); }); stage.on("mousemove touchmove", function(event) { rotax_move(null); }); stage.on("mousedown mouseup touchstart touchmove touchend tap dbltap dragstart dragmove dragend wheel", function(event) { if (event.type === "touchstart") { touchscreen = true; } if (touchscreen) { if (event.type === "touchstart") { on_mousedown(event); } else if (event.type === "dragmove") { if (event.evt.touches[0] && event.evt.touches[1]) { touch_zoom(event); } else { on_dragmove(event); } } else if (event.type === "tap" || event.type === "touchend") { on_mouseup(event); } } else { if (event.type === "mousedown") { if (event.evt.button === 2) { keep_plan = true; document.body.style.cursor = "move"; $("#toggle_pan").css("color", custom_color); on_mousedown(event); } else if (event.evt.button === 0) { on_mousedown(event); } } else if (event.type === "dragmove") { on_dragmove(event); } else if (event.type === "mouseup") { if (event.evt.button === 2) { keep_plan = false; document.body.style.cursor = "default"; $("#toggle_pan").css("color", "#eee"); on_mouseup(event); } else if (event.evt.button === 0) { on_mouseup(event); } } else if (event.type === "mouseup" && event.evt.button === 2) { on_rightmouseup(event); } else if (event.type === "wheel" && !mouse_is_down) { mouse_zoom(event); } } }); var shift_pressed = false; document.addEventListener("keydown", function(event) { console.log("keycode", event.keyCode); if ($(".navi_input").is(":focus")) { if (event.keyCode === 13) { // Enter console.log("GG") // Handle various input commands var input = $(".navi_input").val().trim().toLowerCase(); var parts = input.split(/\s+/); // Rotation commands: "r 90", "r90", "rotate 90", "rotate90", "rotation 90", "rotation90" if ((parts[0] === "r" || parts[0] === "rotate" || parts[0] === "rotation")) { var angle = parseFloat(parts.length > 1 ? parts[1] : input.substring(parts[0].length)); if (!isNaN(angle)) { angle = angle % 360; if (angle < 0) { angle += 360; } console.log("Rotating to angle:", angle); if (transformer.attrs.visible && transformer._nodes.length > 0) { rotate_by_angle(angle); } else if (slab_mode && slab_view_transformer.attrs.visible && slab_view_transformer._nodes.length > 0) { slab_view_rotate_by_angle(angle); } else { print("Please select a slab to rotate"); } } } // Zoom commands: "z 1.2", "zoom 1.2", "scale 1.2" else if (parts[0] === "z" || parts[0] === "zoom" || parts[0] === "scale") { var zoomFactor = parseFloat(parts.length > 1 ? parts[1] : input.substring(parts[0].length)); if (!isNaN(zoomFactor)) { click_zoom(zoomFactor - 1); } } // Fit command: "f", "fit" else if (input === "f" || input === "fit") { fit_to_screen(); } // Hide/show command: "h", "hide", "toggle" else if (input === "h" || input === "hide" || input === "toggle") { toggle_hide(); } // Help command: "help", "?" else if (input === "help" || input === "?") { if ($(".cheatsheet").is(":visible")) { $(".cheatsheet").hide(); } else { $(".cheatsheet").show(); } } // Clear the input field after processing any command $(".navi_input").val(""); } } else { if (!slab_mode && event.keyCode === 69) { // E 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; } } if (!slab_mode && event.keyCode === 72) { // H toggle_hide(); } if (event.keyCode === 16) { // Shift keep_target = true; hold_shift = true; shift_pressed = true; $("#toggle_snap").css("color", custom_color); } if (!slab_mode && event.keyCode === 88 && !hold_rotation_pressed) { // X if (!transformer.attrs.visible) { print("Please select a slab to store its rotation"); return; } var rotationGroup = clip.findOne(function(item) { return item.attrs.name === "rotaxgroup"; }); if (rotationGroup) { var rotation = rotationGroup.rotation() % 360; if (rotation < 0) { rotation += 360; } hold_rotation = rotation; hold_rotation_pressed = true; print("Rotation stored: " + Math.round(100 * hold_rotation) / 100 + "\u00b0, Hold [X] and drag in or click another slab"); $("#toggle_rotation").css("color", custom_color); } } if (event.keyCode === 70) { // F fit_to_screen(); } if (!slab_mode && event.keyCode === 32) { // Space keep_plan = true; document.body.style.cursor = "move"; $("#toggle_pan").css("color", custom_color); } if (event.keyCode === 107 || event.keyCode === 187) { // + or = click_zoom(0.2); } if (event.keyCode === 109 || event.keyCode === 189) { // - or _ click_zoom(-0.2); } if (!slab_mode && event.keyCode === 82) { // R if (!transformer.attrs.visible) { print("Please select a slab to rotate"); return; } var rotax = clip.findOne(function(item) { return item.attrs.name === "rotax"; }); if (rotax) { var currentRotation = rotax.parent.attrs.rotation % 360; if (currentRotation < 0) { currentRotation += 360; } rotate_by_angle(currentRotation + 90); } } if (!slab_mode && event.keyCode === 76) { // L if (!transformer.attrs.visible) { print("Please select a slab to rotate"); return; } var rotaxLeft = clip.findOne(function(item) { return item.attrs.name === "rotax"; }); if (rotaxLeft) { var currentRotationLeft = rotaxLeft.parent.attrs.rotation % 360; if (currentRotationLeft < 0) { currentRotationLeft += 360; } rotate_by_angle(currentRotationLeft - 90); } } if (event.keyCode === 8) { // Backspace if (!transformer.attrs.visible) { print("Please select a slab to delete"); return; } if (transformer._nodes[0]) { var slabToDelete = slabs.find(function(item) { return transformer._nodes[0].attrs.id === item.attrs.slab && transformer._nodes[0].attrs.instance === item.attrs.inst; }); if (slabToDelete) { slabToDelete.destroy(); } var planToDelete = plan.find(function(item) { return transformer._nodes[0].attrs.id === item.attrs.slab && transformer._nodes[0].attrs.instance === item.attrs.inst; }); if (planToDelete) { planToDelete.destroy(); } 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(); show_transformer(false); calculate_used_slab_area(); batchDraw(stage); } } if (event.keyCode === 38 || event.keyCode === 40 || event.keyCode === 37 || event.keyCode === 39) { // Arrow keys // if slab is selected then move the slab var moveStep = 0.1; if (shift_pressed) { moveStep = 1; } if (transformer.attrs.visible && transformer._nodes[0]) { if (event.keyCode === 38) { // Up Arrow transformer._nodes[0].y(transformer._nodes[0].y() - moveStep); } if (event.keyCode === 40) { // Down Arrow transformer._nodes[0].y(transformer._nodes[0].y() + moveStep); } if (event.keyCode === 37) { // Left Arrow transformer._nodes[0].x(transformer._nodes[0].x() - moveStep); } if (event.keyCode === 39) { // Right Arrow transformer._nodes[0].x(transformer._nodes[0].x() + moveStep); } batchDraw(stage); }else if (slab_view_transformer.attrs.visible && slab_view_transformer._nodes[0]) { if (event.keyCode === 38) { // Up Arrow slab_view_transformer._nodes[0].y(slab_view_transformer._nodes[0].y() - moveStep); } if (event.keyCode === 40) { // Down Arrow slab_view_transformer._nodes[0].y(slab_view_transformer._nodes[0].y() + moveStep); } if (event.keyCode === 37) { // Left Arrow slab_view_transformer._nodes[0].x(slab_view_transformer._nodes[0].x() - moveStep); } if (event.keyCode === 39) { // Right Arrow slab_view_transformer._nodes[0].x(slab_view_transformer._nodes[0].x() + moveStep); } // trigger drag event on move var fake_event = { target: slab_view_transformer._nodes[0], type: "keymove", } slab_view_drag(fake_event) batchDraw(stage); }else { print("Please select a slab to move"); return; } } if (event.keyCode === 27) { // Escape keep_plan = false; $("#toggle_pan").css("color", "#eee"); $("#toggle_snap").css("color", "#eee"); transformer.rotationSnaps([]); show_transformer(false); if ($(".layers").is(":visible")) { $(".layers").hide(); } if ($(".cheatsheet").is(":visible")) { $(".cheatsheet").hide(); } } } }); document.addEventListener("keyup", function(event) { if (!$(".navi_input").is(":focus")) { document.body.style.cursor = "default"; if (event.keyCode === 16) { // Shift keep_target = false; hold_shift = false; shift_pressed = false; $("#toggle_snap").css("color", "#eee"); } if (!slab_mode && event.keyCode === 32) { // Space keep_plan = false; $("#toggle_pan").css("color", "#eee"); } if (event.keyCode === 38 || event.keyCode === 40 || event.keyCode === 37 || event.keyCode === 39) { // Arrow Keys intersection_check(); intersection_marker(); undo(); } if (!slab_mode && event.keyCode === 69) { // E print(""); exchange_slab_pressed = false; } if (!slab_mode && event.keyCode === 88) { // X $("#toggle_rotation").css("color", "#eee"); hold_rotation = 0; hold_rotation_pressed = false; } find_changes(); } batchDraw(stage); }); var control_down = false; $(document).bind("keydown", function(event) { if (event.metaKey || event.ctrlKey) { control_down = true; event.preventDefault(); if (event.which === 73) { // Ctrl+I console.log("obj", obj); console.log("user", user); console.log("usage", usage); } if (!slab_mode && event.which === 80) { // Ctrl+P setTimeout(function() { export_plan(true); }, 200); } if (!slab_mode && event.which === 90) { // Ctrl+Z undo("undo"); } if (!slab_mode && event.which === 89) { // Ctrl+Y undo("redo"); } } }); $(document).bind("keyup", function(event) { control_down = false; }); $("[data-action]").on("click", function(event) { 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); }); $("#exit_slab_view").on("click", function(event) { slab_view_reset(); }); $("#zoom_plus").on("click", function(event) { click_zoom(0.2); }); $("#zoom_minus").on("click", function(event) { click_zoom(-0.2); }); $("#toggle_undo").on("click", function(event) { undo("undo"); }); $("#toggle_redo").on("click", function(event) { undo("redo"); }); $("#toggle_fit").on("click", function(event) { fit_to_screen(); }); $("#toggle_download").on("click", function(event) { 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(event) { toggle_hide(); }); function toggle_hide() { var line = plan.findOne(function(item) { return item.attrs.id === "line"; }); if (line) { if (line.visible()) { plan.find(function(item) { return item.attrs.id === "line"; }).hide(); plan.find(function(item) { return item.attrs.id === "solid"; }).hide(); plan.find(function(item) { return item.attrs.id === "text"; }).hide(); $("#toggle_hide").css("color", custom_color); } else { plan.find(function(item) { return item.attrs.id === "line"; }).show(); plan.find(function(item) { return item.attrs.id === "solid"; }).show(); plan.find(function(item) { return item.attrs.id === "text"; }).show(); $("#toggle_hide").css("color", color.white); } batchDraw(plan); } } $("#toggle_layers").on("click", function(event) { if ($(".layers").is(":visible")) { $(".layers").hide(); } else { var usedTickets = 0; for (var slabId in user.clones) { for (var instanceId in user.clones[slabId]) { if (user.clones[slabId][instanceId] !== null && available_targets.includes(user.clones[slabId][instanceId].target)) { usedTickets++; } } } $(".used_tickets").text(usedTickets); let used_slabs = user.yield.slabs; let used_sets = user.yield.sets; let used_yield = Math.round(100 * user.yield.percent) / 100+"%"; $(".used_sets").text(used_sets); $(".used_slabs").text(used_slabs); $(".used_yield").text(used_yield); $(".layers").show(); } }); $("#toggle_cheatsheet").on("click", function(event) { if ($(".cheatsheet").is(":visible")) { $(".cheatsheet").hide(); } else { $(".cheatsheet").show(); } }); $("#toggle_slabinfo").on("click", function(event) { if ($(".slabinfo").is(":visible")) { $(".slabinfo").hide(); } else { $(".slabinfo").show(); } }); $(".layer").on("mousedown", function(event) { window.layer_drag_toggle = true; show_transformer(false); }); $(".layer").on("mouseup", function(event) { window.layer_drag_toggle = false; }); $("body").on("mousedown", function(event) { if ($(event.target).parents(".layers, .navi, #toggle_layers").length === 0 && $(".layers").is(":visible")) { $(".layers").hide(); } if ($(event.target).parents(".layers, .navi, #toggle_cheatsheet").length === 0 && $(".cheatsheet").is(":visible")) { $(".cheatsheet").hide(); } }); $(".layer").on("mouseenter mousedown", function(event) { if (event.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(event) { 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", custom_color); } }); $("#toggle_rotation").on("click", function(event) { if (!transformer.attrs.visible) { print("Please select a slab to store its rotation"); } if (hold_rotation_pressed) { hold_rotation = 0; hold_rotation_pressed = false; $(this).css("color", "#eee"); } else { var rotationGroup = clip.findOne(function(item) { return item.attrs.name === "rotaxgroup"; }); if (rotationGroup) { var rotation = rotationGroup.rotation() % 360; if (rotation < 0) { rotation += 360; } hold_rotation = rotation; hold_rotation_pressed = true; print("Rotation stored: " + Math.round(100 * hold_rotation) / 100 + "\u00b0, drag in or click another slab"); $("#toggle_rotation").css("color", custom_color); } } }); $("#toggle_snap").on("click", function(event) { if (hold_shift) { hold_shift = false; $(this).css("color", "#eee"); } else { hold_shift = true; $(this).css("color", custom_color); } }); $("#load_plan").on("change", function(event) { current_plan = event.target.value; load_plan(current_plan); reload_clones(); }); $("#scale").on("change", function(event) { var currentUrl = window.location.href; if (currentUrl.includes("&scale=")) { var parts = currentUrl.split("&"); var filteredParts = []; for (var i = parts.length - 1; i >= 0; i--) { if (parts[i].indexOf("scale=") === -1) { filteredParts.push(parts[i]); } } currentUrl = filteredParts.join("&"); } currentUrl += (currentUrl.includes("?") ? "&" : "?") + "scale=" + $(this).val(); window.location.replace(currentUrl); }); $("html").bind("touchstart mousedown", function(event) { if (!undo_user) { undo_user = []; undo_user.push(JSON.stringify(user)); } }); $("html").bind("touchend mouseup", function(event) { global_mouseup(event); }); $("[data-done]").on("click", function(event) { if ($(this).attr("data-action") === undefined) { eval_done(this); } }); $("#toggle_undo").css("color", "#161616"); $("#toggle_redo").css("color", "#161616");