mirror of https://github.com/vladmandic/human
new look
parent
981b2b9b08
commit
4b88212f22
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 144 KiB |
|
@ -14,7 +14,6 @@
|
|||
<script src="./face3d.js" type="module"></script>
|
||||
<style>
|
||||
@font-face { font-family: 'Lato'; font-display: swap; font-style: normal; font-weight: 100; src: local('Lato'), url('../assets/lato-light.woff2') }
|
||||
@font-face { font-family: 'FA'; font-display: swap; font-style: normal; font-weight: 900; src: local('FA'), url('../assets/fa-solid-900.woff2'); }
|
||||
html { font-family: 'Lato', 'Segoe UI'; font-size: 16px; font-variant: small-caps; }
|
||||
body { margin: 0; background: black; color: white; overflow-x: hidden; }
|
||||
body::-webkit-scrollbar { display: none; }
|
||||
|
|
|
@ -22,11 +22,11 @@ function createCSS() {
|
|||
.menu { position: absolute; top: 0rem; right: 0; min-width: 180px; width: max-content; padding: 0.2rem 0.2rem 0 0.2rem; line-height: 1.8rem; z-index: 10; background: ${theme.background}; border: none }
|
||||
.button { text-shadow: none; }
|
||||
|
||||
.menu:hover { background: ${theme.hover}; }
|
||||
.menu-container { display: block; max-height: 100vh; }
|
||||
.menu-container-fadeout { max-height: 0; overflow: hidden; transition: max-height, 0.5s ease; }
|
||||
.menu-container-fadein { max-height: 100vh; overflow: hidden; transition: max-height, 0.5s ease; }
|
||||
.menu-item { display: flex; white-space: nowrap; padding: 0.2rem; cursor: default; width: 100%; }
|
||||
.menu-item:hover { background: ${theme.hover} }
|
||||
.menu-title { cursor: pointer; }
|
||||
.menu-hr { margin: 0.2rem; border: 1px solid rgba(0, 0, 0, 0.5) }
|
||||
.menu-label { padding: 0; font-weight: 800; }
|
||||
|
@ -112,7 +112,7 @@ class Menu {
|
|||
if (this.container && this.menu) {
|
||||
this.container.classList.toggle('menu-container-fadeout');
|
||||
this.container.classList.toggle('menu-container-fadein');
|
||||
this.menu.style.borderStyle = this.container.classList.contains('menu-container-fadeout') ? 'none' : 'solid';
|
||||
// this.menu.style.borderStyle = this.container.classList.contains('menu-container-fadeout') ? 'none' : 'solid';
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -153,6 +153,7 @@ class Menu {
|
|||
if (this.container && this.menu) {
|
||||
this.container.classList.toggle('menu-container-fadeout');
|
||||
this.container.classList.toggle('menu-container-fadein');
|
||||
/*
|
||||
if (this.container.classList.contains('menu-container-fadein') && evt) {
|
||||
const x = evt.x || (evt.touches && evt.touches[0] ? evt.touches[0].pageX : null);
|
||||
// const y = evt.y || (evt.touches && evt.touches[0] ? evt.touches[0].pageY : null);
|
||||
|
@ -163,10 +164,11 @@ class Menu {
|
|||
this.menu.style.left = '';
|
||||
this.menu.style.right = '0';
|
||||
}
|
||||
this.menu.style.borderStyle = 'solid';
|
||||
// this.menu.style.borderStyle = 'solid';
|
||||
} else {
|
||||
this.menu.style.borderStyle = 'none';
|
||||
// this.menu.style.borderStyle = 'none';
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -3,7 +3,7 @@
|
|||
<head>
|
||||
<title>Human</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<meta name="viewport" content="width=device-width" id="viewport">
|
||||
<meta name="keywords" content="Human">
|
||||
<meta name="application-name" content="Human">
|
||||
<meta name="description" content="Human: 3D Face Detection, Body Pose, Hand & Finger Tracking, Iris Tracking, Age & Gender Prediction, Emotion Prediction & Gesture Recognition; Author: Vladimir Mandic <https://github.com/vladmandic>">
|
||||
|
@ -11,16 +11,16 @@
|
|||
<link rel="manifest" href="./manifest.webmanifest">
|
||||
<link rel="shortcut icon" href="../favicon.ico" type="image/x-icon">
|
||||
<link rel="apple-touch-icon" href="../assets/icon.png">
|
||||
<!-- <script src="../node_modules/@tensorflow/tfjs/dist/tf.es2017.js"></script> -->
|
||||
<link rel="stylesheet" type="text/css" href="./icons.css">
|
||||
<script src="./index.js" type="module"></script>
|
||||
<style>
|
||||
@font-face { font-family: 'Lato'; font-display: swap; font-style: normal; font-weight: 100; src: local('Lato'), url('../assets/lato-light.woff2') }
|
||||
@font-face { font-family: 'FA'; font-display: swap; font-style: normal; font-weight: 900; src: local('FA'), url('../assets/fa-solid-900.woff2'); }
|
||||
html { font-family: 'Lato', 'Segoe UI'; font-size: 16px; font-variant: small-caps; }
|
||||
body { margin: 0; background: black; color: white; overflow-x: hidden }
|
||||
body::-webkit-scrollbar { display: none; }
|
||||
hr { width: 100%; }
|
||||
.play { position: absolute; width: 250px; height: 250px; z-index: 9; bottom: 15%; left: 50%; margin-left: -125px; display: none; }
|
||||
.play { position: absolute; width: 256px; height: 256px; z-index: 9; bottom: 15%; left: 50%; margin-left: -125px; display: none; filter: grayscale(1); }
|
||||
.play:hover { filter: grayscale(0); }
|
||||
.btn-background { fill:grey; cursor: pointer; opacity: 0.6; }
|
||||
.btn-background:hover { opacity: 1; }
|
||||
.btn-foreground { fill:white; cursor: pointer; opacity: 0.8; }
|
||||
|
@ -35,7 +35,7 @@
|
|||
.canvas { margin: 0 auto; }
|
||||
.bench { position: absolute; right: 0; bottom: 0; }
|
||||
.compare-image { width: 200px; position: absolute; top: 150px; left: 30px; box-shadow: 0 0 2px 2px black; background: black; }
|
||||
.loader { width: 300px; height: 300px; border: 3px solid transparent; border-radius: 50%; border-top: 4px solid #f15e41; animation: spin 4s linear infinite; position: absolute; bottom: 25%; left: 50%; margin-left: -150px; z-index: 15; }
|
||||
.loader { width: 300px; height: 300px; border: 3px solid transparent; border-radius: 50%; border-top: 4px solid #f15e41; animation: spin 4s linear infinite; position: absolute; bottom: 15%; left: 50%; margin-left: -150px; z-index: 15; }
|
||||
.loader::before, .loader::after { content: ""; position: absolute; top: 6px; bottom: 6px; left: 6px; right: 6px; border-radius: 50%; border: 4px solid transparent; }
|
||||
.loader::before { border-top-color: #bad375; animation: 3s spin linear infinite; }
|
||||
.loader::after { border-top-color: #26a9e0; animation: spin 1.5s linear infinite; }
|
||||
|
@ -60,15 +60,13 @@
|
|||
.button-model::before { content: "\f2c2"; }
|
||||
.button-start::before { content: "\f144"; }
|
||||
.button-stop::before { content: "\f28b"; }
|
||||
|
||||
.icon { width: 180px; text-align: -webkit-center; text-align: -moz-center; filter: grayscale(1); }
|
||||
.icon:hover { background: #505050; filter: grayscale(0); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="play" class="play">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zm115.7 272l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z" class="btn-background"/>
|
||||
<path d="M371.7 280l-176 101c-15.8 8.8-35.7-2.5-35.7-21V152c0-18.4 19.8-29.8 35.7-21l176 107c16.4 9.2 16.4 32.9 0 42z" class="btn-foreground"/>
|
||||
</svg>
|
||||
</div>
|
||||
<div id="play" class="play icon-play"></div>
|
||||
<div id="background">
|
||||
<div class='wave one'></div>
|
||||
<div class='wave two'></div>
|
||||
|
@ -77,11 +75,11 @@
|
|||
<div id="loader" class="loader"></div>
|
||||
<div id="status" class="status"></div>
|
||||
<div id="menubar" class="menubar">
|
||||
<span class="button button-display" id="btnDisplay">Display<br>Options</span>
|
||||
<span class="button button-image" id="btnImage">Image<br>Processing</span>
|
||||
<span class="button button-process" id="btnProcess">Model<br>Processing</span>
|
||||
<span class="button button-model" id="btnModel">Model<br>Selection</span>
|
||||
<span class="button button-start" id="btnStart">Start<br>Video</span>
|
||||
<div id="btnDisplay" class="icon"><div class="icon-binoculars"> </div>display options</div>
|
||||
<div id="btnImage" class="icon"><div class="icon-brush"></div>image processing</div>
|
||||
<div id="btnProcess" class="icon"><div class="icon-stats"></div>model processing</div>
|
||||
<div id="btnModel" class="icon"><div class="icon-games"></div>model selection</div>
|
||||
<div id="btnStart" class="icon"><div class="icon-webcam"></div><span id="btnStartText">start video</span></div>
|
||||
</div>
|
||||
<div id="media">
|
||||
<canvas id="canvas" class="canvas"></canvas>
|
||||
|
|
|
@ -196,9 +196,6 @@ async function drawResults(input) {
|
|||
async function setupCamera() {
|
||||
if (ui.busy) return null;
|
||||
ui.busy = true;
|
||||
const viewportScale = Math.min(1, Math.round(100 * window.outerWidth / 700) / 100);
|
||||
// log('demo viewport scale:', viewportScale);
|
||||
document.querySelector('meta[name=viewport]').setAttribute('content', `width=device-width, shrink-to-fit=no, initial-scale=${viewportScale}`);
|
||||
const video = document.getElementById('video');
|
||||
const canvas = document.getElementById('canvas');
|
||||
const output = document.getElementById('log');
|
||||
|
@ -411,8 +408,7 @@ async function detectVideo() {
|
|||
const canvas = document.getElementById('canvas');
|
||||
if ((video.srcObject !== null) && !video.paused) {
|
||||
document.getElementById('play').style.display = 'block';
|
||||
document.getElementById('btnStart').className = 'button button-start';
|
||||
document.getElementById('btnStart').innerHTML = 'start<br>video';
|
||||
document.getElementById('btnStartText').innerHTML = 'start video';
|
||||
status('paused');
|
||||
video.pause();
|
||||
} else {
|
||||
|
@ -421,8 +417,7 @@ async function detectVideo() {
|
|||
document.getElementById('play').style.display = 'none';
|
||||
for (const m of Object.values(menu)) m.hide();
|
||||
status('');
|
||||
document.getElementById('btnStart').className = 'button button-stop';
|
||||
document.getElementById('btnStart').innerHTML = 'pause<br>video';
|
||||
document.getElementById('btnStartText').innerHTML = 'pause video';
|
||||
await video.play();
|
||||
if (!ui.detectThread) runHumanDetect(video, canvas);
|
||||
} else {
|
||||
|
@ -446,16 +441,10 @@ async function detectSampleImages() {
|
|||
}
|
||||
|
||||
function setupMenu() {
|
||||
let x = [];
|
||||
if (window.innerWidth > 800) {
|
||||
// initial position of menu items, later it's calculated based on mouse coordinates
|
||||
x = [`${document.getElementById('btnDisplay').offsetLeft - 50}px`, `${document.getElementById('btnImage').offsetLeft - 50}px`, `${document.getElementById('btnProcess').offsetLeft - 50}px`, `${document.getElementById('btnModel').offsetLeft - 50}px`];
|
||||
} else {
|
||||
// absolute minimum spacing for menus
|
||||
x = ['0rem', '11rem', '21.1rem', '33rem'];
|
||||
}
|
||||
const x = [`${document.getElementById('btnDisplay').offsetLeft}px`, `${document.getElementById('btnImage').offsetLeft}px`, `${document.getElementById('btnProcess').offsetLeft}px`, `${document.getElementById('btnModel').offsetLeft}px`];
|
||||
const top = `${document.getElementById('menubar').offsetHeight - 3}px`;
|
||||
|
||||
menu.display = new Menu(document.body, '', { top: `${document.getElementById('menubar').offsetHeight}px`, left: x[0] });
|
||||
menu.display = new Menu(document.body, '', { top, left: x[0] });
|
||||
menu.display.addBool('perf monitor', ui, 'bench', (val) => ui.bench = val);
|
||||
menu.display.addBool('buffered output', ui, 'buffered', (val) => ui.buffered = val);
|
||||
menu.display.addBool('crop & scale', ui, 'crop', (val) => {
|
||||
|
@ -475,7 +464,7 @@ function setupMenu() {
|
|||
menu.display.addBool('draw polygons', human.draw.options, 'drawPolygons');
|
||||
menu.display.addBool('fill polygons', human.draw.options, 'fillPolygons');
|
||||
|
||||
menu.image = new Menu(document.body, '', { top: `${document.getElementById('menubar').offsetHeight}px`, left: x[1] });
|
||||
menu.image = new Menu(document.body, '', { top, left: x[1] });
|
||||
menu.image.addBool('enabled', human.config.filter, 'enabled', (val) => human.config.filter.enabled = val);
|
||||
ui.menuWidth = menu.image.addRange('image width', human.config.filter, 'width', 0, 3840, 10, (val) => human.config.filter.width = parseInt(val));
|
||||
ui.menuHeight = menu.image.addRange('image height', human.config.filter, 'height', 0, 2160, 10, (val) => human.config.filter.height = parseInt(val));
|
||||
|
@ -495,7 +484,7 @@ function setupMenu() {
|
|||
menu.image.addBool('technicolor', human.config.filter, 'technicolor', (val) => human.config.filter.technicolor = val);
|
||||
menu.image.addBool('polaroid', human.config.filter, 'polaroid', (val) => human.config.filter.polaroid = val);
|
||||
|
||||
menu.process = new Menu(document.body, '', { top: `${document.getElementById('menubar').offsetHeight}px`, left: x[2] });
|
||||
menu.process = new Menu(document.body, '', { top, left: x[2] });
|
||||
menu.process.addList('backend', ['cpu', 'webgl', 'wasm', 'humangl'], human.config.backend, (val) => human.config.backend = val);
|
||||
menu.process.addBool('async operations', human.config, 'async', (val) => human.config.async = val);
|
||||
// menu.process.addBool('enable profiler', human.config, 'profile', (val) => human.config.profile = val);
|
||||
|
@ -538,7 +527,7 @@ function setupMenu() {
|
|||
menu.process.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||
menu.process.addChart('FPS', 'FPS');
|
||||
|
||||
menu.models = new Menu(document.body, '', { top: `${document.getElementById('menubar').offsetHeight}px`, left: x[3] });
|
||||
menu.models = new Menu(document.body, '', { top, left: x[3] });
|
||||
menu.models.addBool('face detect', human.config.face, 'enabled', (val) => human.config.face.enabled = val);
|
||||
menu.models.addBool('face mesh', human.config.face.mesh, 'enabled', (val) => human.config.face.mesh.enabled = val);
|
||||
menu.models.addBool('face iris', human.config.face.iris, 'enabled', (val) => human.config.face.iris.enabled = val);
|
||||
|
@ -567,6 +556,21 @@ function setupMenu() {
|
|||
document.getElementById('play').addEventListener('click', () => detectVideo());
|
||||
}
|
||||
|
||||
async function resize() {
|
||||
const x = [`${document.getElementById('btnDisplay').offsetLeft}px`, `${document.getElementById('btnImage').offsetLeft}px`, `${document.getElementById('btnProcess').offsetLeft}px`, `${document.getElementById('btnModel').offsetLeft}px`];
|
||||
menu.display.menu.style.left = x[0];
|
||||
menu.image.menu.style.left = x[1];
|
||||
menu.process.menu.style.left = x[2];
|
||||
menu.models.menu.style.left = x[3];
|
||||
const viewportScale = Math.min(1, Math.round(100 * window.innerWidth / 960) / 100);
|
||||
const viewport = document.querySelector('meta[name=viewport]');
|
||||
viewport.setAttribute('content', `width=device-width, shrink-to-fit=yes, minimum-scale=0.2, maximum-scale=2.0, user-scalable=yes, initial-scale=${viewportScale}`);
|
||||
// console.log('view', viewportScale, window.innerWidth, viewport);
|
||||
// document.body.style.MozTransform = `scale(${viewportScale})`;
|
||||
// document.body.style.zoom = `scale(${viewportScale})`;
|
||||
setupCamera();
|
||||
}
|
||||
|
||||
async function drawWarmup(res) {
|
||||
const canvas = document.getElementById('canvas');
|
||||
canvas.width = res.canvas.width;
|
||||
|
@ -607,7 +611,8 @@ async function main() {
|
|||
}
|
||||
|
||||
// setup main menu
|
||||
setupMenu();
|
||||
await setupMenu();
|
||||
await resize();
|
||||
document.getElementById('log').innerText = `Human: version ${human.version}`;
|
||||
|
||||
// preload models
|
||||
|
@ -636,4 +641,4 @@ async function main() {
|
|||
}
|
||||
|
||||
window.onload = main;
|
||||
window.onresize = setupCamera;
|
||||
window.onresize = resize;
|
||||
|
|
2
wiki
2
wiki
|
@ -1 +1 @@
|
|||
Subproject commit 458f02833206e3a6ee1c76652d9e8048530f0708
|
||||
Subproject commit ddf8fb116b159dc3dabea4cb858b608fa5914355
|
Loading…
Reference in New Issue