handsfree
Version:
Quickly integrate face, hand, and/or pose tracking to your frontend projects in a snap ✨👌
166 lines (141 loc) • 4.99 kB
HTML
<head>
<!-- Include Handsfree.js -->
<link rel="stylesheet" href="https://unpkg.com/handsfree@8.5.1/build/lib/assets/handsfree.css" />
<script src="https://unpkg.com/handsfree@8.5.1/build/lib/handsfree.js"></script>
<style>
.handsfree-canvas-video {
background: #000;
opacity: 0.1;
}
</style>
</head>
<body>
<!-- Start/stop button with helper classes -->
<div class="text-center">
<button class="handsfree-show-when-stopped handsfree-hide-when-loading" onclick="toggleModel('hands')">Start Hand Tracking</button>
<button class="handsfree-show-when-loading" disabled>Loading ...</button>
<button class="handsfree-show-when-started handsfree-hide-when-loading" onclick="handsfree.stop()">Stop Handsfree</button>
</div>
<p>
<span class="gesture-emoji" gesture="victory">✌</span>
<span class="gesture-emoji" gesture="thumbUp">👍</span>
<span class="gesture-emoji" gesture="thumbDown">👎</span>
<span class="gesture-emoji" gesture="pointLeft">👈</span>
<span class="gesture-emoji" gesture="pointRight">👉</span>
<span class="gesture-emoji" gesture="stop">🤚</span>
<span class="gesture-emoji" gesture="spock">🖖</span>
<span class="gesture-emoji" gesture="horns">🤘</span>
<span class="gesture-emoji" gesture="love">🤟</span>
<span class="gesture-emoji" gesture="fist">✊</span>
<span class="gesture-emoji" gesture="ok">👌</span>
<span class="gesture-emoji" gesture="callMe">🤙</span>
</p>
<!-- Instantiate and start it -->
<script>
const handsfree = new Handsfree({
// Show debug inside a specific element
showDebug: true,
setup: {
wrap: {
$parent: document.querySelector('#debugger-holder')
}
},
// Turn some of these on to combine them
hands: true,
facemesh: false,
pose: false,
weboji: false,
handpose: false
})
/**
* Plugin to detect and toggle models
*/
let lastGestureHandpose = null
let lastGestureHands = [null, null, null, null]
let currentShapeHands = ''
handsfree.use('gestureEmojiDetector', ({hands, handpose}) => {
if (hands?.gesture) {
hands.gesture.forEach((gesture, n) => {
if (gesture && gesture.name !== lastGestureHands[n]) {
let $el = document.querySelector(`.gesture-emoji[gesture="${lastGestureHands[n]}"]`)
if ($el) $el.classList.remove('active')
$el = document.querySelector(`.gesture-emoji[gesture="${gesture.name}"]`)
if ($el) $el.classList.add('active')
lastGestureHands[n] = gesture.name
}
// Disable the gesture emoji if no gestures
if (lastGestureHands[n] && !gesture?.name) {
let $el = document.querySelector(`.gesture-emoji[gesture="${lastGestureHands[n]}"]`)
if ($el) $el.classList.remove('active')
lastGestureHands[n] = null
}
})
}
// Toggle the gesture emoji
if (handpose?.gesture && handpose.gesture.name !== lastGestureHandpose) {
let $el = document.querySelector(`.gesture-emoji[gesture="${lastGestureHandpose}"]`)
if ($el) $el.classList.remove('active')
$el = document.querySelector(`.gesture-emoji[gesture="${handpose.gesture.name}"]`)
if ($el) $el.classList.add('active')
lastGestureHandpose = handpose.gesture.name
}
// Disable the gesture emoji if no gestures
if (lastGestureHandpose && !handpose?.gesture?.name) {
let $el = document.querySelector(`.gesture-emoji[gesture="${lastGestureHandpose}"]`)
if ($el) $el.classList.remove('active')
lastGestureHandpose = null
}
})
// Toggle Model
// @todo Actually add this to Handsfree
function toggleModel(name) {
const config = {}
config[name] = !handsfree.model[name].enabled
config.autostart = true
handsfree.update(config)
}
</script>
<!-- Demo styles -->
<style>
button {
font-size: 1em;
padding: .5em;
}
h1, table {
margin-top: 60px;
}
section {
width: 650px;
max-width: 100%;
margin: auto;
}
table {
width: 100%
}
.finger-pincher {
display: inline-block;
width: 32px;
height: 32px;
border-radius: 32px;
background: #000;
margin: auto;
}
.finger-pincher:last-child {
background: #f00;
}
.text-center {
text-align: center;
}
/* Emojis */
.gesture-emoji {
font-size: 30px;
display: inline-block;
margin-right: 10px;
margin-bottom: 10px;
opacity: 0.2;
}
.gesture-emoji.active {
opacity: 1;
}
</style>
</body>