mesh app work. improve script setup
This commit is contained in:
parent
224a7535c6
commit
16fa536605
8 changed files with 286 additions and 86 deletions
84
app.js
84
app.js
|
|
@ -289,7 +289,7 @@ const script = {
|
||||||
"kiri/tools",
|
"kiri/tools",
|
||||||
"@devices",
|
"@devices",
|
||||||
"@icons"
|
"@icons"
|
||||||
].map(p => p.charAt(0) !== '@' ? `src/${p}.js` : p),
|
],
|
||||||
worker : [
|
worker : [
|
||||||
"main/kiri",
|
"main/kiri",
|
||||||
"ext/three",
|
"ext/three",
|
||||||
|
|
@ -341,7 +341,7 @@ const script = {
|
||||||
"kiri/print",
|
"kiri/print",
|
||||||
"kiri/codec",
|
"kiri/codec",
|
||||||
"kiri/worker"
|
"kiri/worker"
|
||||||
].map(p => `src/${p}.js`),
|
],
|
||||||
minion : [
|
minion : [
|
||||||
"main/kiri",
|
"main/kiri",
|
||||||
"add/license",
|
"add/license",
|
||||||
|
|
@ -367,7 +367,7 @@ const script = {
|
||||||
"kiri/widget",
|
"kiri/widget",
|
||||||
"kiri/codec",
|
"kiri/codec",
|
||||||
"kiri/minion"
|
"kiri/minion"
|
||||||
].map(p => `src/${p}.js`),
|
],
|
||||||
engine : [
|
engine : [
|
||||||
"main/kiri",
|
"main/kiri",
|
||||||
"add/license",
|
"add/license",
|
||||||
|
|
@ -394,10 +394,10 @@ const script = {
|
||||||
"kiri/widget",
|
"kiri/widget",
|
||||||
"kiri/codec",
|
"kiri/codec",
|
||||||
"kiri/engine"
|
"kiri/engine"
|
||||||
].map(p => `src/${p}.js`),
|
],
|
||||||
frame : [
|
frame : [
|
||||||
"kiri/frame"
|
"kiri/frame"
|
||||||
].map(p => `src/${p}.js`),
|
],
|
||||||
meta : [
|
meta : [
|
||||||
"ext/three",
|
"ext/three",
|
||||||
"add/license",
|
"add/license",
|
||||||
|
|
@ -425,32 +425,19 @@ const script = {
|
||||||
"moto/ui",
|
"moto/ui",
|
||||||
"kiri/catalog",
|
"kiri/catalog",
|
||||||
"main/meta"
|
"main/meta"
|
||||||
].map(p => `src/${p}.js`),
|
],
|
||||||
mesh : [
|
mesh : [
|
||||||
"main/mesh",
|
"main/mesh",
|
||||||
|
"moto/client",
|
||||||
"ext/three",
|
"ext/three",
|
||||||
"ext/three-bgu",
|
"ext/three-bgu",
|
||||||
"ext/three-svg",
|
"ext/three-svg",
|
||||||
"ext/jszip",
|
|
||||||
"add/license",
|
"add/license",
|
||||||
"ext/clip2",
|
|
||||||
"ext/tween",
|
"ext/tween",
|
||||||
"ext/fsave",
|
"ext/fsave",
|
||||||
"ext/earcut",
|
|
||||||
"ext/base64",
|
|
||||||
"add/array",
|
"add/array",
|
||||||
"add/three",
|
"add/three",
|
||||||
"geo/base",
|
|
||||||
"geo/point",
|
|
||||||
"geo/points",
|
|
||||||
"geo/slope",
|
|
||||||
"geo/line",
|
|
||||||
"geo/bounds",
|
|
||||||
"geo/polygon",
|
|
||||||
"geo/polygons",
|
|
||||||
"geo/mesh",
|
"geo/mesh",
|
||||||
// "moto/kv",
|
|
||||||
// "moto/ajax",
|
|
||||||
"moto/ctrl",
|
"moto/ctrl",
|
||||||
"moto/space",
|
"moto/space",
|
||||||
"moto/load-3mf",
|
"moto/load-3mf",
|
||||||
|
|
@ -460,28 +447,35 @@ const script = {
|
||||||
"moto/load-url",
|
"moto/load-url",
|
||||||
"moto/load-file",
|
"moto/load-file",
|
||||||
"moto/broker",
|
"moto/broker",
|
||||||
"moto/db",
|
"moto/db"
|
||||||
// "kiri/ui",
|
],
|
||||||
// "kiri/do",
|
mesh_work : [
|
||||||
// "kiri/lang",
|
"moto/worker",
|
||||||
// "kiri/lang-en",
|
"add/license",
|
||||||
// "kiri/catalog",
|
"ext/jszip",
|
||||||
// "kiri/slice",
|
"ext/clip2",
|
||||||
// "kiri/layers",
|
"ext/earcut",
|
||||||
// "kiri/client",
|
"ext/base64",
|
||||||
// "kiri/stack",
|
"ext/three",
|
||||||
// "kiri/stacks",
|
"add/three",
|
||||||
// "kiri/widget",
|
"ext/three-bgu",
|
||||||
// "kiri/print",
|
"geo/base",
|
||||||
// "kiri/codec",
|
"geo/point",
|
||||||
// "kiri/conf",
|
"geo/points",
|
||||||
// "kiri/main",
|
"geo/slope",
|
||||||
// "kiri/init",
|
"geo/line",
|
||||||
// "kiri/export",
|
"geo/bounds",
|
||||||
// "kiri/tools",
|
"geo/polygon",
|
||||||
].map(p => `src/${p}.js`),
|
"geo/polygons",
|
||||||
|
"geo/mesh",
|
||||||
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// process script dependencies, expand paths
|
||||||
|
for (let [key,val] of Object.entries(script)) {
|
||||||
|
script[key] = val.map(p => p.charAt(0) !== '@' ? `src/${p}.js` : p);
|
||||||
|
}
|
||||||
|
|
||||||
// prevent caching of specified modules
|
// prevent caching of specified modules
|
||||||
const cachever = {};
|
const cachever = {};
|
||||||
|
|
||||||
|
|
@ -644,13 +638,9 @@ function generateDevices() {
|
||||||
function prepareScripts() {
|
function prepareScripts() {
|
||||||
generateIcons();
|
generateIcons();
|
||||||
generateDevices();
|
generateDevices();
|
||||||
code.meta = concatCode(script.meta);
|
for (let key of Object.keys(script)) {
|
||||||
code.mesh = concatCode(script.mesh);
|
code[key] = concatCode(script[key]);
|
||||||
code.kiri = concatCode(script.kiri);
|
}
|
||||||
code.worker = concatCode(script.worker);
|
|
||||||
code.minion = concatCode(script.minion);
|
|
||||||
code.engine = concatCode(script.engine);
|
|
||||||
code.frame = concatCode(script.frame);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function concatCode(array) {
|
function concatCode(array) {
|
||||||
|
|
|
||||||
19
notes.md
19
notes.md
|
|
@ -1,4 +1,4 @@
|
||||||
# Kiri:Moto todo and notes
|
# Kiri:Moto / Grid:Apps notes
|
||||||
|
|
||||||
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
|
## `C` cosmetic, `F` functional, `P` performance, `B` bug fix
|
||||||
|
|
||||||
|
|
@ -108,20 +108,3 @@
|
||||||
# Laser
|
# Laser
|
||||||
|
|
||||||
* `F` add PLT / HP-GL output format (https://en.wikipedia.org/wiki/HP-GL)
|
* `F` add PLT / HP-GL output format (https://en.wikipedia.org/wiki/HP-GL)
|
||||||
|
|
||||||
# References
|
|
||||||
|
|
||||||
* https://www.canva.com/colors/color-wheel/
|
|
||||||
* http://lcamtuf.coredump.cx/gcnc/full/
|
|
||||||
* http://wiki.imal.org/howto/cnc-milling-introduction-cutting-tools
|
|
||||||
* http://www.twak.co.uk/2011/01/degeneracy-in-weighted-straight.html
|
|
||||||
* http://photon.chrisgraf.de/
|
|
||||||
* https://github.com/Jack000/SVGnest
|
|
||||||
|
|
||||||
# More CNC
|
|
||||||
|
|
||||||
* https://www.researchgate.net/publication/250328721_Toolpath_Optimization_on_Automatic_Removal_Uncut_and_Application
|
|
||||||
|
|
||||||
# Meta
|
|
||||||
|
|
||||||
* free-space tetrahedron modeler with vertex mating
|
|
||||||
|
|
|
||||||
|
|
@ -48,8 +48,8 @@ if installing the app-server fails or gives you permissions errors, then your no
|
||||||
sudo npm install -g @gridspace/app-server
|
sudo npm install -g @gridspace/app-server
|
||||||
```
|
```
|
||||||
|
|
||||||
to start a local instance of the apps. then open
|
to start a local instance of the apps. then use a browser to open
|
||||||
[localhost:8080/kiri](http://localhost:8080/kiri) on your local host
|
[localhost:8080/kiri](http://localhost:8080/kiri)
|
||||||
|
|
||||||
Alternatively, if you are using a packaged version of npm that ships with
|
Alternatively, if you are using a packaged version of npm that ships with
|
||||||
a Linux distribution, but still want to install in your home directory, you
|
a Linux distribution, but still want to install in your home directory, you
|
||||||
|
|
@ -73,7 +73,7 @@ cd grid-apps
|
||||||
docker-compose -f src/dock/compose.yml up
|
docker-compose -f src/dock/compose.yml up
|
||||||
```
|
```
|
||||||
|
|
||||||
You can now access your environment of grid-apps by going to:
|
You can now access your environment of grid-apps by going to
|
||||||
[localhost:8080/kiri](http://127.0.0.1:8080/kiri)
|
[localhost:8080/kiri](http://127.0.0.1:8080/kiri)
|
||||||
|
|
||||||
### Windows Developers
|
### Windows Developers
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
// required for license and other grid app dependencies
|
// required for license and other grid app dependencies
|
||||||
self.gapp = {};
|
self.gapp = self.gapp || {};
|
||||||
|
|
||||||
function $(id) {
|
function $(id) {
|
||||||
return document.getElementById(id);
|
return document.getElementById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function $d(id, v) {
|
||||||
|
$(id).style.display = v;
|
||||||
|
}
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
let container = $('container'),
|
let container = $('container'),
|
||||||
moto = self.moto,
|
moto = self.moto,
|
||||||
|
|
@ -28,10 +32,13 @@ function init() {
|
||||||
Space.useDefaultKeys(true);
|
Space.useDefaultKeys(true);
|
||||||
|
|
||||||
// hide loading curtain
|
// hide loading curtain
|
||||||
$('curtain').style.display = 'none';
|
$d('curtain','none');
|
||||||
|
|
||||||
// remove version cache bust from url
|
// remove version cache bust from url
|
||||||
window.history.replaceState({},'','/mesh/');
|
window.history.replaceState({},'','/mesh/');
|
||||||
|
|
||||||
|
// start worker
|
||||||
|
moto.client.start(`/code/mesh_work?${gapp.version}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.onreadystatechange = function() {
|
document.onreadystatechange = function() {
|
||||||
|
|
|
||||||
124
src/moto/client.js
Normal file
124
src/moto/client.js
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
let MOTO = self.moto = self.moto || {},
|
||||||
|
time = function() { return new Date().getTime() },
|
||||||
|
restarting = false,
|
||||||
|
running = {},
|
||||||
|
workurl = null,
|
||||||
|
worker = null,
|
||||||
|
seqid = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Function} fn name of function in MOTO.worker
|
||||||
|
* @param {Object} data to send to server
|
||||||
|
* @param {Function} onreply function to call on reply messages
|
||||||
|
* @param {Object[]} zerocopy array of objects to pass using zerocopy
|
||||||
|
*/
|
||||||
|
function send(fn, data, onreply, zerocopy) {
|
||||||
|
let seq = seqid++;
|
||||||
|
|
||||||
|
if (onreply) {
|
||||||
|
// establish listener and track replies
|
||||||
|
running[seq] = { fn:onreply };
|
||||||
|
}
|
||||||
|
let msg = {
|
||||||
|
seq: seq,
|
||||||
|
task: fn,
|
||||||
|
time: time(),
|
||||||
|
data: data
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
worker.postMessage(msg, zerocopy);
|
||||||
|
} catch (error) {
|
||||||
|
console.trace('work send error', {data, error});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// code is running in the browser / client context
|
||||||
|
let CLIENT = MOTO.client = {
|
||||||
|
send: send,
|
||||||
|
|
||||||
|
// factory can be overridden
|
||||||
|
newWorker: function(url = workurl) {
|
||||||
|
if (self.createWorker) {
|
||||||
|
return self.createWorker();
|
||||||
|
} else {
|
||||||
|
return new Worker(workurl = url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// return number of running requests
|
||||||
|
current: function() {
|
||||||
|
let current = 0;
|
||||||
|
for (let rec of Object.values(running)) {
|
||||||
|
if (rec.fn) current++;
|
||||||
|
}
|
||||||
|
return current;
|
||||||
|
},
|
||||||
|
|
||||||
|
stop: function() {
|
||||||
|
if (worker) {
|
||||||
|
worker.terminate();
|
||||||
|
worker = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// same as restart
|
||||||
|
start: function(url) {
|
||||||
|
CLIENT.restart(url);
|
||||||
|
},
|
||||||
|
|
||||||
|
restart: function(url) {
|
||||||
|
// prevent re-entry from cancel callback
|
||||||
|
if (restarting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLIENT.stop();
|
||||||
|
|
||||||
|
restarting = true;
|
||||||
|
|
||||||
|
for (let key in running) {
|
||||||
|
let rec = running[key];
|
||||||
|
if (rec.fn) {
|
||||||
|
rec.fn({error: "cancelled operation"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
running = {};
|
||||||
|
worker = CLIENT.newWorker(url);
|
||||||
|
|
||||||
|
// bind to CLIENT to enable synth injections
|
||||||
|
CLIENT.onmessage = worker.onmessage = function(e) {
|
||||||
|
let now = time(),
|
||||||
|
reply = e.data,
|
||||||
|
record = running[reply.seq],
|
||||||
|
onreply = record ? record.fn : undefined;
|
||||||
|
|
||||||
|
if (reply.done) {
|
||||||
|
delete running[reply.seq];
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate and replace recv time
|
||||||
|
reply.time_recv = now - reply.time_recv;
|
||||||
|
|
||||||
|
if (onreply) {
|
||||||
|
onreply(reply.data, reply);
|
||||||
|
} else {
|
||||||
|
console.log({drop_reply: reply});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// signal worker client is ready
|
||||||
|
worker.postMessage("--init--");
|
||||||
|
|
||||||
|
restarting = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
80
src/moto/worker.js
Normal file
80
src/moto/worker.js
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
/** Copyright Stewart Allen <sa@grid.space> -- All Rights Reserved */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
|
||||||
|
let MOTO = self.moto = self.moto || {},
|
||||||
|
time = Date.now;
|
||||||
|
|
||||||
|
// allow license to inject module
|
||||||
|
self.gapp = self.gapp || MOTO;
|
||||||
|
|
||||||
|
// code is running in the worker / server context
|
||||||
|
const dispatch = MOTO.worker = {
|
||||||
|
|
||||||
|
send: (msg) => {
|
||||||
|
self.postMessage(msg);
|
||||||
|
},
|
||||||
|
|
||||||
|
onmessage: (e) => {
|
||||||
|
|
||||||
|
if (e.data === '--init--') {
|
||||||
|
console.log('worker got init');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let time_recv = time(),
|
||||||
|
msg = e.data || {},
|
||||||
|
run = dispatch[msg.task],
|
||||||
|
send = {
|
||||||
|
data : function(data,direct) {
|
||||||
|
dispatch.send({
|
||||||
|
seq: msg.seq,
|
||||||
|
task: msg.task,
|
||||||
|
done: false,
|
||||||
|
data: data
|
||||||
|
}, direct);
|
||||||
|
},
|
||||||
|
done : function(data,direct) {
|
||||||
|
dispatch.send({
|
||||||
|
seq: msg.seq,
|
||||||
|
task: msg.task,
|
||||||
|
done: true,
|
||||||
|
data: data
|
||||||
|
}, direct);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (run) {
|
||||||
|
try {
|
||||||
|
let time_xfer = (time_recv - msg.time),
|
||||||
|
output = run(msg.data, send),
|
||||||
|
time_send = time(),
|
||||||
|
time_proc = time_send - time_recv;
|
||||||
|
|
||||||
|
if (output) dispatch.send({
|
||||||
|
seq: msg.seq,
|
||||||
|
task: msg.task,
|
||||||
|
time_send: time_xfer,
|
||||||
|
time_proc: time_proc,
|
||||||
|
// replaced on reply side
|
||||||
|
time_recv: time(),
|
||||||
|
data: output
|
||||||
|
});
|
||||||
|
} catch (wrkerr) {
|
||||||
|
// console.log(wrkerr);
|
||||||
|
console.trace(wrkerr.stack);
|
||||||
|
send.done({error: wrkerr.toString()});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log({worker_unhandled: e, msg, fn: dispatch[msg.task]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// attach onmessage hanler
|
||||||
|
self.onmessage = dispatch.onmessage;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
}
|
}
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Russo One';
|
font-family: 'Russo One';
|
||||||
src: url('ext/russo-one.ttf');
|
src: url('/kiri/ext/russo-one.ttf');
|
||||||
}
|
}
|
||||||
a, a:hover, a:visited {
|
a, a:hover, a:visited {
|
||||||
border: none;
|
border: none;
|
||||||
|
|
@ -28,17 +28,33 @@ a, a:hover, a:visited {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
}
|
}
|
||||||
#app-name {
|
#app-name {
|
||||||
position: absolute;
|
xposition: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
transform: translateX(-50%) translateY(-50%);
|
transform: translateX(-50%) translateY(-50%);
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
}
|
}
|
||||||
#app-name, #app-mode-name, #app-acct {
|
#app-name:hover #app-info {
|
||||||
cursor: pointer;
|
display: flex;
|
||||||
}
|
}
|
||||||
#app-mode-name {
|
#app-info {
|
||||||
border-bottom: 2px dotted grey;
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-size: smaller;
|
||||||
|
font-family: sans-serif;
|
||||||
|
margin-top: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
left: 50%;
|
||||||
|
top: 100%;
|
||||||
|
color: var(--fg-gray);
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
#app-name, #app-acct {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
#app,div {
|
#app,div {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -46,6 +62,11 @@ a, a:hover, a:visited {
|
||||||
border: 0;
|
border: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
#top-sep, #mid-sep {
|
||||||
|
z-index: 14;
|
||||||
|
height: 1px;
|
||||||
|
background-image: var(--gradbar);
|
||||||
|
}
|
||||||
#gsbox {
|
#gsbox {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
<title>Mesh:Tool</title>
|
<title>Mesh:Tool</title>
|
||||||
<link rel="icon" href="/kiri/favicon.ico">
|
<link rel="icon" href="/kiri/favicon.ico">
|
||||||
<link rel="apple-touch-icon" href="/kiri/favicon-mobile.png">
|
<link rel="apple-touch-icon" href="/kiri/favicon-mobile.png">
|
||||||
<link rel="stylesheet" type="text/css" href="/kiri/index.css?{{version}}">
|
<link rel="stylesheet" type="text/css" href="/mesh/index.css?{{version}}">
|
||||||
<link href="/font/css/all.min.css" rel="stylesheet">
|
<link href="/font/css/all.min.css" rel="stylesheet">
|
||||||
<script src="/font/js/all.min.js" crossorigin="anonymous"></script>
|
<script src="/font/js/all.min.js" crossorigin="anonymous"></script>
|
||||||
<script src="/code/mesh.js?{{version}}"></script>
|
<script src="/code/mesh.js?{{version}}"></script>
|
||||||
|
|
@ -24,23 +24,18 @@
|
||||||
<div id="curtain" class="j-center a-center"><img id="gsbox"/>loading...</div>
|
<div id="curtain" class="j-center a-center"><img id="gsbox"/>loading...</div>
|
||||||
<div id="container"></div>
|
<div id="container"></div>
|
||||||
<div id="tracker"></div>
|
<div id="tracker"></div>
|
||||||
<div id="top-sep"></div>
|
|
||||||
<div id="top" class="f-row">
|
<div id="top" class="f-row">
|
||||||
|
<div id="app-name" class="f-col a-center">
|
||||||
|
<div>Mesh:Tool<div id="app-info">version</div></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div id="mid-sep"></div>
|
||||||
<div id="gdpr" class="noshow">
|
<div id="gdpr" class="noshow">
|
||||||
<p>this site uses <A href="/privacy.html" target="privacy">cookies</a> to preserve application preferences</p>
|
<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>
|
<button id="gotit" class="f-col j-center">got it</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="tool-info" class="noshow"></div>
|
<div id="tool-info" class="noshow"></div>
|
||||||
<div id="fps" class="noshow"></div>
|
<div id="fps" class="noshow"></div>
|
||||||
<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>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue