Quick start with ppg-js
Start ppg-js with a script tag, npm, or a reusable React hook.
Quick start
Choose the setup that matches your app. In every case, call start() from a button click or tap.
<script src="https://unpkg.com/@sontakey/ppg-js/dist/index.global.js"></script>
<script>
const ppg = new PPG.PPG();
ppg.addEventListener('metrics', (e) => {
console.log(e.detail.heartRate, e.detail.quality);
});
// Camera permission needs a user gesture.
document.querySelector('#start').onclick = () => ppg.start();
</script>import { PPG } from '@sontakey/ppg-js';
const ppg = new PPG();
ppg.addEventListener('state', (e) => {
// NO_FINGER -> SETTLING -> MEASURING
console.log(e.detail.state, e.detail.reason);
});
ppg.addEventListener('metrics', (e) => {
const m = e.detail;
if (!m.quality.good) {
console.log('not ready:', m.quality.reason, m.guidanceMessage);
return;
}
console.log(`${m.heartRate} bpm, RMSSD ${m.rmssd.toFixed(0)} ms`);
});
// Camera, wake lock, and motion permission need a user gesture.
button.onclick = () => ppg.start();import { useEffect, useRef, useState } from 'react';
import { PPG } from '@sontakey/ppg-js';
export function usePulse() {
const ppgRef = useRef<PPG | null>(null);
const [bpm, setBpm] = useState(0);
const [status, setStatus] = useState('Tap start, then cover the camera');
useEffect(() => {
const ppg = new PPG();
ppgRef.current = ppg;
ppg.addEventListener('metrics', (e) => {
const m = e.detail;
if (m.quality.good) setBpm(m.heartRate);
else setStatus(m.guidanceMessage);
});
return () => ppg.destroy();
}, []);
// Call from a button's onClick.
const start = () => ppgRef.current?.start();
return { bpm, status, start };
}After a session
import { hrv } from '@sontakey/ppg-js';
const beats = ppg.getTachogram({ goodOnly: true, hrvOnly: true })
.filter((beat) => beat.valid);
const report = hrv.analyzeHRV(beats, {
rmssdFloorMs: ppg.getMetrics().rmssdFloorMs,
});