一、trackingjs初体验-颜色捕获 vue3
前言
Tracking.js 是一个独立的JavaScript库(不依赖于任何框架),用于跟踪从相机实时收到的数据。
跟踪的数据既可以是颜色,也可以是人,
也就是说我们可以通过检测到某特定颜色,或者检测一个人体/脸的出现与移动,来触发JavaScript 事件。
它是非常易于使用的API,具有数个方法和事件(足够使用了)。
还有一个我觉得不错的功能就是,截取摄像头的图像,对于一些网站用这个功能来设置用户头像也是个很炫的功能。
安装
yarn add tracking
yarn add @types/tracking
使用教程
例子是vue3+ts+less
安装并引入
//@ts-nocheck
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import "tracking";
import "tracking/build/data/face";
import { Notify } from 'vant';
function getUserMedia(constrains, success, error) {
if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
//最新标准API
Notify({ type: 'success', message: '支持最新标准API' });
navigator.mediaDevices.getUserMedia(constrains).then(success).catch(error);
} else if (navigator.webkitGetUserMedia) {
Notify({ type: 'success', message: '支持webkit内核浏览器' });
//webkit内核浏览器
navigator.webkitGetUserMedia(constrains).then(success).catch(error);
} else if (navigator.mozGetUserMedia) {
Notify({ type: 'success', message: '支持Firefox浏览器' });
//Firefox浏览器
navagator.mozGetUserMedia(constrains).then(success).catch(error);
} else if (navigator.getUserMedia) {
Notify({ type: 'success', message: '支持旧版API' });
//旧版API
navigator.getUserMedia(constrains).then(success).catch(error);
} else {
Notify('浏览器不支持getUserMedia');
}
}
// 要重写initUserMedia_ 方法,因为chrome的底层api已做调整
window.tracking.initUserMedia_ = function (element, opt_options) {
const options = {
video: true,
audio: !!(opt_options && opt_options.audio)
};
getUserMedia(options, function (stream) {
try {
element.srcObject = stream;
} catch (err) {
element.src = window.URL.createObjectURL(stream);
}
}, function (e) {
Notify(e.message);
}
);
};
// 重写视频捕获方法,因为不能停止 stop无效的bug
window.tracking.trackVideo_ = function (element, tracker) {
console.log('trackVideo_');
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
var width;
var height;
var resizeCanvas_ = function () {
width = element.offsetWidth;
height = element.offsetHeight;
canvas.width = width;
canvas.height = height;
};
resizeCanvas_();
element.addEventListener('resize', resizeCanvas_);
var requestId;
var stopped = false;
var requestAnimationFrame_ = function () {
requestId = window.requestAnimationFrame(function () {
if (element.readyState === element.HAVE_ENOUGH_DATA) {
try {
// Firefox v~30.0 gets confused with the video readyState firing an
// erroneous HAVE_ENOUGH_DATA just before HAVE_CURRENT_DATA state,
// hence keep trying to read it until resolved.
context.drawImage(element, 0, 0, width, height);
} catch (err) { }
tracking.trackCanvasInternal_(canvas, tracker);
}
if (stopped !== true) {
requestAnimationFrame_();
}
});
};
var task = new tracking.TrackerTask(tracker);
task.on('stop', function () {
stopped = true;
window.cancelAnimationFrame(requestId);
});
task.on('run', function () {
stopped = false;
requestAnimationFrame_();
});
return task.run();
};
createApp(App).use(router).mount('#app')
<template>
<div class="wrapp">
<video id="myVideo" width="800" height="500" preload="preload" autoplay loop muted src="/other/video.mp4" />
<canvas ref="myCanvas" class="myCanvas" width="800" height="500"></canvas>
</div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
// 标识用的画布
const myCanvas = ref<HTMLCanvasElement | null>(null);
// 实例颜色检查器
const myTracker = new tracking.ColorTracker(['yellow']);
// 监听颜色检查器
myTracker.on('track', (event: tracking.TrackEvent) => {
const context = myCanvas.value?.getContext('2d') as CanvasRenderingContext2D;
if (myCanvas.value) {
context.clearRect(0, 0, myCanvas.value.width, myCanvas.value.height);
}
if (event.data.length === 0) {
console.log('没有捕获到内容');
} else {
event.data.forEach((rect: tracking.TrackRect) => {
const { x, y, width, height, color = 'red' } = rect;
context.strokeStyle = color;
context.strokeRect(x, y, width, height);
context.font = '11px Helvetica';
context.fillStyle = '#fff';
context.fillText(`x:${x}px`, x + width + 5, y + 11);
context.fillText(`y:${y}px`, x + width + 5, y + 22);
});
}
});
onMounted(() => {
// 触发颜色检查器
tracking.track('#myVideo', myTracker);
});
</script>
<style lang="less" scoped>
.wrapp {
position: relative;
.myCanvas {
position: absolute;
top: 0;
left: 0;
}
}
</style>
效果
补充
如果需要摄像头实时捕获,则出触发调用,option配置参数 这样即可
onMounted(() => {
// 触发颜色检查器
tracking.track('#myVideo', myTracker, { camera: true });
});