1+ const video3 = document . getElementsByClassName ( 'input_video3' ) [ 0 ] ;
2+ const out3 = document . getElementsByClassName ( 'output3' ) [ 0 ] ;
3+ const controlsElement3 = document . getElementsByClassName ( 'control3' ) [ 0 ] ;
4+ const canvasCtx3 = out3 . getContext ( '2d' ) ;
5+ const fpsControl = new FPS ( ) ;
6+
7+ const spinner = document . querySelector ( '.loading' ) ;
8+ spinner . ontransitionend = ( ) => {
9+ spinner . style . display = 'none' ;
10+ } ;
11+
12+ function onResultsHands ( results ) {
13+ document . body . classList . add ( 'loaded' ) ;
14+ fpsControl . tick ( ) ;
15+
16+ canvasCtx3 . save ( ) ;
17+ canvasCtx3 . clearRect ( 0 , 0 , out3 . width , out3 . height ) ;
18+ canvasCtx3 . drawImage (
19+ results . image , 0 , 0 , out3 . width , out3 . height ) ;
20+ if ( results . multiHandLandmarks && results . multiHandedness ) {
21+ for ( let index = 0 ; index < results . multiHandLandmarks . length ; index ++ ) {
22+ const classification = results . multiHandedness [ index ] ;
23+ const isRightHand = classification . label === 'Right' ;
24+ const landmarks = results . multiHandLandmarks [ index ] ;
25+ drawConnectors (
26+ canvasCtx3 , landmarks , HAND_CONNECTIONS ,
27+ { color : isRightHand ? '#00FF00' : '#FF0000' } ) ,
28+ drawLandmarks ( canvasCtx3 , landmarks , {
29+ color : isRightHand ? '#00FF00' : '#FF0000' ,
30+ fillColor : isRightHand ? '#FF0000' : '#00FF00' ,
31+ radius : ( x ) => {
32+ return lerp ( x . from . z , - 0.15 , .1 , 10 , 1 ) ;
33+ }
34+ } ) ;
35+ }
36+ }
37+ canvasCtx3 . restore ( ) ;
38+ }
39+
40+ const hands = new Hands ( { locateFile : ( file ) => {
41+ return `https://cdn.jsdelivr.net/npm/@mediapipe/[email protected] /${ file } ` ; 42+ } } ) ;
43+ hands . onResults ( onResultsHands ) ;
44+
45+ const camera = new Camera ( video3 , {
46+ onFrame : async ( ) => {
47+ await hands . send ( { image : video3 } ) ;
48+ } ,
49+ width : 480 ,
50+ height : 480
51+ } ) ;
52+ camera . start ( ) ;
53+
54+ new ControlPanel ( controlsElement3 , {
55+ selfieMode : true ,
56+ maxNumHands : 2 ,
57+ minDetectionConfidence : 0.5 ,
58+ minTrackingConfidence : 0.5
59+ } )
60+ . add ( [
61+ new StaticText ( { title : 'MediaPipe Hands' } ) ,
62+ fpsControl ,
63+ new Toggle ( { title : 'Selfie Mode' , field : 'selfieMode' } ) ,
64+ new Slider (
65+ { title : 'Max Number of Hands' , field : 'maxNumHands' , range : [ 1 , 4 ] , step : 1 } ) ,
66+ new Slider ( {
67+ title : 'Min Detection Confidence' ,
68+ field : 'minDetectionConfidence' ,
69+ range : [ 0 , 1 ] ,
70+ step : 0.01
71+ } ) ,
72+ new Slider ( {
73+ title : 'Min Tracking Confidence' ,
74+ field : 'minTrackingConfidence' ,
75+ range : [ 0 , 1 ] ,
76+ step : 0.01
77+ } ) ,
78+ ] )
79+ . on ( options => {
80+ video3 . classList . toggle ( 'selfie' , options . selfieMode ) ;
81+ hands . setOptions ( options ) ;
82+ } ) ;
0 commit comments