From 9a02408e7b3729949192a739847371b575d74c55 Mon Sep 17 00:00:00 2001 From: Stewart Allen Date: Wed, 5 Jun 2024 12:10:33 -0700 Subject: [PATCH] refactor lay flat, focus, hover pop tool menus --- src/kiri-mode/cam/animate.js | 2 - src/kiri-mode/cam/animate2.js | 3 - src/kiri-mode/cam/client.js | 1 + src/kiri/init.js | 189 +++++++--------------------------- src/kiri/tools.js | 30 ++++-- src/moto/space.js | 10 ++ web/kiri/index.css | 189 +++++++++++----------------------- web/kiri/index.html | 169 +++++++++++++----------------- 8 files changed, 202 insertions(+), 391 deletions(-) diff --git a/src/kiri-mode/cam/animate.js b/src/kiri-mode/cam/animate.js index d5704fac..3dfd5094 100644 --- a/src/kiri-mode/cam/animate.js +++ b/src/kiri-mode/cam/animate.js @@ -178,7 +178,6 @@ kiri.load(() => { if (steps !== 1) { playButton.style.display = 'none'; pauseButton.style.display = ''; - // $('render-hide').onclick(); } kiri.client.animate({ speed, @@ -192,7 +191,6 @@ kiri.load(() => { updateSpeed(1); playButton.style.display = 'none'; pauseButton.style.display = ''; - // $('render-hide').onclick(); kiri.client.animate({ speed, steps: steps || Infinity, diff --git a/src/kiri-mode/cam/animate2.js b/src/kiri-mode/cam/animate2.js index f3c87e9c..050f9ed8 100644 --- a/src/kiri-mode/cam/animate2.js +++ b/src/kiri-mode/cam/animate2.js @@ -72,7 +72,6 @@ kiri.load(() => { api.event.emit('animate', 'CAM'); api.alerts.hide(alert); // moto.space.platform.showGridBelow(false); - $('render-hide').onclick(); }); } @@ -147,7 +146,6 @@ kiri.load(() => { if (steps !== 1) { playButton.style.display = 'none'; pauseButton.style.display = ''; - $('render-hide').onclick(); } kiri.client.animate2({ speed, @@ -161,7 +159,6 @@ kiri.load(() => { updateSpeed(1); playButton.style.display = 'none'; pauseButton.style.display = ''; - $('render-hide').onclick(); kiri.client.animate2({ speed, steps: steps || Infinity, diff --git a/src/kiri-mode/cam/client.js b/src/kiri-mode/cam/client.js index c16a4df1..56492b7a 100644 --- a/src/kiri-mode/cam/client.js +++ b/src/kiri-mode/cam/client.js @@ -1559,6 +1559,7 @@ CAM.init = function(kiri, api) { } api.event.on('tool.mesh.face-normal', normal => { + console.log({ poppedRec }); poppedRec.degrees = (Math.atan2(normal.y, normal.z) * RAD2DEG).round(2); poppedRec.absolute = true; func.opRender(); diff --git a/src/kiri/init.js b/src/kiri/init.js index 5a1ba5b1..3e604aaf 100644 --- a/src/kiri/init.js +++ b/src/kiri/init.js @@ -462,9 +462,9 @@ gapp.register("kiri.init", [], (root, exports) => { case cca('e'): // device showDevices(); break; - case cca('w'): // scale - api.event.emit("tool.next"); - break; + // case cca('w'): // scale + // api.event.emit("tool.next"); + // break; case cca('o'): // tools showTools(); break; @@ -516,13 +516,6 @@ gapp.register("kiri.init", [], (root, exports) => { return false; } - function setFocus() { - let int = contextInt[0]; - if (int && int.object && int.object.widget) { - api.space.set_focus(undefined, int.point); - } - } - function duplicateSelection() { api.selection.duplicate(); } @@ -1595,7 +1588,6 @@ gapp.register("kiri.init", [], (root, exports) => { speedbar: $('speedbar'), context: $('context-menu'), - back: $('lt-back'), ltsetup: $('lt-setup'), ltfile: $('lt-file'), ltview: $('lt-view'), @@ -1940,12 +1932,12 @@ gapp.register("kiri.init", [], (root, exports) => { camFirstZMax: newBoolean(LANG.ou_z1st_s, onBooleanClick, {title:LANG.ou_z1st_l}), camForceZMax: newBoolean(LANG.ou_forz_s, onBooleanClick, {title:LANG.ou_forz_l}), camOrigin: newGroup(LANG.co_menu, $('cam-origin'), { modes:CAM, driven, separator }), + camOriginTop: newBoolean(LANG.or_topp_s, onBooleanClick, {title:LANG.or_topp_l}), + camOriginCenter: newBoolean(LANG.or_cntr_s, onBooleanClick, {title:LANG.or_cntr_l}), + separator: newBlank({ class:"set-sep", driven }), camOriginOffX: newInput(LANG.co_offx_s, {title:LANG.co_offx_l, convert:toFloat, units:true}), camOriginOffY: newInput(LANG.co_offy_s, {title:LANG.co_offy_l, convert:toFloat, units:true}), camOriginOffZ: newInput(LANG.co_offz_s, {title:LANG.co_offz_l, convert:toFloat, units:true}), - separator: newBlank({ class:"set-sep", driven }), - camOriginTop: newBoolean(LANG.or_topp_s, onBooleanClick, {title:LANG.or_topp_l}), - camOriginCenter: newBoolean(LANG.or_cntr_s, onBooleanClick, {title:LANG.or_cntr_l}), camExpert: newGroup(LANG.op_xprt_s, $('cam-expert'), { group: "cam_expert", modes:CAM, marker: false, driven, separator }), camExpertFast: newBoolean(LANG.cx_fast_s, onBooleanClick, {title:LANG.cx_fast_l, show: () => !ui.camTrueShadow.checked }), camTrueShadow: newBoolean(LANG.cx_true_s, onBooleanClick, {title:LANG.cx_true_l, show: () => !ui.camExpertFast.checked }), @@ -2401,29 +2393,29 @@ gapp.register("kiri.init", [], (root, exports) => { } }; - space.mouse.up((event, int) => { - // context menu - if (event.button === 2) { - let et = event.target; - if (et.tagName != 'CANVAS' && et.id != 'context-menu') { - return; - } - let full = api.view.is_arrange(); - for (let key of ["layflat","mirror","duplicate"]) { - $(`context-${key}`).disabled = !full; - } - let style = ui.context.style; - style.display = 'flex'; - style.left = `${event.clientX-3}px`; - style.top = `${event.clientY-3}px`; - ui.context.onmouseleave = () => { - style.display = ''; - }; - event.preventDefault(); - event.stopPropagation(); - contextInt = int; - } - }); + // space.mouse.up((event, int) => { + // // context menu + // if (event.button === 2) { + // let et = event.target; + // if (et.tagName != 'CANVAS' && et.id != 'context-menu') { + // return; + // } + // let full = api.view.is_arrange(); + // for (let key of ["layflat","mirror","duplicate"]) { + // $(`context-${key}`).disabled = !full; + // } + // let style = ui.context.style; + // style.display = 'flex'; + // style.left = `${event.clientX-3}px`; + // style.top = `${event.clientY-3}px`; + // ui.context.onmouseleave = () => { + // style.display = ''; + // }; + // event.preventDefault(); + // event.stopPropagation(); + // contextInt = int; + // } + // }); space.mouse.downSelect((int, event) => { if (api.feature.on_mouse_down) { @@ -2520,8 +2512,6 @@ gapp.register("kiri.init", [], (root, exports) => { function init_two() { api.event.emit('init.two'); - // api.space.set_focus(); - // call driver initializations, if present Object.values(kiri.driver).forEach(driver => { if (driver.init) try { @@ -2710,7 +2700,6 @@ gapp.register("kiri.init", [], (root, exports) => { api.widgets.for(w => w.unrotate()); api.selection.update_info(); }; - $('lay-flat').onclick = () => { api.event.emit("tool.mesh.lay-flat") }; // rotation buttons let d = (Math.PI / 180) * 5; $('rot_x_lt').onclick = () => { api.selection.rotate(-d,0,0) }; @@ -2727,17 +2716,15 @@ gapp.register("kiri.init", [], (root, exports) => { $('mesh-swap').onclick = () => { api.widgets.replace() }; $('mesh-export-stl').onclick = () => { objectsExport('stl') }; $('mesh-export-obj').onclick = () => { objectsExport('obj') }; - // context menu - $('context-export-workspace').onclick = () => { profileExport(true) }; - $('context-clear-workspace').onclick = () => { - api.view.set(VIEWS.ARRANGE); - api.platform.clear(); - ui.context.onmouseleave(); - }; $('context-duplicate').onclick = duplicateSelection; $('context-mirror').onclick = mirrorSelection; $('context-layflat').onclick = () => { api.event.emit("tool.mesh.lay-flat") }; - $('context-setfocus').onclick = setFocus; + $('context-setfocus').onclick = () => { + api.event.emit( + "tool.camera.focus", + ev => api.space.set_focus(undefined, ev.object.point) + ); + }; ui.modal.onclick = api.modal.hide; ui.modalBox.onclick = (ev) => { ev.stopPropagation() }; @@ -2748,112 +2735,6 @@ gapp.register("kiri.init", [], (root, exports) => { // show topline separator when iframed try { if (WIN.self !== WIN.top) $('top-sep').style.display = 'flex' } catch (e) { console.log(e) } - // bind tictac buttons to panel show/hide - let groups = {}; - for (let tt of [...document.getElementsByClassName('tictac')]) { - let sid = tt.getAttribute('select'); - let gid = tt.getAttribute('group') || 'default'; - let grp = groups[gid] = groups[gid] || []; - let target = $(sid); - target.style.display = 'none'; - target.control = tt; - grp.push({button: tt, div: target}); - tt.onclick = () => { - for (let rec of grp) { - let {button, div} = rec; - if (div === target) { - div.style.display = ''; - button.classList.add('selected'); - } else { - div.style.display = 'none'; - button.classList.remove('selected'); - } - } - let lid = tt.getAttribute('label'); - if (lid) { - $(lid).innerText = tt.getAttribute('title'); - } - }; - } - - // bind closer X to hiding parent action - for (let tt of [...document.getElementsByClassName('closer')]) { - let tid = tt.getAttribute('target'); - let target = tid ? $(tid) : parentWithClass(tt, 'movable'); - target.classList.add('hide'); - let close = tt.onmousedown = (ev) => { - target.classList.add('hide'); - if (ev) { - ev.preventDefault(); - ev.stopPropagation(); - } - }; - api.event.on('key.esc', close); - } - - // add drag behavior to movers - [...document.getElementsByClassName('mover')].forEach(mover => { - mover.onmousedown = (ev) => { - let moving = parentWithClass(mover, 'movable'); - let mpos = { - x: moving.offsetLeft, - y: moving.offsetTop - }; - ev.preventDefault(); - ev.stopPropagation(); - let origin = { - x: ev.screenX, - y: ev.screenY - }; - let tracker = ui.tracker; - tracker.style.display = 'block'; - tracker.onmousemove = (ev) => { - ev.preventDefault(); - ev.stopPropagation(); - let pos = { - x: ev.screenX, - y: ev.screenY - }; - let delta = { - x: pos.x - origin.x, - y: pos.y - origin.y - }; - moving.style.left = `${mpos.x + delta.x}px`; - moving.style.top = `${mpos.y + delta.y}px`; - }; - tracker.onmouseup = (ev) => { - ui.tracker.style.display = 'none'; - ev.preventDefault(); - ev.stopPropagation(); - tracker.onmouseup = null; - tracker.onmouseout = null; - tracker.onmousemove = null; - }; - }; - }); - - // bind tool buttons - { - let { event } = api; - let next = 0; - let list = ['rotate','scale','mesh']; - event.on("tool.next", () => { - event.emit("tool.show", list[next++ % list.length]); - }); - event.on("tool.show", tictac => { - if (typeof(tictac) === 'string') { - next = list.indexOf(tictac)+1; - tictac = $(`ft-${tictac}`); - } - let mover = parentWithClass(tictac.control, 'movable'); - mover.classList.remove('hide'); - tictac.control.onclick(); - }); - $('tool-rotate').onclick = event.bind("tool.show", "rotate"); - $('tool-scale').onclick = event.bind("tool.show", "scale"); - $('tool-mesh').onclick = event.bind("tool.show", "mesh"); - } - // warn users they are running a beta release if (kiri.beta && kiri.beta > 0 && sdb.kiri_beta != kiri.beta) { api.show.alert("this is a beta / development release"); diff --git a/src/kiri/tools.js b/src/kiri/tools.js index ce1646d8..bb55d4f5 100644 --- a/src/kiri/tools.js +++ b/src/kiri/tools.js @@ -5,7 +5,7 @@ gapp.register("kiri.tools", [], (root, exports) => { const { Vector3, Quaternion } = THREE; -const { kiri } = root; +const { kiri, moto } = root; const { api } = kiri; const XAXIS = new THREE.Vector3(1,0,0); @@ -13,7 +13,7 @@ const ZAXIS = new THREE.Vector3(0,0,1); // circle let pgeo = new THREE.CircleGeometry(8, 30); -let pmat = new THREE.MeshBasicMaterial({color: 0xff0000, opacity: 0.5, transparent: true}); +let pmat = new THREE.MeshBasicMaterial({color: 0xddeeff, opacity: 0.6, transparent: true}); let pmesh = new THREE.Mesh(pgeo, pmat); // circle outline @@ -34,7 +34,7 @@ for (let i=0; i { + opName = 'camera focus'; + onDone = fn; + startIt(); +}); + api.event.on('tool.mesh.face-up', () => { opName = 'face select'; onDone = onFaceUpSelect; @@ -103,6 +109,16 @@ api.event.on('tool.mesh.lay-flat', () => { startIt(); }); +function scale() { + let cam = moto.space.internals().camera; + let dist = cam.position.distanceTo(pmesh.position); + let scale = opName === 'camera focus' ? + Math.min(0.25, 100 / dist) : dist / 100; + pmesh.scale.set(scale,scale,scale); +} + +api.event.on("space.view.zoom", scale); + api.event.on('mouse.hover', (ev) => { if (!enabled) { return; @@ -134,6 +150,7 @@ api.event.on('mouse.hover', (ev) => { new Vector3(norm.x,norm.y,norm.z) ); pmesh.setRotationFromQuaternion(q); + scale(); } }); @@ -145,7 +162,8 @@ api.event.on('mouse.hover.up', (ev) => { if (!object) { return; } - onDone(); + onDone(ev); + endIt(); }); }); diff --git a/src/moto/space.js b/src/moto/space.js index 304006b7..c2be98d1 100644 --- a/src/moto/space.js +++ b/src/moto/space.js @@ -712,6 +712,12 @@ gapp.register("moto.space", [], (root, exports) => { m.renderOrder = 3; }); Space.scene.add(group); + const scale = grid.origin.scale = () => { + const dist = camera.position.distanceTo(group.position); + const scale = Math.min(dist / 100, 0.5); + group.scale.set(scale, scale, scale); + }; + scale(); updateDraws(); } @@ -1369,11 +1375,15 @@ gapp.register("moto.space", [], (root, exports) => { updateLastAction(); updateFocus(); }, (val) => { + if (camera && grid?.origin?.scale) { + grid.origin.scale(); + } if (camera && viewControl) { // increase intersect line precision on zoom const dist = camera.position.distanceTo(viewControl.target); raycaster.params.Line.threshold = Math.min(1, dist / 100); } + moto.broker.publish("space.view.zoom", camera); updateLastAction(); if (slider) slider(val); }); diff --git a/web/kiri/index.css b/web/kiri/index.css index 93cce156..a4bcd411 100644 --- a/web/kiri/index.css +++ b/web/kiri/index.css @@ -255,6 +255,7 @@ th, tr, td, label { { background-color: #555 !important; } +.dark #render-tools .pop, .dark #render-tools svg, .dark #lang-pop, .dark .pop-tics > div, @@ -265,7 +266,6 @@ th, tr, td, label { .dark .set2-group .var-row, .dark .set2-sep, .dark .var-row, -.dark .movable .body, .dark #layers .var-row, .dark #slider-zero, .dark #slider-max, @@ -276,6 +276,7 @@ th, tr, td, label { background-color: #222; color: white; } +.dark #render-tools .pop, .dark #render-tools svg, .dark .cam-pop-op { border-color: #555; @@ -596,6 +597,9 @@ th, tr, td, label { .gap5 { gap: 5px; } +.gap10 { + gap: 10px; +} .grid { display: grid; } @@ -928,31 +932,6 @@ th, tr, td, label { max-height: 1px; background-image: var(--gradbar2); } -.movable { - margin: 5px; -} -.movable .title { - color: white; - padding: 2px 3px 1px 3px; - background-color: var(--main-color); - border-top-left-radius: 10px; - border-top-right-radius: 10px; - font-size: smaller; - text-align: center; -} -.movable .body { - margin: 0; - padding: 0 5px 0 0; - background-color: #fff; - border-left: 1px solid #eee; - border-right: 1px solid #eee; -} -.movable .footer { - height: 10px; - border-bottom-left-radius: 5px; - border-bottom-right-radius: 5px; - background-color: var(--main-color); -} .closer { position: absolute; @@ -1016,12 +995,62 @@ th, tr, td, label { color: white; } +/* top center toolbar */ +#render-tools { + pointer-events: all; + position: absolute; + gap: 2px; + top: 3px; + left: 0; + right: 0; + align-items: center; + justify-content: center; + flex-direction: row; +} +#render-tools svg { + font-size: 20px; + aspect-ratio: 1/1; + background-color: #fff; + border: 1px solid #aaa; + border-radius: 3px; + padding: 8px; +} +#render-tools svg:hover { + border: 1px solid blue; + background-color: var(--blue-4); +} +/** tool pop menus */ +#render-tools .pop:before { + position: absolute; + top: -10px; + left: -20px; + width: calc(100% + 40px); + height: calc(100% + 20px); + /* background-color: red; */ + content: ""; +} +#render-tools .pop { + background-color: #fff; + border: 1px solid #aaa; + border-radius: 3px; + position: absolute; + display: none; + margin-top: 3px; + padding: 3px; + top: 100%; +} +#render-tools > span:hover .pop { + display: grid; +} +/** selection rotation */ #ft-rotate { grid-gap: 2px; grid-template-rows: auto auto auto 1fr; grid-template-columns: auto auto auto auto; } -#ft-rotate label, #ft-rotate svg { +#ft-rotate label, +#ft-rotate svg +{ text-align: center; } #ft-rotate svg { @@ -1044,6 +1073,7 @@ th, tr, td, label { align-items: stretch; min-width: 150px; } +/** selection scaling */ #ft-scale { grid-gap: 2px; grid-template-rows: auto auto auto 1fr; @@ -1058,6 +1088,7 @@ th, tr, td, label { margin-left: 0; margin-right: 0; } +/** selection mesh actions */ #ft-mesh label { font-size: smaller; } @@ -1068,36 +1099,6 @@ th, tr, td, label { #ft-mesh { min-width: 200px; } -#render-tools { - pointer-events: all; - position: absolute; - gap: 2px; - top: 3px; - left: 0; - right: 0; - align-items: center; - justify-content: center; - flex-direction: row; - z-index: 102; -} -#render-tools svg { - font-size: 20px; - aspect-ratio: 1/1; - background-color: #fff; - border: 1px solid var(--blue-4); - border-radius: 3px; - padding: 8px; -} -#render-tools svg:hover { - border: 1px solid blue; - background-color: var(--blue-4); -} -#render-hide > a { - border: 0.5px dashed black; - border-radius: 2px; - width: 17px; - height: 17px; -} #mesh-info { grid-gap: 2px; grid-template-rows: auto auto auto; @@ -1112,54 +1113,10 @@ th, tr, td, label { background-color: var(--main-color); } -#lt-back, #lt-options { - flex-direction: row; - position: absolute; - display: none; - gap: 5px; - top: 0; -} -#lt-trash:hover, #lt-w-enable:hover, #lt-w-disable:hover { - color: var(--main-color); -} -#act-sep, #lt-sep { - border-top-right-radius: 3px; - border-bottom-right-radius: 3px; - background-color: var(--main-color); - height: 10px; - left: -5px; -} - -#lt-end { - height: 10px; - border-top-right-radius: 1px; - border-bottom-right-radius: 10px; - background-color: var(--main-color); - left: -5px; -} #act-animate.disabled { color: #aaa !important; } -.lt-menu { - flex-direction: column; - align-items: center; - margin: 2px 0 2px 0; - padding: 5px 5px 5px 10px; - border: 1px solid rgba(0,0,0,0); - border-radius: 3px; - color: #ccc; - left: -5px; - background-color: rgba(255,255,255,0.75); -} -.lt-menu svg { - font-size: 40px; - text-align: center; -} -.lt-menu label { - font-size: small; -} - .dev-buttons { margin: 1px -1px 0 -1px; } @@ -1485,28 +1442,6 @@ th, tr, td, label { #mod-tools .set-header { margin: 0; } -/* .devlist { - background-color: #fdfdfd; -} -.devlist button { - margin: 1px; - padding: 2px; - border: 0; - border-radius: 0; - font-size: 11px; - font-family: sans-serif; - background-color: #f8f8f8; - text-align: left; - min-height: 1.5em; -} -.devlist button:hover { - background-color: var(--main-color); - color: white; -} -.devlist button.selected { - background-color: var(--highlight); - border: 1px solid var(--highlight); -} */ #mod-help svg { width: 36px; height: 36px; @@ -1842,14 +1777,6 @@ th, tr, td, label { .t-inset { padding: 3px; } -.t-pad { - width: 5px; - height: 5px; -} -.t-pad2 { - width: 10px; - height: 10px; -} #devices { width: 225px; diff --git a/web/kiri/index.html b/web/kiri/index.html index d5b74a8e..d3d3ec31 100644 --- a/web/kiri/index.html +++ b/web/kiri/index.html @@ -211,6 +211,70 @@
loading
+ +
+
+ +
+
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+
+
+ +
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
+
+ + [0] + + - + + - +
+ + + +
+
+ + + + + + + +
+
+
@@ -254,17 +318,6 @@
-
- - - - - - - - - -
@@ -446,13 +499,15 @@
-
- - -
- - -
+
+
+ + +
+
+ + +
@@ -462,19 +517,13 @@

-
+
-
-
-
-
-
-
@@ -494,14 +543,6 @@
- -
- - -
- -
-
@@ -525,68 +566,6 @@
- -
-
- -
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- -
- -
- -
- -
- -
- -
- - -
-
-
-
- - [0] - - - - - - -
- - - -
-
- -
-