mirror of https://github.com/vladmandic/human
ui redesign
parent
e76091ed5b
commit
5a87c48bfe
|
@ -21,12 +21,17 @@
|
||||||
],
|
],
|
||||||
"ignorePatterns": [ "dist", "assets", "media", "models", "node_modules" ],
|
"ignorePatterns": [ "dist", "assets", "media", "models", "node_modules" ],
|
||||||
"rules": {
|
"rules": {
|
||||||
"max-len": [1, 275, 3],
|
|
||||||
"camelcase": "off",
|
"camelcase": "off",
|
||||||
"guard-for-in": "off",
|
"dot-notation": "off",
|
||||||
"prefer-template":"off",
|
|
||||||
"import/extensions": "off",
|
|
||||||
"func-names": "off",
|
"func-names": "off",
|
||||||
|
"guard-for-in": "off",
|
||||||
|
"import/extensions": "off",
|
||||||
|
"import/no-absolute-path": "off",
|
||||||
|
"import/no-extraneous-dependencies": "off",
|
||||||
|
"import/prefer-default-export": "off",
|
||||||
|
"max-len": [1, 275, 3],
|
||||||
|
"newline-per-chained-call": "off",
|
||||||
|
"no-async-promise-executor": "off",
|
||||||
"no-await-in-loop": "off",
|
"no-await-in-loop": "off",
|
||||||
"no-bitwise": "off",
|
"no-bitwise": "off",
|
||||||
"no-case-declarations":"off",
|
"no-case-declarations":"off",
|
||||||
|
@ -35,25 +40,21 @@
|
||||||
"no-mixed-operators": "off",
|
"no-mixed-operators": "off",
|
||||||
"no-param-reassign":"off",
|
"no-param-reassign":"off",
|
||||||
"no-plusplus": "off",
|
"no-plusplus": "off",
|
||||||
"dot-notation": "off",
|
"no-regex-spaces": "off",
|
||||||
"no-restricted-globals": "off",
|
"no-restricted-globals": "off",
|
||||||
"no-restricted-syntax": "off",
|
"no-restricted-syntax": "off",
|
||||||
"no-underscore-dangle": "off",
|
|
||||||
"no-return-assign": "off",
|
"no-return-assign": "off",
|
||||||
"newline-per-chained-call": "off",
|
"no-underscore-dangle": "off",
|
||||||
|
"node/no-unpublished-import": "off",
|
||||||
|
"node/no-unpublished-require": "off",
|
||||||
"node/no-unsupported-features/es-syntax": "off",
|
"node/no-unsupported-features/es-syntax": "off",
|
||||||
"node/shebang": "off",
|
"node/shebang": "off",
|
||||||
"object-curly-newline": "off",
|
"object-curly-newline": "off",
|
||||||
"prefer-destructuring": "off",
|
"prefer-destructuring": "off",
|
||||||
|
"prefer-template":"off",
|
||||||
"promise/always-return": "off",
|
"promise/always-return": "off",
|
||||||
"promise/catch-or-return": "off",
|
"promise/catch-or-return": "off",
|
||||||
"promise/no-nesting": "off",
|
"promise/no-nesting": "off",
|
||||||
"no-async-promise-executor": "off",
|
|
||||||
"import/no-absolute-path": "off",
|
|
||||||
"import/no-extraneous-dependencies": "off",
|
|
||||||
"node/no-unpublished-import": "off",
|
|
||||||
"node/no-unpublished-require": "off",
|
|
||||||
"no-regex-spaces": "off",
|
|
||||||
"radix": "off"
|
"radix": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
Binary file not shown.
252
demo/browser.js
252
demo/browser.js
|
@ -1,7 +1,7 @@
|
||||||
import Human from '../dist/human.esm.js';
|
import Human from '../dist/human.esm.js';
|
||||||
import draw from './draw.js';
|
import draw from './draw.js';
|
||||||
import Menu from './menu.js';
|
import Menu from './menu.js';
|
||||||
import GLBench from '../assets/gl-bench.js';
|
import GLBench from './gl-bench.js';
|
||||||
|
|
||||||
const userConfig = {}; // add any user configuration overrides
|
const userConfig = {}; // add any user configuration overrides
|
||||||
|
|
||||||
|
@ -11,10 +11,9 @@ const human = new Human(userConfig);
|
||||||
const ui = {
|
const ui = {
|
||||||
baseColor: 'rgba(173, 216, 230, 0.3)', // 'lightblue' with light alpha channel
|
baseColor: 'rgba(173, 216, 230, 0.3)', // 'lightblue' with light alpha channel
|
||||||
baseBackground: 'rgba(50, 50, 50, 1)', // 'grey'
|
baseBackground: 'rgba(50, 50, 50, 1)', // 'grey'
|
||||||
baseLabel: 'rgba(173, 216, 230, 0.9)', // 'lightblue' with dark alpha channel
|
baseLabel: 'rgba(173, 216, 230, 1)', // 'lightblue' with dark alpha channel
|
||||||
baseFontProto: 'small-caps {size} "Segoe UI"',
|
baseFontProto: 'small-caps {size} "Segoe UI"',
|
||||||
baseLineWidth: 12,
|
baseLineWidth: 12,
|
||||||
baseLineHeightProto: 2,
|
|
||||||
crop: true,
|
crop: true,
|
||||||
columns: 2,
|
columns: 2,
|
||||||
busy: false,
|
busy: false,
|
||||||
|
@ -38,7 +37,6 @@ const ui = {
|
||||||
detectFPS: [],
|
detectFPS: [],
|
||||||
drawFPS: [],
|
drawFPS: [],
|
||||||
buffered: false,
|
buffered: false,
|
||||||
bufferedFPSTarget: 0,
|
|
||||||
drawThread: null,
|
drawThread: null,
|
||||||
detectThread: null,
|
detectThread: null,
|
||||||
framesDraw: 0,
|
framesDraw: 0,
|
||||||
|
@ -47,11 +45,9 @@ const ui = {
|
||||||
};
|
};
|
||||||
|
|
||||||
// global variables
|
// global variables
|
||||||
let menu;
|
const menu = {};
|
||||||
let menuFX;
|
|
||||||
let worker;
|
let worker;
|
||||||
let bench;
|
let bench;
|
||||||
let sample;
|
|
||||||
let lastDetectedResult = {};
|
let lastDetectedResult = {};
|
||||||
|
|
||||||
// helper function: translates json to human readable string
|
// helper function: translates json to human readable string
|
||||||
|
@ -78,14 +74,16 @@ const status = (msg) => {
|
||||||
document.getElementById('status').innerText = msg;
|
document.getElementById('status').innerText = msg;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function calcSimmilariry(faces) {
|
let original;
|
||||||
if (!faces || !faces[0] || (faces[0].embedding?.length !== 192)) return;
|
async function calcSimmilariry(result) {
|
||||||
const current = faces[0].embedding;
|
document.getElementById('compare-container').style.display = human.config.face.embedding.enabled ? 'block' : 'none';
|
||||||
const original = (sample && sample.face && sample.face[0] && sample.face[0].embedding) ? sample.face[0].embedding : null;
|
if ((result?.face?.length > 0) && (result?.face[0].embedding?.length !== 192)) return;
|
||||||
if (original && original.length === 192) {
|
if (!original) {
|
||||||
const simmilarity = human.simmilarity(current, original);
|
original = result;
|
||||||
document.getElementById('simmilarity').innerText = `simmilarity: ${Math.trunc(1000 * simmilarity) / 10}%`;
|
document.getElementById('compare-canvas').getContext('2d').drawImage(original.canvas, 0, 0, 200, 200);
|
||||||
}
|
}
|
||||||
|
const simmilarity = human.simmilarity(original.face[0].embedding, result.face[0].embedding);
|
||||||
|
document.getElementById('simmilarity').innerText = `simmilarity: ${Math.trunc(1000 * simmilarity) / 10}%`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draws processed results and starts processing of a next frame
|
// draws processed results and starts processing of a next frame
|
||||||
|
@ -103,7 +101,7 @@ async function drawResults(input) {
|
||||||
// console.log(result.performance);
|
// console.log(result.performance);
|
||||||
|
|
||||||
// draw fps chart
|
// draw fps chart
|
||||||
await menu.updateChart('FPS', ui.detectFPS);
|
await menu.process.updateChart('FPS', ui.detectFPS);
|
||||||
|
|
||||||
// get updated canvas
|
// get updated canvas
|
||||||
if (ui.buffered || !result.canvas) result.canvas = await human.image(input, userConfig);
|
if (ui.buffered || !result.canvas) result.canvas = await human.image(input, userConfig);
|
||||||
|
@ -125,7 +123,7 @@ async function drawResults(input) {
|
||||||
await draw.body(result.body, canvas, ui);
|
await draw.body(result.body, canvas, ui);
|
||||||
await draw.hand(result.hand, canvas, ui);
|
await draw.hand(result.hand, canvas, ui);
|
||||||
await draw.gesture(result.gesture, canvas, ui);
|
await draw.gesture(result.gesture, canvas, ui);
|
||||||
await calcSimmilariry(result.face);
|
await calcSimmilariry(result);
|
||||||
|
|
||||||
// update log
|
// update log
|
||||||
const engine = human.tf.engine();
|
const engine = human.tf.engine();
|
||||||
|
@ -145,14 +143,11 @@ async function drawResults(input) {
|
||||||
ui.framesDraw++;
|
ui.framesDraw++;
|
||||||
ui.lastFrame = performance.now();
|
ui.lastFrame = performance.now();
|
||||||
// if buffered, immediate loop but limit frame rate although it's going to run slower as JS is singlethreaded
|
// if buffered, immediate loop but limit frame rate although it's going to run slower as JS is singlethreaded
|
||||||
if ((ui.bufferedFPSTarget === 0) && ui.buffered) {
|
if (ui.buffered) {
|
||||||
ui.drawThread = requestAnimationFrame(() => drawResults(input, canvas));
|
ui.drawThread = requestAnimationFrame(() => drawResults(input, canvas));
|
||||||
} else if ((ui.bufferedFPSTarget === 0) && ui.buffered && !ui.drawThread) {
|
|
||||||
log('starting buffered refresh');
|
|
||||||
if (ui.bufferedFPSTarget > 0) ui.drawThread = setInterval(() => drawResults(input, canvas), 1000 / ui.bufferedFPSTarget);
|
|
||||||
} else if (!ui.buffered && ui.drawThread) {
|
} else if (!ui.buffered && ui.drawThread) {
|
||||||
log('stopping buffered refresh');
|
log('stopping buffered refresh');
|
||||||
clearTimeout(ui.drawThread);
|
cancelAnimationFrame(ui.drawThread);
|
||||||
ui.drawThread = null;
|
ui.drawThread = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -181,7 +176,7 @@ async function setupCamera() {
|
||||||
video: { facingMode: ui.facing ? 'user' : 'environment', resizeMode: ui.crop ? 'crop-and-scale' : 'none' },
|
video: { facingMode: ui.facing ? 'user' : 'environment', resizeMode: ui.crop ? 'crop-and-scale' : 'none' },
|
||||||
};
|
};
|
||||||
if (window.innerWidth > window.innerHeight) constraints.video.width = { ideal: window.innerWidth };
|
if (window.innerWidth > window.innerHeight) constraints.video.width = { ideal: window.innerWidth };
|
||||||
else constraints.video.height = { ideal: window.innerHeight };
|
else constraints.video.height = { ideal: (window.innerHeight - document.getElementById('menubar').offsetHeight) };
|
||||||
try {
|
try {
|
||||||
stream = await navigator.mediaDevices.getUserMedia(constraints);
|
stream = await navigator.mediaDevices.getUserMedia(constraints);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
@ -209,8 +204,9 @@ async function setupCamera() {
|
||||||
ui.menuWidth.input.setAttribute('value', video.width);
|
ui.menuWidth.input.setAttribute('value', video.width);
|
||||||
ui.menuHeight.input.setAttribute('value', video.height);
|
ui.menuHeight.input.setAttribute('value', video.height);
|
||||||
// silly font resizing for paint-on-canvas since viewport can be zoomed
|
// silly font resizing for paint-on-canvas since viewport can be zoomed
|
||||||
const size = 14 + (6 * canvas.width / window.innerWidth);
|
const size = Math.trunc(window.devicePixelRatio * (8 + (4 * canvas.width / window.innerWidth)));
|
||||||
ui.baseFont = ui.baseFontProto.replace(/{size}/, `${size}px`);
|
ui.baseFont = ui.baseFontProto.replace(/{size}/, `${size}px`);
|
||||||
|
ui.baseLineHeight = size + 4;
|
||||||
if (live) video.play();
|
if (live) video.play();
|
||||||
// eslint-disable-next-line no-use-before-define
|
// eslint-disable-next-line no-use-before-define
|
||||||
if (live && !ui.detectThread) runHumanDetect(video, canvas);
|
if (live && !ui.detectThread) runHumanDetect(video, canvas);
|
||||||
|
@ -223,6 +219,20 @@ async function setupCamera() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function initPerfMonitor() {
|
||||||
|
if (!bench) {
|
||||||
|
const gl = null;
|
||||||
|
// cosnt gl = human.tf.engine().backend.gpgpu.gl;
|
||||||
|
// if (!gl) log('bench cannot get tensorflow webgl context');
|
||||||
|
bench = new GLBench(gl, {
|
||||||
|
trackGPU: false, // this is really slow
|
||||||
|
chartHz: 20,
|
||||||
|
chartLen: 20,
|
||||||
|
});
|
||||||
|
bench.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// wrapper for worker.postmessage that creates worker if one does not exist
|
// wrapper for worker.postmessage that creates worker if one does not exist
|
||||||
function webWorker(input, image, canvas, timestamp) {
|
function webWorker(input, image, canvas, timestamp) {
|
||||||
if (!worker) {
|
if (!worker) {
|
||||||
|
@ -233,8 +243,11 @@ function webWorker(input, image, canvas, timestamp) {
|
||||||
worker.addEventListener('message', (msg) => {
|
worker.addEventListener('message', (msg) => {
|
||||||
if (msg.data.result.performance && msg.data.result.performance.total) ui.detectFPS.push(1000 / msg.data.result.performance.total);
|
if (msg.data.result.performance && msg.data.result.performance.total) ui.detectFPS.push(1000 / msg.data.result.performance.total);
|
||||||
if (ui.detectFPS.length > ui.maxFPSframes) ui.detectFPS.shift();
|
if (ui.detectFPS.length > ui.maxFPSframes) ui.detectFPS.shift();
|
||||||
if (ui.bench) bench.end();
|
if (ui.bench) {
|
||||||
if (ui.bench) bench.nextFrame(timestamp);
|
if (!bench) initPerfMonitor();
|
||||||
|
bench.nextFrame(timestamp);
|
||||||
|
}
|
||||||
|
if (document.getElementById('gl-bench')) document.getElementById('gl-bench').style.display = ui.bench ? 'block' : 'none';
|
||||||
lastDetectedResult = msg.data.result;
|
lastDetectedResult = msg.data.result;
|
||||||
ui.framesDetect++;
|
ui.framesDetect++;
|
||||||
if (!ui.drawThread) drawResults(input);
|
if (!ui.drawThread) drawResults(input);
|
||||||
|
@ -243,7 +256,6 @@ function webWorker(input, image, canvas, timestamp) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// pass image data as arraybuffer to worker by reference to avoid copy
|
// pass image data as arraybuffer to worker by reference to avoid copy
|
||||||
if (ui.bench) bench.begin();
|
|
||||||
worker.postMessage({ image: image.data.buffer, width: canvas.width, height: canvas.height, userConfig }, [image.data.buffer]);
|
worker.postMessage({ image: image.data.buffer, width: canvas.width, height: canvas.height, userConfig }, [image.data.buffer]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +265,7 @@ function runHumanDetect(input, canvas, timestamp) {
|
||||||
const live = input.srcObject && (input.srcObject.getVideoTracks()[0].readyState === 'live') && (input.readyState > 2) && (!input.paused);
|
const live = input.srcObject && (input.srcObject.getVideoTracks()[0].readyState === 'live') && (input.readyState > 2) && (!input.paused);
|
||||||
if (!live && input.srcObject) {
|
if (!live && input.srcObject) {
|
||||||
// stop ui refresh
|
// stop ui refresh
|
||||||
if (ui.drawThread) clearTimeout(ui.drawThread);
|
if (ui.drawThread) cancelAnimationFrame(ui.drawThread);
|
||||||
if (ui.detectThread) cancelAnimationFrame(ui.detectThread);
|
if (ui.detectThread) cancelAnimationFrame(ui.detectThread);
|
||||||
ui.drawThread = null;
|
ui.drawThread = null;
|
||||||
ui.detectThread = null;
|
ui.detectThread = null;
|
||||||
|
@ -272,19 +284,20 @@ function runHumanDetect(input, canvas, timestamp) {
|
||||||
const offscreen = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(canvas.width, canvas.height) : document.createElement('canvas');
|
const offscreen = (typeof OffscreenCanvas !== 'undefined') ? new OffscreenCanvas(canvas.width, canvas.height) : document.createElement('canvas');
|
||||||
offscreen.width = canvas.width;
|
offscreen.width = canvas.width;
|
||||||
offscreen.height = canvas.height;
|
offscreen.height = canvas.height;
|
||||||
|
|
||||||
const ctx = offscreen.getContext('2d');
|
const ctx = offscreen.getContext('2d');
|
||||||
ctx.drawImage(input, 0, 0, input.width, input.height, 0, 0, canvas.width, canvas.height);
|
ctx.drawImage(input, 0, 0, input.width, input.height, 0, 0, canvas.width, canvas.height);
|
||||||
const data = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
const data = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
// perform detection in worker
|
// perform detection in worker
|
||||||
webWorker(input, data, canvas, userConfig, timestamp);
|
webWorker(input, data, canvas, userConfig, timestamp);
|
||||||
} else {
|
} else {
|
||||||
if (ui.bench) bench.begin();
|
|
||||||
human.detect(input, userConfig).then((result) => {
|
human.detect(input, userConfig).then((result) => {
|
||||||
if (result.performance && result.performance.total) ui.detectFPS.push(1000 / result.performance.total);
|
if (result.performance && result.performance.total) ui.detectFPS.push(1000 / result.performance.total);
|
||||||
if (ui.detectFPS.length > ui.maxFPSframes) ui.detectFPS.shift();
|
if (ui.detectFPS.length > ui.maxFPSframes) ui.detectFPS.shift();
|
||||||
if (ui.bench) bench.end();
|
if (ui.bench) {
|
||||||
if (ui.bench) bench.nextFrame(timestamp);
|
if (!bench) initPerfMonitor();
|
||||||
|
bench.nextFrame(timestamp);
|
||||||
|
}
|
||||||
|
if (document.getElementById('gl-bench')) document.getElementById('gl-bench').style.display = ui.bench ? 'block' : 'none';
|
||||||
if (result.error) log(result.error);
|
if (result.error) log(result.error);
|
||||||
else {
|
else {
|
||||||
lastDetectedResult = result;
|
lastDetectedResult = result;
|
||||||
|
@ -331,15 +344,19 @@ async function detectVideo() {
|
||||||
document.getElementById('canvas').style.display = 'block';
|
document.getElementById('canvas').style.display = 'block';
|
||||||
const video = document.getElementById('video');
|
const video = document.getElementById('video');
|
||||||
const canvas = document.getElementById('canvas');
|
const canvas = document.getElementById('canvas');
|
||||||
ui.baseLineHeight = ui.baseLineHeightProto;
|
|
||||||
if ((video.srcObject !== null) && !video.paused) {
|
if ((video.srcObject !== null) && !video.paused) {
|
||||||
document.getElementById('play').style.display = 'block';
|
document.getElementById('play').style.display = 'block';
|
||||||
|
document.getElementById('btnStart').className = 'button button-start';
|
||||||
|
document.getElementById('btnStart').innerHTML = 'start<br>video';
|
||||||
status('paused');
|
status('paused');
|
||||||
video.pause();
|
video.pause();
|
||||||
} else {
|
} else {
|
||||||
await setupCamera();
|
await setupCamera();
|
||||||
document.getElementById('play').style.display = 'none';
|
document.getElementById('play').style.display = 'none';
|
||||||
|
for (const m of Object.values(menu)) m.hide();
|
||||||
status('');
|
status('');
|
||||||
|
document.getElementById('btnStart').className = 'button button-stop';
|
||||||
|
document.getElementById('btnStart').innerHTML = 'pause<br>video';
|
||||||
video.play();
|
video.play();
|
||||||
}
|
}
|
||||||
if (!ui.detectThread) runHumanDetect(video, canvas);
|
if (!ui.detectThread) runHumanDetect(video, canvas);
|
||||||
|
@ -349,9 +366,9 @@ async function detectVideo() {
|
||||||
async function detectSampleImages() {
|
async function detectSampleImages() {
|
||||||
document.getElementById('play').style.display = 'none';
|
document.getElementById('play').style.display = 'none';
|
||||||
userConfig.videoOptimized = false;
|
userConfig.videoOptimized = false;
|
||||||
const size = 12 + Math.trunc(12 * ui.columns * window.innerWidth / document.body.clientWidth);
|
const size = Math.trunc(window.devicePixelRatio * (8 + (4 * ui.columns)));
|
||||||
ui.baseFont = ui.baseFontProto.replace(/{size}/, `${size}px`);
|
ui.baseFont = ui.baseFontProto.replace(/{size}/, `${size}px`);
|
||||||
ui.baseLineHeight = ui.baseLineHeightProto * ui.columns;
|
ui.baseLineHeight = size + 2;
|
||||||
document.getElementById('canvas').style.display = 'none';
|
document.getElementById('canvas').style.display = 'none';
|
||||||
document.getElementById('samples-container').style.display = 'block';
|
document.getElementById('samples-container').style.display = 'block';
|
||||||
log('Running detection of sample images');
|
log('Running detection of sample images');
|
||||||
|
@ -362,121 +379,116 @@ async function detectSampleImages() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setupMenu() {
|
function setupMenu() {
|
||||||
document.getElementById('compare-container').style.display = human.config.face.embedding.enabled ? 'block' : 'none';
|
let x = [];
|
||||||
menu = new Menu(document.body, '', { top: '1rem', right: '1rem' });
|
if (window.innerWidth > 800) {
|
||||||
const btn = menu.addButton('start video', 'pause video', () => detectVideo());
|
// initial position of menu items, later it's calculated based on mouse coordinates
|
||||||
menu.addButton('process images', 'process images', () => detectSampleImages());
|
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`];
|
||||||
document.getElementById('play').addEventListener('click', () => btn.click());
|
} else {
|
||||||
|
// absolute minimum spacing for menus
|
||||||
|
x = ['0rem', '11rem', '21.1rem', '33rem'];
|
||||||
|
}
|
||||||
|
|
||||||
menu.addHTML('<hr style="min-width: 200px; border-style: inset; border-color: dimgray">');
|
menu.display = new Menu(document.body, '', { top: `${document.getElementById('menubar').offsetHeight}px`, left: x[0] });
|
||||||
menu.addList('backend', ['cpu', 'webgl', 'wasm'], human.config.backend, (val) => human.config.backend = val);
|
menu.display.addBool('perf monitor', ui, 'bench', (val) => ui.bench = val);
|
||||||
menu.addBool('async operations', human.config, 'async', (val) => human.config.async = val);
|
menu.display.addBool('buffered output', ui, 'buffered', (val) => ui.buffered = val);
|
||||||
// menu.addBool('enable profiler', human.config, 'profile', (val) => human.config.profile = val);
|
menu.display.addBool('crop & scale', ui, 'crop', () => setupCamera());
|
||||||
// menu.addBool('memory shield', human.config, 'deallocate', (val) => human.config.deallocate = val);
|
menu.display.addBool('camera facing', ui, 'facing', () => setupCamera());
|
||||||
menu.addBool('use web worker', ui, 'useWorker');
|
menu.display.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||||
menu.addHTML('<hr style="min-width: 200px; border-style: inset; border-color: dimgray">');
|
menu.display.addBool('use 3D depth', ui, 'useDepth');
|
||||||
menu.addLabel('enabled models');
|
menu.display.addBool('draw boxes', ui, 'drawBoxes');
|
||||||
menu.addBool('face detect', human.config.face, 'enabled');
|
menu.display.addBool('draw polygons', ui, 'drawPolygons');
|
||||||
menu.addBool('face mesh', human.config.face.mesh, 'enabled');
|
menu.display.addBool('Fill Polygons', ui, 'fillPolygons');
|
||||||
menu.addBool('face iris', human.config.face.iris, 'enabled');
|
menu.display.addBool('draw points', ui, 'drawPoints');
|
||||||
menu.addBool('face age', human.config.face.age, 'enabled');
|
|
||||||
menu.addBool('face gender', human.config.face.gender, 'enabled');
|
|
||||||
menu.addBool('face emotion', human.config.face.emotion, 'enabled');
|
|
||||||
// menu.addBool('face compare', human.config.face.embedding, 'enabled', (val) => {
|
|
||||||
// human.config.face.embedding.enabled = val;
|
|
||||||
// document.getElementById('compare-container').style.display = human.config.face.embedding.enabled ? 'block' : 'none';
|
|
||||||
// });
|
|
||||||
menu.addBool('body pose', human.config.body, 'enabled');
|
|
||||||
menu.addBool('hand pose', human.config.hand, 'enabled');
|
|
||||||
menu.addBool('gesture analysis', human.config.gesture, 'enabled');
|
|
||||||
|
|
||||||
menu.addHTML('<hr style="min-width: 200px; border-style: inset; border-color: dimgray">');
|
menu.image = new Menu(document.body, '', { top: `${document.getElementById('menubar').offsetHeight}px`, left: x[1] });
|
||||||
menu.addLabel('model parameters');
|
menu.image.addBool('enabled', human.config.filter, 'enabled');
|
||||||
menu.addRange('max objects', human.config.face.detector, 'maxFaces', 1, 50, 1, (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));
|
||||||
|
menu.image.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||||
|
menu.image.addRange('brightness', human.config.filter, 'brightness', -1.0, 1.0, 0.05, (val) => human.config.filter.brightness = parseFloat(val));
|
||||||
|
menu.image.addRange('contrast', human.config.filter, 'contrast', -1.0, 1.0, 0.05, (val) => human.config.filter.contrast = parseFloat(val));
|
||||||
|
menu.image.addRange('sharpness', human.config.filter, 'sharpness', 0, 1.0, 0.05, (val) => human.config.filter.sharpness = parseFloat(val));
|
||||||
|
menu.image.addRange('blur', human.config.filter, 'blur', 0, 20, 1, (val) => human.config.filter.blur = parseInt(val));
|
||||||
|
menu.image.addRange('saturation', human.config.filter, 'saturation', -1.0, 1.0, 0.05, (val) => human.config.filter.saturation = parseFloat(val));
|
||||||
|
menu.image.addRange('hue', human.config.filter, 'hue', 0, 360, 5, (val) => human.config.filter.hue = parseInt(val));
|
||||||
|
menu.image.addRange('pixelate', human.config.filter, 'pixelate', 0, 32, 1, (val) => human.config.filter.pixelate = parseInt(val));
|
||||||
|
menu.image.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||||
|
menu.image.addBool('negative', human.config.filter, 'negative');
|
||||||
|
menu.image.addBool('sepia', human.config.filter, 'sepia');
|
||||||
|
menu.image.addBool('vintage', human.config.filter, 'vintage');
|
||||||
|
menu.image.addBool('kodachrome', human.config.filter, 'kodachrome');
|
||||||
|
menu.image.addBool('technicolor', human.config.filter, 'technicolor');
|
||||||
|
menu.image.addBool('polaroid', human.config.filter, 'polaroid');
|
||||||
|
|
||||||
|
menu.process = new Menu(document.body, '', { top: `${document.getElementById('menubar').offsetHeight}px`, left: x[2] });
|
||||||
|
menu.process.addList('backend', ['cpu', 'webgl', 'wasm'], 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);
|
||||||
|
menu.process.addBool('memory shield', human.config, 'deallocate', (val) => human.config.deallocate = val);
|
||||||
|
menu.process.addBool('use web worker', ui, 'useWorker');
|
||||||
|
menu.process.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||||
|
menu.process.addLabel('model parameters');
|
||||||
|
menu.process.addRange('max objects', human.config.face.detector, 'maxFaces', 1, 50, 1, (val) => {
|
||||||
human.config.face.detector.maxFaces = parseInt(val);
|
human.config.face.detector.maxFaces = parseInt(val);
|
||||||
human.config.body.maxDetections = parseInt(val);
|
human.config.body.maxDetections = parseInt(val);
|
||||||
human.config.hand.maxHands = parseInt(val);
|
human.config.hand.maxHands = parseInt(val);
|
||||||
});
|
});
|
||||||
menu.addRange('skip frames', human.config.face.detector, 'skipFrames', 0, 50, 1, (val) => {
|
menu.process.addRange('skip frames', human.config.face.detector, 'skipFrames', 0, 50, 1, (val) => {
|
||||||
human.config.face.detector.skipFrames = parseInt(val);
|
human.config.face.detector.skipFrames = parseInt(val);
|
||||||
human.config.face.emotion.skipFrames = parseInt(val);
|
human.config.face.emotion.skipFrames = parseInt(val);
|
||||||
human.config.face.age.skipFrames = parseInt(val);
|
human.config.face.age.skipFrames = parseInt(val);
|
||||||
human.config.hand.skipFrames = parseInt(val);
|
human.config.hand.skipFrames = parseInt(val);
|
||||||
});
|
});
|
||||||
menu.addRange('min confidence', human.config.face.detector, 'minConfidence', 0.0, 1.0, 0.05, (val) => {
|
menu.process.addRange('min confidence', human.config.face.detector, 'minConfidence', 0.0, 1.0, 0.05, (val) => {
|
||||||
human.config.face.detector.minConfidence = parseFloat(val);
|
human.config.face.detector.minConfidence = parseFloat(val);
|
||||||
human.config.face.gender.minConfidence = parseFloat(val);
|
human.config.face.gender.minConfidence = parseFloat(val);
|
||||||
human.config.face.emotion.minConfidence = parseFloat(val);
|
human.config.face.emotion.minConfidence = parseFloat(val);
|
||||||
human.config.hand.minConfidence = parseFloat(val);
|
human.config.hand.minConfidence = parseFloat(val);
|
||||||
});
|
});
|
||||||
menu.addRange('score threshold', human.config.face.detector, 'scoreThreshold', 0.1, 1.0, 0.05, (val) => {
|
menu.process.addRange('score threshold', human.config.face.detector, 'scoreThreshold', 0.1, 1.0, 0.05, (val) => {
|
||||||
human.config.face.detector.scoreThreshold = parseFloat(val);
|
human.config.face.detector.scoreThreshold = parseFloat(val);
|
||||||
human.config.hand.scoreThreshold = parseFloat(val);
|
human.config.hand.scoreThreshold = parseFloat(val);
|
||||||
human.config.body.scoreThreshold = parseFloat(val);
|
human.config.body.scoreThreshold = parseFloat(val);
|
||||||
});
|
});
|
||||||
menu.addRange('overlap', human.config.face.detector, 'iouThreshold', 0.1, 1.0, 0.05, (val) => {
|
menu.process.addRange('overlap', human.config.face.detector, 'iouThreshold', 0.1, 1.0, 0.05, (val) => {
|
||||||
human.config.face.detector.iouThreshold = parseFloat(val);
|
human.config.face.detector.iouThreshold = parseFloat(val);
|
||||||
human.config.hand.iouThreshold = parseFloat(val);
|
human.config.hand.iouThreshold = parseFloat(val);
|
||||||
});
|
});
|
||||||
|
menu.process.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||||
|
menu.process.addButton('process sample images', 'process images', () => detectSampleImages());
|
||||||
|
menu.process.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||||
|
menu.process.addChart('FPS', 'FPS');
|
||||||
|
|
||||||
menu.addHTML('<hr style="min-width: 200px; border-style: inset; border-color: dimgray">');
|
menu.models = new Menu(document.body, '', { top: `${document.getElementById('menubar').offsetHeight}px`, left: x[3] });
|
||||||
menu.addChart('FPS', 'FPS');
|
menu.models.addBool('face detect', human.config.face, 'enabled');
|
||||||
|
menu.models.addBool('face mesh', human.config.face.mesh, 'enabled');
|
||||||
|
menu.models.addBool('face iris', human.config.face.iris, 'enabled');
|
||||||
|
menu.models.addBool('face age', human.config.face.age, 'enabled');
|
||||||
|
menu.models.addBool('face gender', human.config.face.gender, 'enabled');
|
||||||
|
menu.models.addBool('face emotion', human.config.face.emotion, 'enabled');
|
||||||
|
menu.models.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||||
|
menu.models.addBool('body pose', human.config.body, 'enabled');
|
||||||
|
menu.models.addBool('hand pose', human.config.hand, 'enabled');
|
||||||
|
menu.models.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||||
|
menu.models.addBool('gestures', human.config.gesture, 'enabled');
|
||||||
|
menu.models.addHTML('<hr style="border-style: inset; border-color: dimgray">');
|
||||||
|
menu.models.addBool('face compare', human.config.face.embedding, 'enabled', (val) => {
|
||||||
|
original = null;
|
||||||
|
human.config.face.embedding.enabled = val;
|
||||||
|
});
|
||||||
|
|
||||||
menuFX = new Menu(document.body, '', { top: '1rem', right: '18rem' });
|
document.getElementById('btnDisplay').addEventListener('click', (evt) => menu.display.toggle(evt));
|
||||||
menuFX.addLabel('ui options');
|
document.getElementById('btnImage').addEventListener('click', (evt) => menu.image.toggle(evt));
|
||||||
menuFX.addBool('buffered output', ui, 'buffered', (val) => ui.buffered = val);
|
document.getElementById('btnProcess').addEventListener('click', (evt) => menu.process.toggle(evt));
|
||||||
menuFX.addBool('crop & scale', ui, 'crop', () => setupCamera());
|
document.getElementById('btnModel').addEventListener('click', (evt) => menu.models.toggle(evt));
|
||||||
menuFX.addBool('camera front/back', ui, 'facing', () => setupCamera());
|
document.getElementById('btnStart').addEventListener('click', () => detectVideo());
|
||||||
menuFX.addBool('use 3D depth', ui, 'useDepth');
|
document.getElementById('play').addEventListener('click', () => detectVideo());
|
||||||
menuFX.addBool('draw boxes', ui, 'drawBoxes');
|
|
||||||
menuFX.addBool('draw polygons', ui, 'drawPolygons');
|
|
||||||
menuFX.addBool('Fill Polygons', ui, 'fillPolygons');
|
|
||||||
menuFX.addBool('draw points', ui, 'drawPoints');
|
|
||||||
menuFX.addHTML('<hr style="min-width: 200px; border-style: inset; border-color: dimgray">');
|
|
||||||
menuFX.addLabel('image processing');
|
|
||||||
menuFX.addBool('enabled', human.config.filter, 'enabled');
|
|
||||||
ui.menuWidth = menuFX.addRange('image width', human.config.filter, 'width', 0, 3840, 10, (val) => human.config.filter.width = parseInt(val));
|
|
||||||
ui.menuHeight = menuFX.addRange('image height', human.config.filter, 'height', 0, 2160, 10, (val) => human.config.filter.height = parseInt(val));
|
|
||||||
menuFX.addRange('brightness', human.config.filter, 'brightness', -1.0, 1.0, 0.05, (val) => human.config.filter.brightness = parseFloat(val));
|
|
||||||
menuFX.addRange('contrast', human.config.filter, 'contrast', -1.0, 1.0, 0.05, (val) => human.config.filter.contrast = parseFloat(val));
|
|
||||||
menuFX.addRange('sharpness', human.config.filter, 'sharpness', 0, 1.0, 0.05, (val) => human.config.filter.sharpness = parseFloat(val));
|
|
||||||
menuFX.addRange('blur', human.config.filter, 'blur', 0, 20, 1, (val) => human.config.filter.blur = parseInt(val));
|
|
||||||
menuFX.addRange('saturation', human.config.filter, 'saturation', -1.0, 1.0, 0.05, (val) => human.config.filter.saturation = parseFloat(val));
|
|
||||||
menuFX.addRange('hue', human.config.filter, 'hue', 0, 360, 5, (val) => human.config.filter.hue = parseInt(val));
|
|
||||||
menuFX.addRange('pixelate', human.config.filter, 'pixelate', 0, 32, 1, (val) => human.config.filter.pixelate = parseInt(val));
|
|
||||||
menuFX.addBool('negative', human.config.filter, 'negative');
|
|
||||||
menuFX.addBool('sepia', human.config.filter, 'sepia');
|
|
||||||
menuFX.addBool('vintage', human.config.filter, 'vintage');
|
|
||||||
menuFX.addBool('kodachrome', human.config.filter, 'kodachrome');
|
|
||||||
menuFX.addBool('technicolor', human.config.filter, 'technicolor');
|
|
||||||
menuFX.addBool('polaroid', human.config.filter, 'polaroid');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function setupMonitor() {
|
|
||||||
let gl = human.tf.engine().backend.gpgpu;
|
|
||||||
if (!gl) gl = document.getElementById('bench-canvas').getContext('webgl2');
|
|
||||||
if (!bench) {
|
|
||||||
bench = new GLBench(gl, {
|
|
||||||
trackGPU: true,
|
|
||||||
chartHz: 20,
|
|
||||||
chartLen: 20,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
function update(now) {
|
|
||||||
bench.nextFrame(now);
|
|
||||||
requestAnimationFrame(update);
|
|
||||||
}
|
|
||||||
requestAnimationFrame(update);
|
|
||||||
*/
|
|
||||||
// class MathBackendWebGL extends tf.KernelBackend property gpgpu is gl context
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
log('demo starting ...');
|
log('demo starting ...');
|
||||||
setupMenu();
|
setupMenu();
|
||||||
setupMonitor();
|
document.getElementById('log').innerText = `Human: version ${human.version}`;
|
||||||
document.getElementById('log').innerText = `Human: version ${human.version} TensorFlow/JS: version ${human.tf.version_core}`;
|
|
||||||
// human.tf.ENV.set('WEBGL_FORCE_F16_TEXTURES', true);
|
// human.tf.ENV.set('WEBGL_FORCE_F16_TEXTURES', true);
|
||||||
// this is not required, just pre-loads all models
|
// this is not required, just pre-loads all models
|
||||||
if (ui.modelsPreload && !ui.useWorker) {
|
if (ui.modelsPreload && !ui.useWorker) {
|
||||||
|
@ -486,7 +498,7 @@ async function main() {
|
||||||
// this is not required, just pre-warms all models for faster initial inference
|
// this is not required, just pre-warms all models for faster initial inference
|
||||||
if (ui.modelsWarmup && !ui.useWorker) {
|
if (ui.modelsWarmup && !ui.useWorker) {
|
||||||
status('initializing');
|
status('initializing');
|
||||||
sample = await human.warmup(userConfig, document.getElementById('sample-image'));
|
await human.warmup(userConfig);
|
||||||
}
|
}
|
||||||
status('human: ready');
|
status('human: ready');
|
||||||
document.getElementById('loader').style.display = 'none';
|
document.getElementById('loader').style.display = 'none';
|
||||||
|
|
23
demo/draw.js
23
demo/draw.js
|
@ -7,7 +7,10 @@ async function drawGesture(result, canvas, ui) {
|
||||||
for (const [key, val] of Object.entries(result)) {
|
for (const [key, val] of Object.entries(result)) {
|
||||||
if (val.length > 0) {
|
if (val.length > 0) {
|
||||||
const label = `${key}: ${val.join(', ')}`;
|
const label = `${key}: ${val.join(', ')}`;
|
||||||
ctx.fillText(label, 6, i * (ui.baseLineHeight + 24));
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.fillText(label, 8, 2 + (i * ui.baseLineHeight));
|
||||||
|
ctx.fillStyle = ui.baseLabel;
|
||||||
|
ctx.fillText(label, 6, 0 + (i * ui.baseLineHeight));
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +32,7 @@ async function drawFace(result, canvas, ui, triangulation) {
|
||||||
const labels = [];
|
const labels = [];
|
||||||
// labels.push(`${Math.trunc(100 * face.confidence)}% face`);
|
// labels.push(`${Math.trunc(100 * face.confidence)}% face`);
|
||||||
if (face.genderConfidence) labels.push(`${Math.trunc(100 * face.genderConfidence)}% ${face.gender || ''}`);
|
if (face.genderConfidence) labels.push(`${Math.trunc(100 * face.genderConfidence)}% ${face.gender || ''}`);
|
||||||
|
// if (face.genderConfidence) labels.push(face.gender);
|
||||||
if (face.age) labels.push(`age: ${face.age || ''}`);
|
if (face.age) labels.push(`age: ${face.age || ''}`);
|
||||||
if (face.iris) labels.push(`iris: ${face.iris}`);
|
if (face.iris) labels.push(`iris: ${face.iris}`);
|
||||||
if (face.emotion && face.emotion.length > 0) {
|
if (face.emotion && face.emotion.length > 0) {
|
||||||
|
@ -36,7 +40,13 @@ async function drawFace(result, canvas, ui, triangulation) {
|
||||||
labels.push(emotion.join(' '));
|
labels.push(emotion.join(' '));
|
||||||
}
|
}
|
||||||
ctx.fillStyle = ui.baseLabel;
|
ctx.fillStyle = ui.baseLabel;
|
||||||
for (const i in labels) ctx.fillText(labels[i], face.box[0] + 8, face.box[1] + 24 + ((i + 1) * ui.baseLineHeight));
|
for (let i = 0; i < labels.length; i++) {
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.fillText(labels[i], face.box[0] + face.box[2] + 9, ((i + 1) * ui.baseLineHeight) + face.box[1] + 9);
|
||||||
|
ctx.fillStyle = ui.baseLabel;
|
||||||
|
ctx.fillText(labels[i], face.box[0] + face.box[2] + 8, ((i + 1) * ui.baseLineHeight) + face.box[1] + 8);
|
||||||
|
}
|
||||||
|
ctx.fillStyle = ui.baseColor;
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
ctx.lineWidth = 1;
|
ctx.lineWidth = 1;
|
||||||
if (face.mesh) {
|
if (face.mesh) {
|
||||||
|
@ -186,8 +196,10 @@ async function drawHand(result, canvas, ui) {
|
||||||
ctx.strokeStyle = ui.baseColor;
|
ctx.strokeStyle = ui.baseColor;
|
||||||
ctx.fillStyle = ui.baseColor;
|
ctx.fillStyle = ui.baseColor;
|
||||||
ctx.rect(hand.box[0], hand.box[1], hand.box[2], hand.box[3]);
|
ctx.rect(hand.box[0], hand.box[1], hand.box[2], hand.box[3]);
|
||||||
|
ctx.fillStyle = 'black';
|
||||||
|
ctx.fillText('hand', hand.box[0] + 3, 1 + hand.box[1] + ui.baseLineHeight, hand.box[2]);
|
||||||
ctx.fillStyle = ui.baseLabel;
|
ctx.fillStyle = ui.baseLabel;
|
||||||
ctx.fillText('hand', hand.box[0] + 2, hand.box[1] + 22, hand.box[2]);
|
ctx.fillText('hand', hand.box[0] + 2, 0 + hand.box[1] + ui.baseLineHeight, hand.box[2]);
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
if (ui.drawPoints) {
|
if (ui.drawPoints) {
|
||||||
|
@ -222,11 +234,10 @@ async function drawHand(result, canvas, ui) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const draw = {
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
|
export default {
|
||||||
face: drawFace,
|
face: drawFace,
|
||||||
body: drawBody,
|
body: drawBody,
|
||||||
hand: drawHand,
|
hand: drawHand,
|
||||||
gesture: drawGesture,
|
gesture: drawGesture,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default draw;
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
// modified based on: https://github.com/munrocket/gl-bench
|
/* eslint-disable max-len */
|
||||||
|
|
||||||
|
// based on: https://github.com/munrocket/gl-bench
|
||||||
|
|
||||||
const UICSS = `
|
const UICSS = `
|
||||||
#gl-bench { position: absolute; right: 1rem; bottom: 1rem; z-index:1000; -webkit-user-select: none; -moz-user-select: none; user-select: none; }
|
#gl-bench { position: absolute; right: 1rem; bottom: 1rem; z-index:1000; -webkit-user-select: none; -moz-user-select: none; user-select: none; }
|
||||||
#gl-bench div { position: relative; display: block; margin: 4px; padding: 0 7px 0 10px; background: darkslategray; border-radius: 0.2rem; cursor: pointer; opacity: 0.9; }
|
#gl-bench div { position: relative; display: block; margin: 4px; padding: 0 7px 0 10px; background: darkslategray; border-radius: 0.2rem; cursor: pointer; opacity: 0.9; }
|
||||||
#gl-bench svg { height: 60px; margin: 0 4px 0px 4px; }
|
#gl-bench svg { height: 60px; margin: 0 0px 0px 4px; }
|
||||||
#gl-bench text { font-size: 16px; font-family: 'Lato', 'Segoe UI'; dominant-baseline: middle; text-anchor: middle; }
|
#gl-bench text { font-size: 16px; font-family: 'Lato', 'Segoe UI'; dominant-baseline: middle; text-anchor: middle; }
|
||||||
#gl-bench .gl-mem { font-size: 12px; fill: white; }
|
#gl-bench .gl-mem { font-size: 12px; fill: white; }
|
||||||
#gl-bench .gl-fps { font-size: 13px; fill: white; }
|
#gl-bench .gl-fps { font-size: 13px; fill: white; }
|
||||||
|
@ -17,7 +19,7 @@ const UISVG = `
|
||||||
<div class="gl-box">
|
<div class="gl-box">
|
||||||
<svg viewBox="0 0 55 60">
|
<svg viewBox="0 0 55 60">
|
||||||
<text x="27" y="56" class="gl-fps">00 FPS</text>
|
<text x="27" y="56" class="gl-fps">00 FPS</text>
|
||||||
<text x="28" y="8" class="gl-mem"></text>
|
<text x="30" y="8" class="gl-mem"></text>
|
||||||
<rect x="0" y="14" rx="4" ry="4" width="55" height="32"></rect>
|
<rect x="0" y="14" rx="4" ry="4" width="55" height="32"></rect>
|
||||||
<polyline class="gl-chart"></polyline>
|
<polyline class="gl-chart"></polyline>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -87,21 +89,41 @@ class GLBench {
|
||||||
});
|
});
|
||||||
}, 0));
|
}, 0));
|
||||||
|
|
||||||
const addProfiler = (fn, self, target) => function () {
|
const addProfiler = (fn, self, target) => {
|
||||||
const t = self.now();
|
const t = self.now();
|
||||||
// eslint-disable-next-line prefer-rest-params
|
// eslint-disable-next-line prefer-rest-params
|
||||||
fn.apply(target, arguments);
|
fn.apply(target, arguments);
|
||||||
if (self.trackGPU) self.finished.push(glFinish(t, self.activeAccums.slice(0)));
|
if (self.trackGPU) self.finished.push(glFinish(t, self.activeAccums.slice(0)));
|
||||||
};
|
};
|
||||||
|
|
||||||
['drawArrays', 'drawElements', 'drawArraysInstanced', 'drawBuffers', 'drawElementsInstanced', 'drawRangeElements'].forEach((fn) => { if (gl[fn]) gl[fn] = addProfiler(gl[fn], this, gl); });
|
/* ['drawArrays', 'drawElements', 'drawArraysInstanced', 'drawBuffers', 'drawElementsInstanced', 'drawRangeElements'].forEach((fn) => {
|
||||||
|
if (gl[fn]) {
|
||||||
|
gl[fn] = addProfiler(gl[fn], this, gl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
const fn = 'drawElements';
|
||||||
|
if (gl[fn]) {
|
||||||
|
gl[fn] = addProfiler(gl[fn], this, gl);
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('bench: cannot attach to webgl function');
|
||||||
|
}
|
||||||
|
|
||||||
gl.getExtension = ((fn, self) => function () {
|
/*
|
||||||
|
gl.getExtension = ((fn, self) => {
|
||||||
// eslint-disable-next-line prefer-rest-params
|
// eslint-disable-next-line prefer-rest-params
|
||||||
const ext = fn.apply(gl, arguments);
|
const ext = fn.apply(gl, arguments);
|
||||||
if (ext) ['drawElementsInstancedANGLE', 'drawBuffersWEBGL'].forEach((fn2) => { if (ext[fn2]) ext[fn2] = addProfiler(ext[fn2], self, ext); });
|
if (ext) {
|
||||||
|
['drawElementsInstancedANGLE', 'drawBuffersWEBGL'].forEach((fn2) => {
|
||||||
|
if (ext[fn2]) {
|
||||||
|
ext[fn2] = addProfiler(ext[fn2], self, ext);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return ext;
|
return ext;
|
||||||
})(gl.getExtension, this);
|
})(gl.getExtension, this);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// init ui and ui loggers
|
// init ui and ui loggers
|
||||||
|
@ -127,7 +149,7 @@ class GLBench {
|
||||||
nodes['gl-gpu'][i].style.strokeDasharray = (gpu * 0.27).toFixed(0) + ' 100';
|
nodes['gl-gpu'][i].style.strokeDasharray = (gpu * 0.27).toFixed(0) + ' 100';
|
||||||
// eslint-disable-next-line no-nested-ternary
|
// eslint-disable-next-line no-nested-ternary
|
||||||
nodes['gl-mem'][i].innerHTML = names[i] ? names[i] : (mem ? 'mem: ' + mem.toFixed(0) + 'mb' : '');
|
nodes['gl-mem'][i].innerHTML = names[i] ? names[i] : (mem ? 'mem: ' + mem.toFixed(0) + 'mb' : '');
|
||||||
nodes['gl-fps'][i].innerHTML = fps.toFixed(0) + ' FPS';
|
nodes['gl-fps'][i].innerHTML = 'FPS: ' + fps.toFixed(1);
|
||||||
logger(names[i], cpu, gpu, mem, fps, totalTime, frameId);
|
logger(names[i], cpu, gpu, mem, fps, totalTime, frameId);
|
||||||
};
|
};
|
||||||
})(this.paramLogger, this.dom, this.names);
|
})(this.paramLogger, this.dom, this.names);
|
|
@ -19,22 +19,26 @@
|
||||||
<!-- <script src="./browser.js" type="module"></script> -->
|
<!-- <script src="./browser.js" type="module"></script> -->
|
||||||
<style>
|
<style>
|
||||||
@font-face { font-family: 'Lato'; font-display: swap; font-style: normal; font-weight: 400; src: local('Lato'), url('../assets/lato.ttf') format('truetype'); }
|
@font-face { font-family: 'Lato'; font-display: swap; font-style: normal; font-weight: 400; src: local('Lato'), url('../assets/lato.ttf') format('truetype'); }
|
||||||
|
@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; }
|
html { font-family: 'Lato', 'Segoe UI'; font-size: 16px; font-variant: small-caps; }
|
||||||
body { margin: 0; background: black; color: white; overflow-x: hidden; scrollbar-width: none; }
|
body { margin: 0; background: black; color: white; overflow-x: hidden; scrollbar-width: none; }
|
||||||
body::-webkit-scrollbar { display: none; }
|
body::-webkit-scrollbar { display: none; }
|
||||||
.play { position: absolute; width: 300px; height: 300px; z-index: 9; top: 30%; left: 50%; margin-left: -150px; display: none; }
|
hr { width: 100%; }
|
||||||
.play-background { fill:darkslategray; cursor:pointer; opacity: 0.6; }
|
.play { position: absolute; width: 250px; height: 250px; z-index: 9; top: 55%; left: 50%; margin-left: -125px; display: none; }
|
||||||
.play-foreground { fill:white; cursor:pointer; opacity: 0.8; }
|
.btn-background { fill:grey; cursor: pointer; opacity: 0.6; }
|
||||||
.play-foreground:hover { opacity: 1; }
|
.btn-background:hover { opacity: 1; }
|
||||||
|
.btn-foreground { fill:white; cursor: pointer; opacity: 0.8; }
|
||||||
|
.btn-foreground:hover { opacity: 1; }
|
||||||
.status { position: absolute; width: 100vw; bottom: 15%; text-align: center; font-size: 4rem; font-weight: 100; text-shadow: 2px 2px darkslategrey; }
|
.status { position: absolute; width: 100vw; bottom: 15%; text-align: center; font-size: 4rem; font-weight: 100; text-shadow: 2px 2px darkslategrey; }
|
||||||
.thumbnail { margin: 8px; box-shadow: 0 0 4px 4px dimgrey; }
|
.thumbnail { margin: 8px; box-shadow: 0 0 4px 4px dimgrey; }
|
||||||
.thumbnail:hover { box-shadow: 0 0 8px 8px dimgrey; filter: grayscale(1); }
|
.thumbnail:hover { box-shadow: 0 0 8px 8px dimgrey; filter: grayscale(1); }
|
||||||
.log { position: fixed; bottom: 0; margin: 0.4rem; font-size: 0.9rem; }
|
.log { position: absolute; bottom: 0; margin: 0.4rem; font-size: 0.9rem; }
|
||||||
|
.menubar { width: 100vw; background: darkslategray; display: flex; justify-content: space-evenly; text-align: center; padding: 8px; cursor: pointer; }
|
||||||
.samples-container { display: flex; flex-wrap: wrap; }
|
.samples-container { display: flex; flex-wrap: wrap; }
|
||||||
.video { display: none; }
|
.video { display: none; }
|
||||||
.canvas { margin: 0 auto; }
|
.canvas { margin: 0 auto; }
|
||||||
.bench { position: absolute; right: 0; bottom: 0; }
|
.bench { position: absolute; right: 0; bottom: 0; }
|
||||||
.compare-image { width: 10vw; position: absolute; top: 150px; left: 30px; box-shadow: 0 0 2px 2px black; background: black; }
|
.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; top: 30%; 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; top: 30%; 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, .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::before { border-top-color: #bad375; animation: 3s spin linear infinite; }
|
||||||
|
@ -51,13 +55,22 @@
|
||||||
from { transform: rotate(0deg); }
|
from { transform: rotate(0deg); }
|
||||||
from { transform: rotate(360deg); }
|
from { transform: rotate(360deg); }
|
||||||
}
|
}
|
||||||
|
.button { text-shadow: 2px 2px black; display: flex; }
|
||||||
|
.button:hover { text-shadow: -2px -2px black; color: lightblue; }
|
||||||
|
.button::before { display: inline-block; font-style: normal; font-variant: normal; text-rendering: auto; -webkit-font-smoothing: antialiased; font-family: "FA"; font-weight: 900; font-size: 2.4rem; margin-right: 0.4rem; }
|
||||||
|
.button-display::before { content: "\f8c4"; }
|
||||||
|
.button-image::before { content: "\f3f2"; }
|
||||||
|
.button-process::before { content: "\f3f0"; }
|
||||||
|
.button-model::before { content: "\f2c2"; }
|
||||||
|
.button-start::before { content: "\f144"; }
|
||||||
|
.button-stop::before { content: "\f28b"; }
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="play" class="play">
|
<div id="play" class="play">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
<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="play-background"/>
|
<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="play-foreground"/>
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div id="background">
|
<div id="background">
|
||||||
|
@ -67,16 +80,22 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="loader" class="loader"></div>
|
<div id="loader" class="loader"></div>
|
||||||
<div id="status" class="status"></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>
|
||||||
<div id="media">
|
<div id="media">
|
||||||
<canvas id="canvas" class="canvas"></canvas>
|
<canvas id="canvas" class="canvas"></canvas>
|
||||||
<video id="video" playsinline class="video"></video>
|
<video id="video" playsinline class="video"></video>
|
||||||
</div>
|
</div>
|
||||||
<div id="compare-container" style="display: none" class="compare-image">
|
<div id="compare-container" style="display: none" class="compare-image">
|
||||||
<img id="sample-image" style="width: 100%" src="../assets/sample-me.jpg"></img>
|
<canvas id="compare-canvas" width="200px" height="200px"></canvas>
|
||||||
<div id="simmilarity"></div>
|
<div id="simmilarity"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="samples-container" class="samples-container"></div>
|
<div id="samples-container" class="samples-container"></div>
|
||||||
<canvas id="bench-canvas" class="bench"></canvas>
|
|
||||||
<div id="log" class="log"></div>
|
<div id="log" class="log"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
26
demo/menu.js
26
demo/menu.js
|
@ -19,15 +19,15 @@ function createCSS() {
|
||||||
if (CSScreated) return;
|
if (CSScreated) return;
|
||||||
const css = `
|
const css = `
|
||||||
:root { --rounded: 0.2rem; }
|
:root { --rounded: 0.2rem; }
|
||||||
.menu { position: absolute; top: 0rem; right: 0; width: fit-content; padding: 0 0.8rem 0 0.8rem; line-height: 1.8rem; z-index: 10;
|
.menu { position: absolute; top: 0rem; right: 0; width: fit-content; padding: 0 0.2rem 0 0.2rem; line-height: 1.8rem; z-index: 10;
|
||||||
box-shadow: 0 0 8px dimgrey; background: ${theme.background}; border-radius: var(--rounded); border-color: black; border-style: solid; border-width: thin; }
|
box-shadow: 0 0 8px dimgrey; background: ${theme.background}; border-radius: var(--rounded); border-color: black; border-style: solid; border-width: thin; }
|
||||||
|
|
||||||
.menu:hover { box-shadow: 0 0 8px ${theme.hover}; }
|
.menu:hover { box-shadow: 0 0 8px ${theme.hover}; }
|
||||||
.menu-container { display: block; max-height: 100vh; }
|
.menu-container { display: block; max-height: 100vh; }
|
||||||
.menu-container-fadeout { max-height: 0; overflow: hidden; transition: max-height, 0.5s ease; }
|
.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-container-fadein { max-height: 100vh; overflow: hidden; transition: max-height, 0.5s ease; }
|
||||||
.menu-item { display: flex; white-space: nowrap; padding: 0.2rem; width: max-content; cursor: default; }
|
.menu-item { display: flex; white-space: nowrap; padding: 0.2rem; cursor: default; width: 100%; }
|
||||||
.menu-title { text-align: right; cursor: pointer; }
|
.menu-title { cursor: pointer; }
|
||||||
.menu-hr { margin: 0.2rem; border: 1px solid rgba(0, 0, 0, 0.5) }
|
.menu-hr { margin: 0.2rem; border: 1px solid rgba(0, 0, 0, 0.5) }
|
||||||
.menu-label { padding: 0; font-weight: 800; }
|
.menu-label { padding: 0; font-weight: 800; }
|
||||||
|
|
||||||
|
@ -39,12 +39,12 @@ function createCSS() {
|
||||||
.menu-chart-title { padding: 0; font-size: 0.8rem; font-weight: 800; align-items: center}
|
.menu-chart-title { padding: 0; font-size: 0.8rem; font-weight: 800; align-items: center}
|
||||||
.menu-chart-canvas { background: transparent; margin: 0.2rem 0 0.2rem 0.6rem; }
|
.menu-chart-canvas { background: transparent; margin: 0.2rem 0 0.2rem 0.6rem; }
|
||||||
|
|
||||||
.menu-button { border: 0; background: ${theme.buttonBackground}; width: 100%; padding: 8px; margin: 8px 0 8px 0; cursor: pointer; box-shadow: 4px 4px 4px 0 dimgrey;
|
.menu-button { border: 0; background: ${theme.buttonBackground}; width: -webkit-fill-available; padding: 8px; margin: 8px; cursor: pointer; box-shadow: 4px 4px 4px 0 dimgrey;
|
||||||
border-radius: var(--rounded); justify-content: center; font-family: inherit; font-variant: inherit; font-size: 1rem; font-weight: 800; }
|
border-radius: var(--rounded); justify-content: center; font-family: inherit; font-variant: inherit; font-size: 1rem; font-weight: 800; }
|
||||||
.menu-button:hover { background: ${theme.buttonHover}; box-shadow: 4px 4px 4px 0 black; }
|
.menu-button:hover { background: ${theme.buttonHover}; box-shadow: 4px 4px 4px 0 black; }
|
||||||
.menu-button:focus { outline: none; }
|
.menu-button:focus { outline: none; }
|
||||||
|
|
||||||
.menu-checkbox { width: 2.8rem; height: 1rem; background: ${theme.itemBackground}; margin: 0.5rem 0.8rem 0 0; position: relative; border-radius: var(--rounded); }
|
.menu-checkbox { width: 2.8rem; height: 1rem; background: ${theme.itemBackground}; margin: 0.5rem 0.5rem 0 0; position: relative; border-radius: var(--rounded); }
|
||||||
.menu-checkbox:after { content: 'OFF'; color: ${theme.checkboxOff}; position: absolute; right: 0.2rem; top: -0.4rem; font-weight: 800; font-size: 0.5rem; }
|
.menu-checkbox:after { content: 'OFF'; color: ${theme.checkboxOff}; position: absolute; right: 0.2rem; top: -0.4rem; font-weight: 800; font-size: 0.5rem; }
|
||||||
.menu-checkbox:before { content: 'ON'; color: ${theme.checkboxOn}; position: absolute; left: 0.3rem; top: -0.4rem; font-weight: 800; font-size: 0.5rem; }
|
.menu-checkbox:before { content: 'ON'; color: ${theme.checkboxOn}; position: absolute; left: 0.3rem; top: -0.4rem; font-weight: 800; font-size: 0.5rem; }
|
||||||
.menu-checkbox-label { width: 1.3rem; height: 0.8rem; cursor: pointer; position: absolute; top: 0.1rem; left: 0.1rem; z-index: 1; background: ${theme.checkboxOff};
|
.menu-checkbox-label { width: 1.3rem; height: 0.8rem; cursor: pointer; position: absolute; top: 0.1rem; left: 0.1rem; z-index: 1; background: ${theme.checkboxOff};
|
||||||
|
@ -53,14 +53,14 @@ function createCSS() {
|
||||||
input[type=checkbox] { visibility: hidden; }
|
input[type=checkbox] { visibility: hidden; }
|
||||||
input[type=checkbox]:checked + label { left: 1.4rem; background: ${theme.checkboxOn}; }
|
input[type=checkbox]:checked + label { left: 1.4rem; background: ${theme.checkboxOn}; }
|
||||||
|
|
||||||
.menu-range { margin: 0 0.8rem 0 0; width: 5rem; background: transparent; color: ${theme.rangeBackground}; }
|
.menu-range { margin: 0.2rem 0.5rem 0 0; width: 3.5rem; background: transparent; color: ${theme.rangeBackground}; }
|
||||||
.menu-range:before { color: ${theme.rangeLabel}; margin: 0 0.4rem 0 0; font-weight: 800; font-size: 0.6rem; position: relative; top: 0.3rem; content: attr(value); }
|
.menu-range:before { color: ${theme.rangeLabel}; margin: 0 0.4rem 0 0; font-weight: 800; font-size: 0.6rem; position: relative; top: 0.3rem; content: attr(value); }
|
||||||
|
|
||||||
input[type=range] { -webkit-appearance: none; }
|
input[type=range] { -webkit-appearance: none; }
|
||||||
input[type=range]::-webkit-slider-runnable-track { width: 100%; height: 1rem; cursor: pointer; background: ${theme.itemBackground}; border-radius: var(--rounded); border: 1px; }
|
input[type=range]::-webkit-slider-runnable-track { width: 100%; height: 1rem; cursor: pointer; background: ${theme.itemBackground}; border-radius: var(--rounded); border: 1px; }
|
||||||
input[type=range]::-moz-range-track { width: 100%; height: 1rem; cursor: pointer; background: ${theme.itemBackground}; border-radius: var(--rounded); border: 1px; }
|
input[type=range]::-moz-range-track { width: 100%; height: 1rem; cursor: pointer; background: ${theme.itemBackground}; border-radius: var(--rounded); border: 1px; }
|
||||||
input[type=range]::-webkit-slider-thumb { border: 1px solid #000000; margin-top: 0.05rem; height: 0.9rem; width: 1.5rem; border-radius: var(--rounded); background: ${theme.rangeBackground}; cursor: pointer; -webkit-appearance: none; }
|
input[type=range]::-webkit-slider-thumb { border: 1px solid #000000; margin-top: 0.05rem; height: 0.9rem; width: 1rem; border-radius: var(--rounded); background: ${theme.rangeBackground}; cursor: pointer; -webkit-appearance: none; }
|
||||||
input[type=range]::-moz-range-thumb { border: 1px solid #000000; margin-top: 0.05rem; height: 0.9rem; width: 1.5rem; border-radius: var(--rounded); background: ${theme.rangeBackground}; cursor: pointer; -webkit-appearance: none; }
|
input[type=range]::-moz-range-thumb { border: 1px solid #000000; margin-top: 0.05rem; height: 0.9rem; width: 1rem; border-radius: var(--rounded); background: ${theme.rangeBackground}; cursor: pointer; -webkit-appearance: none; }
|
||||||
|
|
||||||
.svg-background { fill:darkslategrey; cursor:pointer; opacity: 0.6; }
|
.svg-background { fill:darkslategrey; cursor:pointer; opacity: 0.6; }
|
||||||
.svg-foreground { fill:white; cursor:pointer; opacity: 0.8; }
|
.svg-foreground { fill:white; cursor:pointer; opacity: 0.8; }
|
||||||
|
@ -106,7 +106,7 @@ class Menu {
|
||||||
<path d="M400 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zm-51.37 182.31L232.06 348.16a10.38 10.38 0 0 1-16.12 0L99.37 214.31C92.17 206 97.28 192 107.43 192h233.14c10.15 0 15.26 14 8.06 22.31z" class="svg-background"/>
|
<path d="M400 32H48A48 48 0 0 0 0 80v352a48 48 0 0 0 48 48h352a48 48 0 0 0 48-48V80a48 48 0 0 0-48-48zm-51.37 182.31L232.06 348.16a10.38 10.38 0 0 1-16.12 0L99.37 214.31C92.17 206 97.28 192 107.43 192h233.14c10.15 0 15.26 14 8.06 22.31z" class="svg-background"/>
|
||||||
<path d="M348.63 214.31L232.06 348.16a10.38 10.38 0 0 1-16.12 0L99.37 214.31C92.17 206 97.28 192 107.43 192h233.14c10.15 0 15.26 14 8.06 22.31z" class="svg-foreground"/>
|
<path d="M348.63 214.31L232.06 348.16a10.38 10.38 0 0 1-16.12 0L99.37 214.31C92.17 206 97.28 192 107.43 192h233.14c10.15 0 15.26 14 8.06 22.31z" class="svg-foreground"/>
|
||||||
</svg>`;
|
</svg>`;
|
||||||
elTitle.innerHTML = `${title}${svg}`;
|
if (title) elTitle.innerHTML = `${title}${svg}`;
|
||||||
this.menu.appendChild(elTitle);
|
this.menu.appendChild(elTitle);
|
||||||
elTitle.addEventListener('click', () => {
|
elTitle.addEventListener('click', () => {
|
||||||
this.container.classList.toggle('menu-container-fadeout');
|
this.container.classList.toggle('menu-container-fadeout');
|
||||||
|
@ -152,9 +152,9 @@ class Menu {
|
||||||
this.container.classList.toggle('menu-container-fadein');
|
this.container.classList.toggle('menu-container-fadein');
|
||||||
if (this.container.classList.contains('menu-container-fadein') && evt) {
|
if (this.container.classList.contains('menu-container-fadein') && evt) {
|
||||||
const x = evt.x || (evt.touches && evt.touches[0] ? evt.touches[0].pageX : null);
|
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);
|
// const y = evt.y || (evt.touches && evt.touches[0] ? evt.touches[0].pageY : null);
|
||||||
if (x) this.menu.style.left = `${x - 105}px`;
|
if (x) this.menu.style.left = `${x - (this.menu.offsetWidth / 2)}px`;
|
||||||
if (y) this.menu.style.top = '5.5rem'; // `${evt.y + 55}px`;
|
// if (y) this.menu.style.top = '5.5rem'; // `${evt.y + 55}px`;
|
||||||
if (this.menu.offsetLeft < 0) this.menu.style.left = 0;
|
if (this.menu.offsetLeft < 0) this.menu.style.left = 0;
|
||||||
if ((this.menu.offsetLeft + this.menu.offsetWidth) > window.innerWidth) {
|
if ((this.menu.offsetLeft + this.menu.offsetWidth) > window.innerWidth) {
|
||||||
this.menu.style.left = null;
|
this.menu.style.left = null;
|
||||||
|
@ -279,7 +279,7 @@ class Menu {
|
||||||
else this.addValue(title, val);
|
else this.addValue(title, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
addChart(title, id, width = 200, height = 40, color) {
|
addChart(title, id, width = 150, height = 40, color) {
|
||||||
if (color) theme.chartColor = color;
|
if (color) theme.chartColor = color;
|
||||||
const el = document.createElement('div');
|
const el = document.createElement('div');
|
||||||
el.className = 'menu-item menu-chart-title';
|
el.className = 'menu-item menu-chart-title';
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,11 +1,7 @@
|
||||||
{
|
{
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"assets/gl-bench.js": {
|
|
||||||
"bytes": 10410,
|
|
||||||
"imports": []
|
|
||||||
},
|
|
||||||
"demo/browser.js": {
|
"demo/browser.js": {
|
||||||
"bytes": 23089,
|
"bytes": 24755,
|
||||||
"imports": [
|
"imports": [
|
||||||
{
|
{
|
||||||
"path": "dist/human.esm.js"
|
"path": "dist/human.esm.js"
|
||||||
|
@ -17,16 +13,20 @@
|
||||||
"path": "demo/menu.js"
|
"path": "demo/menu.js"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "assets/gl-bench.js"
|
"path": "demo/gl-bench.js"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"demo/draw.js": {
|
"demo/draw.js": {
|
||||||
"bytes": 9814,
|
"bytes": 10436,
|
||||||
|
"imports": []
|
||||||
|
},
|
||||||
|
"demo/gl-bench.js": {
|
||||||
|
"bytes": 10782,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"demo/menu.js": {
|
"demo/menu.js": {
|
||||||
"bytes": 13814,
|
"bytes": 13842,
|
||||||
"imports": []
|
"imports": []
|
||||||
},
|
},
|
||||||
"dist/human.esm.js": {
|
"dist/human.esm.js": {
|
||||||
|
@ -38,29 +38,29 @@
|
||||||
"dist/demo-browser-index.js.map": {
|
"dist/demo-browser-index.js.map": {
|
||||||
"imports": [],
|
"imports": [],
|
||||||
"inputs": {},
|
"inputs": {},
|
||||||
"bytes": 2671871
|
"bytes": 2675872
|
||||||
},
|
},
|
||||||
"dist/demo-browser-index.js": {
|
"dist/demo-browser-index.js": {
|
||||||
"imports": [],
|
"imports": [],
|
||||||
"exports": [],
|
"exports": [],
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"dist/human.esm.js": {
|
"dist/human.esm.js": {
|
||||||
"bytesInOutput": 1776267
|
"bytesInOutput": 1776263
|
||||||
},
|
},
|
||||||
"demo/draw.js": {
|
"demo/draw.js": {
|
||||||
"bytesInOutput": 7284
|
"bytesInOutput": 7668
|
||||||
},
|
},
|
||||||
"demo/menu.js": {
|
"demo/menu.js": {
|
||||||
"bytesInOutput": 11921
|
"bytesInOutput": 11838
|
||||||
},
|
},
|
||||||
"assets/gl-bench.js": {
|
"demo/gl-bench.js": {
|
||||||
"bytesInOutput": 7731
|
"bytesInOutput": 7436
|
||||||
},
|
},
|
||||||
"demo/browser.js": {
|
"demo/browser.js": {
|
||||||
"bytesInOutput": 16997
|
"bytesInOutput": 19015
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"bytes": 1827465
|
"bytes": 1829485
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -116,8 +116,8 @@ class Human {
|
||||||
if (userConfig) this.config = mergeDeep(this.config, userConfig);
|
if (userConfig) this.config = mergeDeep(this.config, userConfig);
|
||||||
|
|
||||||
if (this.firstRun) {
|
if (this.firstRun) {
|
||||||
this.checkBackend(true);
|
|
||||||
this.log(`version: ${this.version} TensorFlow/JS version: ${tf.version_core}`);
|
this.log(`version: ${this.version} TensorFlow/JS version: ${tf.version_core}`);
|
||||||
|
this.checkBackend(true);
|
||||||
this.log('configuration:', this.config);
|
this.log('configuration:', this.config);
|
||||||
this.log('flags:', tf.ENV.flags);
|
this.log('flags:', tf.ENV.flags);
|
||||||
this.firstRun = false;
|
this.firstRun = false;
|
||||||
|
|
Loading…
Reference in New Issue