前言

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 });
});

一、trackingjs初体验-颜色捕获 vue3的更多相关文章

  1. Xamarin.iOS开发初体验

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0

  2. 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验

    在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...

  3. 百度EChart3初体验

    由于项目需要在首页搞一个订单数量的走势图,经过多方查找,体验,感觉ECharts不错,封装的很细,我们只需要看自己需要那种类型的图表,搞定好自己的json数据就OK.至于说如何体现出来,官网的教程很详 ...

  4. Java8初体验(二)Stream语法详解

    感谢同事[天锦]的投稿.投稿请联系 tengfei@ifeve.com 上篇文章Java8初体验(一)lambda表达式语法比 较详细的介绍了lambda表达式的方方面面,细心的读者会发现那篇文章的例 ...

  5. iOS AR技术初体验,使用EasyAR示例程序的小白指南

    QQ前两天的传递火炬,是我第一次直接接触到AR.(虽然之前听同事说过,因为他喜欢玩游戏,PS.3DS等等都玩过,这个技术最开始就是从这里出现的).所以感觉很有趣,就想自己也试着搞一下玩玩...下面是我 ...

  6. Microsoft IoT Starter Kit 开发初体验-反馈控制与数据存储

    在上一篇文章<Microsoft IoT Starter Kit 开发初体验>中,讲述了微软中国发布的Microsoft IoT Starter Kit所包含的硬件介绍.开发环境搭建.硬件 ...

  7. PHP初体验

    PHP初体验 提笔写初体验总不知道从何说起,直接聊PHP中的函数.PHP网络技术.数据库操作.PHP模板等感觉又不是初体验.最后还是决定从PHP的面向对象.PHP的魔术方法.PHP的反射.PHP中的异 ...

  8. Swift与C++混编 OpenCV初体验 图片打码~

    OpenCV初体验,给图片打码 提到OpenCV,相信大多数人都听说过,应用领域非常广泛,使用C++开发,天生具有跨平台的优势,我们学习一次,就可以在各个平台使用,这个还是很具有诱惑力的.本文主要记录 ...

  9. 数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)

    数据结构(逻辑结构,物理结构,特点) 一.数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关.逻辑结构包括: 集合 数 ...

  10. SASS初体验

    SASS初体验 标签(空格分隔): sass scss css 1. 编译环境 需要安装Ruby,之后需要打开Start Command Prompt with Ruby运行 gem install ...

随机推荐

  1. rabbitmq分布式事务

    Rabbitmq解决分布式事务的原理:可靠消息最终一致性方案 需要保证以下三要素 1.确认生成者一定要将消息可靠投递到MQ[采用MQ的异步confirm消息确认机制] public interface ...

  2. 🎀Charles激活

    简介 Charles激活码计算 激活 Help -> Register Charles 添加 Registered Name 和计算出的 License key 点击 Register Java ...

  3. jmeter使用json断言校验返回结果

    jmeter断言有好几种方式,本案讲json断言 http请求返回数据的格式有json格式,如下图,比如需要验证"ShipperRealName"参数的值 步骤如下: 第一步,选中 ...

  4. WPF 解决PasswordBox 属性Password无法绑定到后台的问题

    在 WPF 中,你可以使用密码框的 Password 属性来绑定到后台,但是由于安全性考虑,WPF 的密码框不直接支持双向绑定.然而,你仍然可以通过其他方式实现将密码框的内容绑定到后台. 一种常见的方 ...

  5. 一些软件、jar包下载链接、方法

    目录 jar包下载 dbutils C3P0 软件下载 TeamViewer 远程桌面 EV录屏 SublimeText 编辑器 feiQ 通信 文件共享 jdk 8u171 下载 jar包下载 db ...

  6. Form验证实例

    程序目录 models.py from django.db import models# Create your models here.class UserInfo(models.Model):   ...

  7. RocketMQ源码详解(消息存储、Consumer)

    消息存储 消息存储核心类 private final MessageStoreConfig messageStoreConfig; //消息配置属性 private final CommitLog c ...

  8. Reverse Integer——LeetCode进阶路⑦

    原题链接https://leetcode.com/problems/reverse-integer/ 题目描述 Given a 32-bit signed integer, reverse digit ...

  9. 深度系统deepin/uos动态壁纸

    深度系统deepin下使用动态壁纸 演示视频: https://www.bilibili.com/video/BV1bB4y1c7Fq 最新版本(2022/2/9): uos版本 : https:// ...

  10. DOS命令快速启动和关闭MySQL服务

    为了搭建网格服务框架,在本地创建了MySQL数据库,但是,为了减少内存占用,MySQL数据库服务没有设置为自动启动,所以,需要手动的开启和关闭服务.因此,需要掌握一些短小精悍的DOS命令,下面介绍启动 ...