checkpoint reflow

This commit is contained in:
Stewart Allen 2024-05-22 18:20:02 -04:00
commit 76171c2474
5 changed files with 345 additions and 297 deletions

View file

@ -144,7 +144,7 @@ CAM.init = function(kiri, api) {
isIndexed = undefined;
isCamMode = mode === 'CAM';
SPACE.platform.setColor(isCamMode ? 0xeeeeee : 0xcccccc);
api.uc.setVisible($('camops'), isCamMode && isArrange);
api.uc.setClass($('right-work'), 'slim-hide', isCamMode);
api.uc.setVisible(UI.func.animate, isCamMode);
if (!isCamMode) {
func.clearPops();
@ -162,8 +162,7 @@ CAM.init = function(kiri, api) {
isAnimate = false;
animFn().animate_clear(api);
func.clearPops();
api.uc.setVisible($('camops'), isCamMode && isArrange);
// $('camops').style.display = isCamMode && isArrange ? 'flex' : '';
api.uc.setClass($('right-work'), 'slim-hide', isCamMode);
if (isCamMode && isPreview) {
for (let widget of API.widgets.all()) {
widget.setAxisIndex(0);
@ -636,13 +635,13 @@ CAM.init = function(kiri, api) {
for (let el of bounds) {
if (el === target) continue;
let rect = el.getBoundingClientRect();
let left = rect.left;
let right = rect.left + rect.width;
let top = rect.top;
let bottom = rect.bottom;// + rect.height;
let tar = mobile ? ev.touches[0] : ev;
if (tar.pageX >= left && tar.pageX <= right) {
let mid = (left + right) / 2;
if (tar.pageY >= top && tar.pageY <= bottom) {
let mid = (top + bottom) / 2;
try { listel.removeChild(target); } catch (e) { }
el.insertAdjacentElement(tar.pageX < mid ? "beforebegin" : "afterend", target);
el.insertAdjacentElement(tar.pageY < mid ? "beforebegin" : "afterend", target);
}
}
}

View file

@ -961,8 +961,8 @@ gapp.register("kiri.main", [], (root, exports) => {
}
function setControlsVisible(show) {
$('mid-lcol').style.display = show ? 'flex' : 'none';
$('mid-rcol').style.display = show ? 'flex' : 'none';
$('mid-left').style.display = show ? 'flex' : 'none';
$('mid-right').style.display = show ? 'flex' : 'none';
}
function downloadBlob(data, filename) {

View file

@ -80,10 +80,13 @@ gapp.register("kiri.ui", [], (root, exports) => {
alert,
onBlur,
setVisible(el, bool) {
kiri.ui.setClass(el, 'hide', bool);
},
setClass(el, clazz, bool) {
if (bool) {
el.classList.remove('hide');
el.classList.remove(clazz);
} else {
el.classList.add('hide');
el.classList.add(clazz);
}
}
};

View file

@ -2,234 +2,53 @@
--fg-gray: #495057;
--bg-gray: rgba(0,0,0,0.25);
--gradbar: linear-gradient(to right, #ddd, #666, #ddd);
--gradbar-vert: linear-gradient(to bottom, #ddd, #666, #ddd);
--holdbar: linear-gradient(to top, rgba(100,100,100,0.1), rgba(255,255,255,1), rgba(100,100,100,0.1));
--holdbar-dk: linear-gradient(to top, rgba(100,100,100,0.1), rgba(255,255,255,0.25), rgba(100,100,100,0.1));
--holdbar-sf: linear-gradient(to top, rgba(200,200,200,0.1), rgba(255,255,255,1), rgba(200,200,200,0.1)) !important;
--highlight: rgba(126,153,183,0.4);
--main-color: rgba(126,153,183,1);
--main-color-hover: rgb(96, 127, 164);
--top: rgba(255,255,255,0.75);
--work-area: rgba(255,255,255,0.75);
--menu: #f0f0f0;
--menu-text: #222;
--menu-border: #555;
--dark-menu-text: #111;
--menu-hover: #ddd;
}
/* surface size configuration and font import */
@font-face {
font-family: 'Russo One';
src: url('/moto/russo-one.ttf');
}
a, a:hover, a:visited {
border: none;
color: inherit;
text-decoration: none;
}
#app {
position: fixed;
overflow: hidden;
font-weight: normal;
font-family: sans-serif;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
@media only screen and (max-width : 1024px) {
#top {
font-size: smaller;
}
}
#top {
text-transform: capitalize;
background-color: var(--top);
z-index: 15;
font-family: sans-serif;
}
#top > div {
margin: 0 5px 0 5px;
@media only screen and (max-height : 750px) {
.lt-menu, .pop-lcol {
font-size: 16px !important;
}
.lt-menu svg {
font-size: 30px !important;
}
.pop-lcol svg {
font-size: 20px !important;
}
#mod-x {
position: absolute;
font-size: 30px;
top: 8px;
}
}
.top-menu {
display: flex;
gap: 3px;
align-items: center;
white-space: nowrap;
}
.top-menu > span {
padding: 3px 6px 3px 6px;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
}
.top-menu hr {
width: calc(100% - 3px);
margin: 0;
border: 0;
padding: 0;
height: 0.5px;
background-color: var(--menu-border);
}
.top-menu label {
color: #444;
}
.dark .top-menu label {
color: var(--dark-menu-text)
}
.top-menu svg {
color: var(--main-color);
}
.top-menu > span {
position: relative;
display: flex;
gap: 5px;
align-items: center;
}
.top-menu > span:hover label {
color: var(--menu-text);
}
.dark .top-menu > span:hover label {
color: var(--dark-menu-text) !important;
}
.top-menu > span:hover > svg {
color: var(--main-color-hover);
}
.top-menu > span:hover {
background-color: var(--menu);
border-left: 1px solid var(--menu-border);
border-right: 1px solid var(--menu-border);
}
.top-menu > span:hover .top-menu-drop {
display: flex;
}
.top-menu-left {
align-items: self-start;
}
.top-menu-left .content {
border-top-right-radius: 4px;
}
.top-menu-right {
align-items: self-end;
}
.top-menu-center .content > div > label {
text-align: center !important;
}
.top-menu-right .content {
border-top-left-radius: 4px;
}
.top-menu-drop {
position: absolute;
display: none;
top: 100%;
left: -1px;
right: -1px;
flex-direction: column;
font-family: sans-serif;
}
.top-menu-drop svg {
width: 15px;
}
#top .content {
gap: 2px;
display: flex;
align-items: center;
flex-direction: column;
background-color: var(--menu);
border-top: 1px dashed var(--menu-border);
border-left: 1px solid var(--menu-border);
border-right: 1px solid var(--menu-border);
border-bottom: 1px solid var(--menu-border);
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
}
#top .content {
display: flex;
flex-direction: column;
align-items: stretch;
padding: 2px;
}
#top .content > div {
display: flex;
flex-direction: row;
}
#top .content > div > label {
text-align: left;
flex-grow: 1;
}
#top .content > div > span {
text-align: right;
}
#top .content > div > span {
padding: 2px 7px 2px 7px;
padding-left: 10px;
text-align: center;
}
#top .content > div > label {
padding: 2px 7px 2px 7px;
justify-self: stretch;
align-self: stretch;
border-radius: 3px;
}
#top .content > div:hover {
background-color: var(--menu-hover);
}
#app-name {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
z-index: 50;
}
#app-name {
cursor: pointer;
}
.km-font {
font-family: 'Russo One', sans-serif;
}
.menu-title {
font-size: larger;
font-weight: bold;
}
#app-name hr {
margin: 1px;
}
#app-name:hover #app-name-pop {
display: flex;
}
#app-name-pop {
color: var(--fg-gray);
font-family: sans-serif;
position: absolute;
top: 100%;
}
#app-name-pop .content {
text-align: center;
}
#app-lang {
justify-content: flex-end;
}
#app-lang:hover #lang-pop {
display: flex;
}
#app,div {
display: flex;
padding: 0;
border: 0;
margin: 0;
}
#gsbox {
width: 40px;
height: 40px;
padding-right: 15px;
position: fixed;
display: none;
/* default element configuration */
a, a:hover, a:visited {
border: none;
color: inherit;
text-decoration: none;
}
div {
position: relative;
@ -332,6 +151,200 @@ th, tr, td, span, div, label, button {
th, tr, td, label {
white-space: nowrap;
}
/* container for entire page / app */
#app {
position: fixed;
overflow: hidden;
font-weight: normal;
font-family: sans-serif;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
/* top menu bar, drop menus */
#top {
background-color: var(--work-area);
text-transform: capitalize;
font-family: sans-serif;
z-index: 15;
}
#top > div {
margin: 0 5px 0 5px;
}
.top-menu {
display: flex;
gap: 3px;
align-items: center;
white-space: nowrap;
}
.top-menu > span {
padding: 3px 6px 3px 6px;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
}
.top-menu hr {
width: calc(100% - 3px);
margin: 0;
border: 0;
padding: 0;
height: 0.5px;
background-color: var(--menu-border);
}
.top-menu label {
color: #444;
}
.dark .top-menu label {
color: var(--dark-menu-text)
}
.top-menu svg {
color: var(--main-color);
}
.top-menu > span {
position: relative;
display: flex;
gap: 5px;
align-items: center;
}
.top-menu > span:hover label {
color: var(--menu-text);
}
.dark .top-menu > span:hover label {
color: var(--dark-menu-text) !important;
}
.top-menu > span:hover > svg {
color: var(--main-color-hover);
}
.top-menu > span:hover {
background-color: var(--menu);
border-left: 1px solid var(--menu-border);
border-right: 1px solid var(--menu-border);
}
.top-menu > span:hover .top-menu-drop {
display: flex;
}
.top-menu-left {
align-items: self-start;
}
.top-menu-left .content {
border-top-right-radius: 4px;
}
.top-menu-right {
align-items: self-end;
}
.top-menu-center .content > div > label {
text-align: center !important;
}
.top-menu-right .content {
border-top-left-radius: 4px;
}
.top-menu-drop {
position: absolute;
display: none;
top: 100%;
left: -1px;
right: -1px;
flex-direction: column;
font-family: sans-serif;
}
.top-menu-drop svg {
width: 15px;
}
#top .content {
gap: 2px;
display: flex;
align-items: center;
flex-direction: column;
background-color: var(--menu);
border-top: 1px dashed var(--menu-border);
border-left: 1px solid var(--menu-border);
border-right: 1px solid var(--menu-border);
border-bottom: 1px solid var(--menu-border);
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
}
#top .content {
display: flex;
flex-direction: column;
align-items: stretch;
padding: 2px;
}
#top .content > div {
display: flex;
flex-direction: row;
}
#top .content > div > label {
text-align: left;
flex-grow: 1;
}
#top .content > div > span {
text-align: right;
}
#top .content > div > span {
padding: 2px 7px 2px 7px;
padding-left: 10px;
text-align: center;
}
#top .content > div > label {
padding: 2px 7px 2px 7px;
justify-self: stretch;
align-self: stretch;
border-radius: 3px;
}
#top .content > div:hover {
background-color: var(--menu-hover);
}
#app-name {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
z-index: 50;
}
#app-name {
cursor: pointer;
}
#app-name hr {
margin: 1px;
}
#app-name:hover #app-name-pop {
display: flex;
}
#app-name-pop {
color: var(--fg-gray);
font-family: sans-serif;
position: absolute;
top: 100%;
}
#app-name-pop .content {
text-align: center;
}
#app-lang {
justify-content: flex-end;
}
#app-lang:hover #lang-pop {
display: flex;
}
#app,div {
display: flex;
padding: 0;
border: 0;
margin: 0;
}
#loading {
width: 40px;
height: 40px;
padding-right: 15px;
position: fixed;
display: none;
}
.noselect {
-khtml-user-select: none;
-moz-user-select: none;
@ -339,6 +352,14 @@ th, tr, td, label {
user-select: none;
}
.km-font {
font-family: 'Russo One', sans-serif;
}
.menu-title {
font-size: larger;
font-weight: bold;
}
.hide {
display: none !important;
}
@ -469,17 +490,19 @@ th, tr, td, label {
bottom: 0;
left: 0;
right: 0;
z-index: -1;
}
.chonk {
height: 15px;
min-width: 100px;
background-color: rgba(0,0,0,0.25);
}
#mode-info {
/* display: none; */
white-space: nowrap;
font-size: smaller;
font-family: sans-serif;
top: 50%;
height: 100%;
/* transform: translateY(-50%); */
padding: 1px 0 1px 0;
align-items: center;
align-items: stretch;
justify-content: center;
padding: 3px;
}
@ -496,7 +519,7 @@ th, tr, td, label {
border-left: 1px solid #ddd;
border-bottom: 1px solid #ddd;
}
#mode-info > div {
#mode-info span {
font-size: smaller;
padding: 2px 5px 2px 5px;
color: var(--fg-gray);
@ -586,23 +609,37 @@ th, tr, td, label {
text-transform: none !important;
}
#mid-lcol, #mid-rcol, #modal {
#mid-left {
background-color: var(--work-area);
}
#mid-left, #mid-right, #modal {
pointer-events: visible;
text-transform: capitalize;
}
#mid-lcol label, #mid-lcol svg {
#mid-left label, #mid-left svg {
pointer-events: none;
}
#right-work {
overflow: hidden;
}
.slim-hide {
width: 0;
}
#top-sep {
display: none;
}
#top-sep, #mid-sep {
#top-sep, #top-mid-sep {
z-index: 14;
height: 1px;
background-image: var(--gradbar);
}
.mid-sep {
z-index: 14;
width: 1px;
background-image: var(--gradbar-vert);
}
.movable {
margin: 5px;
@ -816,22 +853,6 @@ th, tr, td, label {
.lt-menu label {
font-size: small;
}
@media only screen and (max-height : 750px) {
.lt-menu, .pop-lcol {
font-size: 16px !important;
}
.lt-menu svg {
font-size: 30px !important;
}
.pop-lcol svg {
font-size: 20px !important;
}
#mod-x {
position: absolute;
font-size: 30px;
top: 8px;
}
}
.dev-buttons {
margin: 1px -1px 0 -1px;
@ -871,6 +892,7 @@ th, tr, td, label {
text-align: center;
font-size: smaller;
}
#camop_dialog {
flex-direction: column;
}
@ -884,35 +906,22 @@ th, tr, td, label {
display: block;
}
#camops {
background-color: var(--work-area);
display: flex;
padding: 0;
height: 38px;
margin: 0 0 max(4px, env(safe-area-inset-bottom)) 0;
}
#camops .left {
width: 12px;
border-top-left-radius: 10px;
border-bottom-left-radius: 10px;
background-color: var(--main-color);
margin-right: 1px;
}
#camops .right {
width: 12px;
border-top-right-radius: 10px;
border-bottom-right-radius: 10px;
background-color: var(--main-color);
margin-left: 1px;
padding: 5px 0 0 0;
}
.cam-pop-op {
text-align: left;
position: absolute;
white-space: nowrap;
flex-direction: column;
bottom: 40px;
top: 0;
right: 100%;
/* transform: translateY(-30%); */
background-color: rgba(255,255,255,0.8);
border: 1px solid #aaa;
border-radius: 5px;
margin-right: 5px;
margin-right: 6px;
padding: 5px;
}
.pop-tics {
@ -936,6 +945,10 @@ th, tr, td, label {
word-break: break-word;
white-space: normal;
}
#oplist {
gap: 3px;
margin-bottom: 3px;
}
#oplist > div, .opdiv {
display: flex;
flex-direction: column;
@ -943,8 +956,8 @@ th, tr, td, label {
justify-content: center;
border: 1px solid rgba(0,0,0,0.25);
border-radius: 4px;
margin: 0 2px 0 2px;
padding: 2px 10px 2px 10px;
margin: 0 5px 0 5px;
padding: 5px 10px 5px 10px;
background-color: rgba(255,255,255,0.75);
white-space: nowrap;
}
@ -1006,8 +1019,9 @@ th, tr, td, label {
#op-add-pop {
position: absolute;
display: none;
padding: 5px;
bottom: 35px;
right: 100%;
top: 0;
transform: translateY(-50%);
}
#op-add:hover #op-add-pop {
display: flex;
@ -1795,10 +1809,6 @@ th, tr, td, label {
align-items: stretch;
text-transform: capitalize;
background-color: rgba(255,255,255,0.5);
/* border: 1px solid var(--menu-border); */
border: 1px solid #aaa;
border-bottom-right-radius: 5px;
border-top-right-radius: 5px;
padding: 5px;
gap: 5px;
}
@ -1997,7 +2007,7 @@ th, tr, td, label {
#rnfo label {
text-align: right;
}
#tool-info {
/* #tool-info {
position: fixed;
white-space: pre;
background-color: rgba(255,255,255,0.25);
@ -2007,7 +2017,7 @@ th, tr, td, label {
font-family: monospace;
font-size: 12px;
color: #000;
}
} */
#context-menu {
display: none;
position: absolute;

View file

@ -28,12 +28,10 @@
</head>
<body>
<div id="app" class="f-col">
<div id="curtain" class="j-center a-center"><img id="gsbox">loading...</div>
<div id="container"></div>
<div id="tracker"></div>
<div id="curtain" class="j-center a-center"><img id="loading">loading...</div>
<div id="top-sep"></div>
<!-- TOP MENU BAR -->
<div id="top" class="f-row">
<div class="f-row top-menu">
<span>
@ -240,81 +238,22 @@
</div>
<div id="set-prefs">
<label lk="prefs">prefs</label>
<span><i class="fa-solid fa-ssquare-check"></i></span>
<span><i class="fa-solid fa-square-check"></i></span>
</div>
</div>
</div>
</span>
</div>
</div>
<div id="mid-sep"></div>
<div id="float-tools" class="f-col movable hide">
<div id="float-tools-title" class="title mover">
<label id="ft-label" class="grow">title bar</label>
<div id="float-tools-close" class="closer"><i class="fas fa-times"></i></div>
</div>
<div class="body f-row">
<div class="f-col menu">
<div lkt="rotate" class="tictac" select="ft-rotate" label="ft-label"><i class="fas fa-sync-alt"></i></div>
<div lkt="scale" class="tictac" select="ft-scale" label="ft-label"><i class="fas fa-expand"></i></div>
<div lkt="mesh" class="tictac" select="ft-mesh" label="ft-label"><i class="fas fa-dice-d20"></i></div>
<div lkt="select" class="tictac" select="ft-select" label="ft-label"><i class="fas fa-mouse-pointer"></i></div>
</div>
<div id="ft-scale" class="grow grid">
<div><label class="middle">X</label><input id="lock_x" type="checkbox" checked></div>
<div><label class="middle">Y</label><input id="lock_y" type="checkbox" checked></div>
<div><label class="middle">Z</label><input id="lock_z" type="checkbox" checked></div>
<div><label id="lab-axis" lk="axis">axis</label></div>
<div><input id="size_x" size="8" class="value"></div>
<div><input id="size_y" size="8" class="value"></div>
<div><input id="size_z" size="8" class="value"></div>
<div><label id="lab-size" lk="size">size</label></div>
<div><input id="scale_x" size="8" class="value" value="1"></div>
<div><input id="scale_y" size="8" class="value" value="1"></div>
<div><input id="scale_z" size="8" class="value" value="1"></div>
<div><label id="lab-scale" lk="scale">scale</label></div>
<button id="scale-reset" class="gr4">reset</button>
</div>
<div id="ft-rotate" class="grow grid">
<div id="rot_x_lt"><i class="fas fa-chevron-left"></i></div>
<label>X</label>
<div id="rot_x_gt"><i class="fas fa-chevron-right"></i></div>
<input id="rot_x" class="value center" size="6" value="0">
<div id="rot_y_lt"><i class="fas fa-chevron-left"></i></div>
<label>Y</label>
<div id="rot_y_gt"><i class="fas fa-chevron-right"></i></div>
<input id="rot_y" class="value center" size="6" value="0">
<div id="rot_z_lt"><i class="fas fa-chevron-left"></i></div>
<label>Z</label>
<div id="rot_z_gt"><i class="fas fa-chevron-right"></i></div>
<input id="rot_z" class="value center" size="6" value="0">
<div class="buttons f-row">
<button id="lay-flat" class="grow">lay flat</button>
<button id="unrotate" class="grow" lk="reset">reset</button>
</div>
</div>
<div id="ft-mesh" class="grow f-col">
<div id="mesh-info" class="grid">
<label>object:</label>
<span id="mesh-name" class="value">[0]</span>
<label>points:</label>
<span id="mesh-points" class="value">-</span>
<label>faces:</label>
<span id="mesh-faces" class="value">-</span>
</div>
<button id="mesh-export-obj" lk="rc_xobj">export OBJ</button>
<button id="mesh-export-stl" lk="rc_xstl">export STL</button>
<button id="mesh-swap" lk="rc_swap">replace vertices</button>
</div>
<div id="ft-select" class="grow f-col"></div>
</div>
<div class="footer"></div>
</div>
<div id="top-mid-sep"></div>
<div id="mid" class="grow f-row">
<div id="progress"><div id="progbar"><div id="progtxt">loading</div></div></div>
<div id="mid-lcol" class="f-col j-center noshow">
<!-- left settings menu -->
<div id="mid-left" class="f-col j-left noshow">
<!-- ephemeral -->
<div id="lt-back" class="lt-menu lt-enabled">
<i class="fas fa-arrow-circle-left"></i>
</div>
@ -323,9 +262,21 @@
<div id="lt-w-enable"><i class="fas fa-check-circle"></i></div>
<div id="lt-w-disable"><i class="fas fa-times-circle"></i></div>
</div>
<div id="settings" class="f-col"></div>
<!-- always up -->
<div class="chonk"></div>
<div id="mode-info" class="f-col">
<div><label>Mode</label><span id="app-mode-name"></span></div>
<div><label>Device</label><span id="mode-device"></span></div>
<div><label>Profile</label><span id="mode-profile"></span></div>
</div>
<div class="chonk"></div>
<div id="settings" class="f-col grow"></div>
<div class="chonk"></div>
</div>
<div id="mid-mcol" class="grow">
<div class="mid-sep"></div>
<div id="mid-mid" class="grow">
<div id="modal">
<div id="modal-box" class="f-col">
@ -501,54 +452,69 @@
</div>
</div>
</div>
<div id="mid-rcol" class="f-col j-center noshow">
<div id="mid-right" class="f-row j-center">
<div id="set-menu" class="f-col">
<div id="speeds"><div id="speedbar" class="f-col a-stretch j-center" lkt="sb_info"></div></div>
<!-- <div id="set-top" class="set-group"></div>
<div id="settings" class="f-col"></div>
<div id="set-end" class="set-group"></div> -->
</div>
</div>
</div>
<div id="end" class="f-col a-center">
<div id="bottom">
<div id="camops" class="f-row a-stretch j-center">
<div class="left"></div>
<div id="oplist" class="f-row j-center"></div>
<div id="ophint" class="f-row">
<div class="opdiv">use + menu to add milling operations</div>
<div class="opdiv">drag to re-order</div>
</div>
<div id="op-add" class="opdiv">
<i class="fas fa-plus"></i>
<div id="op-add-pop" class="f-col">
<div id="op-add-list" class="opdiv op-grid">
<div id="cam-index" title="rotate index axis">index</div>
<div id="cam-lathe" title="lathe operation">lathe</div>
<div id="laser-on" title="turn on laser mode">laser on</div>
<div id="laser-off" title="turn off laser mode">laser off</div>
<div id="cam-flip" title="flip part and load&#13;profile for other side&#13;for double-sided work">flip</div>
<div id="cam-reg" title="drill registration holes&#13;along the X or Y axis&#13;for double-sided work">register</div>
<div title="drill any holes matching&#13;selected tool diameter">drill</div>
<div title="clear stock face&#13;or top of part&#13;when no stock">level</div>
<div title="follow selected features with&#13;a specified tool. often used&#13;for lettering and engraving">trace</div>
<div title="insert custom gcode">gcode</div>
<div title="remove an area of material&#13;inside a defined boundary&#13;sometimes called pocketing">rough</div>
<div title="clean up after roughing&#13;or perform a part cutout">outline</div>
<div title="2.5D tracing along X or Y axis&#13;used for complex part features">contour</div>
<div title="clear areas above&#13;selected surfaces">pocket</div>
<div class="mid-sep"></div>
<div id="right-work" class="f-col j-center slim-hide">
<div class="chonk"></div>
<div>operation chain</div>
<div class="chonk"></div>
<div id="camops" class="f-col a-stretch grow">
<div id="oplist" class="f-col j-center"></div>
<div id="ophint" class="f-row">
<div class="opdiv">use + menu to add milling operations</div>
<div class="opdiv">drag to re-order</div>
</div>
<div id="op-add" class="opdiv">
<i class="fas fa-plus"></i>
<div id="op-add-pop" class="f-col">
<div id="op-add-list" class="opdiv op-grid">
<div id="cam-index" title="rotate index axis">index</div>
<div id="cam-lathe" title="lathe operation">lathe</div>
<div id="laser-on" title="turn on laser mode">laser on</div>
<div id="laser-off" title="turn off laser mode">laser off</div>
<div id="cam-flip" title="flip part and load&#13;profile for other side&#13;for double-sided work">flip</div>
<div id="cam-reg" title="drill registration holes&#13;along the X or Y axis&#13;for double-sided work">register</div>
<div title="drill any holes matching&#13;selected tool diameter">drill</div>
<div title="clear stock face&#13;or top of part&#13;when no stock">level</div>
<div title="follow selected features with&#13;a specified tool. often used&#13;for lettering and engraving">trace</div>
<div title="insert custom gcode">gcode</div>
<div title="remove an area of material&#13;inside a defined boundary&#13;sometimes called pocketing">rough</div>
<div title="clean up after roughing&#13;or perform a part cutout">outline</div>
<div title="2.5D tracing along X or Y axis&#13;used for complex part features">contour</div>
<div title="clear areas above&#13;selected surfaces">pocket</div>
</div>
</div>
</div>
</div>
<div class="right"></div>
<div class="chonk"></div>
</div>
</div>
</div>
<div id="end" class="f-col a-center">
<div id="bottom">
</div>
</div>
<!-- ThreeJS container -->
<div id="container"></div>
<!-- click + drag mouse tracking -->
<div id="tracker"></div>
<!-- EU compliance -->
<div id="gdpr" class="noshow">
<p>this site uses <A href="/privacy.html" target="privacy">cookies</a> to preserve application preferences</p>
<button id="gotit" class="f-col j-center">got it</button>
</div>
<div id="tool-info" class="noshow"></div>
<!-- <div id="tool-info" class="noshow"></div> -->
<!-- right click pop-up menu -->
<div id="context-menu">
<button id="context-export-workspace" lk="rc_xpws">export workspace</button>
<button id="context-clear-workspace" lk="rc_clws">clear workspace</button>
@ -561,28 +527,98 @@
</div>
<div id="app-state">
<div id="mode-info" class="f-row">
<!-- <div id="mode-info" class="f-row">
<label>Mode</label><div id="app-mode-name"></div>
<label>Device</label><div id="mode-device"></div>
<label>Profile</label><div id="mode-profile"></div>
</div>
</div> -->
</div>
<!-- developer debugging -->
<div id="stats">
<div id="rms"></div>
<div id="fps"></div>
<div id="rnfo"></div>
</div>
<!-- CAM animation controls and readout -->
<div id="layer-animate" class="f-col a-center"></div>
<div id="layer-toolpos" class="f-row a-center"></div>
<!-- ephemeral non-modal alerts -->
<div id="alert-area">
<div id="alert-border">
<div id="alert-text">alerts<br>alerts<br>alerts</div>
</div>
</div>
<div id="top-slider" class="f-col grow">
<input id="anim-slider" type="range" min="0" max="1000" value="0"></input>
</div>
<div id="float-tools" class="f-col movable hide">
<div id="float-tools-title" class="title mover">
<label id="ft-label" class="grow">title bar</label>
<div id="float-tools-close" class="closer"><i class="fas fa-times"></i></div>
</div>
<div class="body f-row">
<div class="f-col menu">
<div lkt="rotate" class="tictac" select="ft-rotate" label="ft-label"><i class="fas fa-sync-alt"></i></div>
<div lkt="scale" class="tictac" select="ft-scale" label="ft-label"><i class="fas fa-expand"></i></div>
<div lkt="mesh" class="tictac" select="ft-mesh" label="ft-label"><i class="fas fa-dice-d20"></i></div>
<div lkt="select" class="tictac" select="ft-select" label="ft-label"><i class="fas fa-mouse-pointer"></i></div>
</div>
<div id="ft-scale" class="grow grid">
<div><label class="middle">X</label><input id="lock_x" type="checkbox" checked></div>
<div><label class="middle">Y</label><input id="lock_y" type="checkbox" checked></div>
<div><label class="middle">Z</label><input id="lock_z" type="checkbox" checked></div>
<div><label id="lab-axis" lk="axis">axis</label></div>
<div><input id="size_x" size="8" class="value"></div>
<div><input id="size_y" size="8" class="value"></div>
<div><input id="size_z" size="8" class="value"></div>
<div><label id="lab-size" lk="size">size</label></div>
<div><input id="scale_x" size="8" class="value" value="1"></div>
<div><input id="scale_y" size="8" class="value" value="1"></div>
<div><input id="scale_z" size="8" class="value" value="1"></div>
<div><label id="lab-scale" lk="scale">scale</label></div>
<button id="scale-reset" class="gr4">reset</button>
</div>
<div id="ft-rotate" class="grow grid">
<div id="rot_x_lt"><i class="fas fa-chevron-left"></i></div>
<label>X</label>
<div id="rot_x_gt"><i class="fas fa-chevron-right"></i></div>
<input id="rot_x" class="value center" size="6" value="0">
<div id="rot_y_lt"><i class="fas fa-chevron-left"></i></div>
<label>Y</label>
<div id="rot_y_gt"><i class="fas fa-chevron-right"></i></div>
<input id="rot_y" class="value center" size="6" value="0">
<div id="rot_z_lt"><i class="fas fa-chevron-left"></i></div>
<label>Z</label>
<div id="rot_z_gt"><i class="fas fa-chevron-right"></i></div>
<input id="rot_z" class="value center" size="6" value="0">
<div class="buttons f-row">
<button id="lay-flat" class="grow">lay flat</button>
<button id="unrotate" class="grow" lk="reset">reset</button>
</div>
</div>
<div id="ft-mesh" class="grow f-col">
<div id="mesh-info" class="grid">
<label>object:</label>
<span id="mesh-name" class="value">[0]</span>
<label>points:</label>
<span id="mesh-points" class="value">-</span>
<label>faces:</label>
<span id="mesh-faces" class="value">-</span>
</div>
<button id="mesh-export-obj" lk="rc_xobj">export OBJ</button>
<button id="mesh-export-stl" lk="rc_xstl">export STL</button>
<button id="mesh-swap" lk="rc_swap">replace vertices</button>
</div>
<div id="ft-select" class="grow f-col"></div>
</div>
<div class="footer"></div>
</div>
</div>
</body>
</html>