继续昨天的代码更新一下
需求是: vue2 主页面是一个表格,存在按钮点击进行调取摄像头拍照,拍照呢要有头像的取景框,鼠标可移动,键盘通过方向键也可移动,调整了昨天的代码存在的问题,拖动会拍照一部分外面的内容,
今天,疑惑点在获取更新后的节点,及怎么设置键盘事件监听的方法上。
忘记使用 updated 里获取更新后的dom 做监听 通过$nexttick去获取;
忘记使用原生 js 做事件监听,
目前还未完成,下一步需要做的是键盘操作dom移动。
cv的太多,稍微创新一点的需求就做的好慢啊,加油自己!!
回顾一下dom操作的跳转
文章来源:https://www.toymoban.com/news/detail-800711.html
取景框如图:也可下载获取。
vue代码如下:文章来源地址https://www.toymoban.com/news/detail-800711.html
<template>
<div>
<!--开启摄像头的弹窗-->
<div
class="info2"
@click="onTake"
style="width: 200px; height: 200px; border: 1px solid skyblue"
>
<el-image v-if="url" :src="url"></el-image>
<div v-if="!url" style="line-height: 200px; text-align: center">
暂无图片
</div>
</div>
<!--开启摄像头的拍照和-->
<el-dialog
title="拍照上传"
:visible.sync="visible"
@close="onCancel1"
width="1065px"
>
<div class="box">
<!-- 蒙层 -->
<div
id="camerabox"
ref="camerabox"
@keydown="handleKeyDown()"
@click="cameraBoxMove"
v-drag
></div>
<video
id="videoCamera"
class="canvas"
:width="videoWidth"
:height="videoHeight"
autoPlay
></video>
<canvas
id="canvasCamera"
class="canvas"
:width="videoWidth"
:height="videoHeight"
></canvas>
</div>
<div slot="footer">
<el-button @click="drawImage" icon="el-icon-camera" size="small">
拍照
</el-button>
<el-button
v-if="os"
@click="getCompetence"
icon="el-icon-video-camera"
size="small"
>
打开摄像头
</el-button>
<el-button
v-else
@click="stopNavigator"
icon="el-icon-switch-button"
size="small"
>
关闭摄像头
</el-button>
<el-button @click="resetCanvas" icon="el-icon-refresh" size="small">
重置
</el-button>
<el-button @click="onCancel" icon="el-icon-circle-close" size="small">
完成
</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import "@/utils/drage.js";
export default {
name: "photo",
//对参数进行设置
data() {
return {
url: "", // 上传的图片的地址
visible: false, //弹窗
videoWidth: 1024, // 绘画布的宽高
videoHeight: 700,
os: false, //控制摄像头开关
thisCancas: null,
thisContext: null,
thisVideo: null,
imgSrc: undefined,
imgFile: null,
top: null,
left: null,
};
},
updated() {
this.handleKeyDown(Event)
},
methods: {
/*调用摄像头拍照开始*/
onTake() {
this.visible = true;
this.getCompetence();
this.imgSrc = "";
},
handleKeyDown(event) {
this.getTopLeft()
this.$nextTick(() => {
const _this = this;
let MC = _this.$refs.camerabox;
// console.log(' this',MC)
document.addEventListener('keydown',function(e){
// console.log(e.key)
if(e.key === 'ArrowLeft' ) { // ←
console.log('←', MC)
this.left - 5
}
if(e.key === 'ArrowRight' ) { // ←
console.log('→', )
this.left + 5
}
if(e.key === 'ArrowUp' ) { // ←
console.log('↑', )
this.top - 5
}
if(e.key === 'ArrowDown' ) { // ←
console.log('↓', )
this.top + 5
}
})
})
},
/*关闭弹窗,以及关闭摄像头功能*/
onCancel1() {
this.visible = false;
this.stopNavigator(); // 关闭摄像头
},
// 调用摄像头权限
getCompetence() {
//必须在model中render后才可获取到dom节点,直接获取无法获取到model中的dom节点
this.$nextTick(() => {
const _this = this;
this.os = false; //切换成关闭摄像头
// 获取画布节点
this.thisCancas = document.getElementById("canvasCamera");
// 为画布指定绘画为2d类型
this.thisContext = this.thisCancas.getContext("2d");
//获取video节点
this.thisVideo = document.getElementById("videoCamera");
// 旧版本浏览器可能根本不支持mediaDevices,我们首先设置一个空对象
if (navigator.mediaDevices === undefined) {
navigator.menavigatordiaDevices = {};
}
// 一些浏览器实现了部分mediaDevices,我们不能只分配一个对象
// 使用getUserMedia,因为它会覆盖现有的属性。
// 这里,如果缺少getUserMedia属性,就添加它。
if (navigator.mediaDevices.getUserMedia === undefined) {
navigator.mediaDevices.getUserMedia = function (constraints) {
// 首先获取现存的getUserMedia(如果存在)
let getUserMedia =
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.getUserMedia;
// 有些浏览器不支持,会返回错误信息
// 保持接口一致
if (!getUserMedia) {
return Promise.reject(
new Error("getUserMedia is not implemented in this browser")
);
}
// 否则,使用Promise将调用包装到旧的navigator.getUserMedia
return new Promise(function (resolve, reject) {
getUserMedia.call(navigator, constraints, resolve, reject);
});
};
}
const constraints = {
audio: false,
video: {
width: _this.videoWidth,
height: _this.videoHeight,
transform: "scaleX(-1)",
},
};
navigator.mediaDevices
.getUserMedia(constraints)
.then(function (stream) {
// 旧的浏览器可能没有srcObject
if ("srcObject" in _this.thisVideo) {
_this.thisVideo.srcObject = stream;
} else {
// 避免在新的浏览器中使用它,因为它正在被弃用。
_this.thisVideo.src = window.URL.createObjectURL(stream);
}
_this.thisVideo.onloadedmetadata = function (e) {
_this.thisVideo.play();
};
})
.catch((err) => {
this.$notify({
title: "警告",
message: "没有开启摄像头权限或浏览器版本不兼容.",
type: "warning",
});
});
});
// this.cameraBoxMoveKey()
},
/* 蒙层鼠标拖动移动 */
cameraBoxMove() {
this.getTopLeft();
this.dontOut();
},
getTopLeft(){
let reg = new RegExp("px", "g");
this.top = this.$refs.camerabox.style.top.replace(reg, "");
this.left = this.$refs.camerabox.style.left.replace(reg, "");
console.log(this.top, this.left);
},
cameraBoxMoveKey() {
let dd = window.document.getElementById("camerabox");
console.log("dd", dd);
},
/* 不让出区域 */
dontOut() {
if (this.top < 0) {
this.$refs.camerabox.style.top = "0px";
}
if (this.left < 0) {
this.$refs.camerabox.style.left = "0px";
}
if (this.left > 712) {
this.$refs.camerabox.style.left = "712px";
}
if (this.top > 277) {
this.$refs.camerabox.style.top = "277px";
}
this.getTopLeft();
},
//调用摄像头 --- 进行绘制图片
drawImage() {
// this.getMousePoint()
let dw = this.$refs.camerabox.clientWidth;
let dh = this.$refs.camerabox.clientHeight;
// 点击,canvas画图
this.thisContext.drawImage(
this.thisVideo,
this.left, // 设置 为鼠标的起点x
this.top, // 设置 为鼠标的起点x
314,
420,
0, // 这个坐标 0
0, // 这个坐标 0
dw, // 拍片的宽
dh // 拍片的高
);
// 获取图片base64链接
this.imgSrc = this.thisCancas.toDataURL("image/png");
},
//清空画布
clearCanvas(id) {
let c = document.getElementById(id);
let cxt = c.getContext("2d");
cxt.clearRect(0, 0, c.width, c.height);
},
//重置画布
resetCanvas() {
// this.imgSrc = "";
this.clearCanvas("canvasCamera");
},
//关闭摄像头
stopNavigator() {
if (this.thisVideo && this.thisVideo !== null) {
this.thisVideo.srcObject.getTracks()[0].stop();
this.os = true; //切换成打开摄像头
}
},
/*调用摄像头拍照结束*/
/*完成拍照并对其照片进行上传*/
onCancel() {
if (!this.imgSrc) {
alert("请点击拍照,确认照片后才能完成!");
return false;
}
this.visible = false;
this.stopNavigator();
/* this.resetCanvas();*/
// console.log(this.imgSrc);
this.imgFile = this.dataURLtoFile(this.imgSrc, new Date() + ".png");
console.log(this.imgFile);
// let par = {
// photo: this.imgFile,
// };
let data = new FormData();
data.append("photo", this.imgFile); //1是图片,2是视频
// data.append("code", this.addForm.code);
console.log(data);
// checkbeforepersonalphoto上传图片的接口
// checkbeforepersonalphoto(data).then(res => {
// if (res.code == "1") {
// this.$message({
// message: "上传成功",
// type: "success"
// });
// this.url = res.data;
// }
// });
},
dataURLtoFile(dataurl, filename) {
var arr = dataurl.split(",");
var mime = arr[0].match(/:(.*?);/)[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
},
},
};
</script>
<style scoped>
.box {
position: relative;
}
#camerabox {
width: 310px;
height: 419px;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
border: 2px solid skyblue;
position: absolute;
background: url(../../public/selectImage.png);
background-repeat: no-repeat;
z-index: 9999;
}
</style>
<!-- <style lang="scss" scoped>
.info2 {
width: 10%;
height: 100px;
}
.box {
display:flex;
}
</style> -->
到了这里,关于vue 2.0需求拍摄证件照(需要设置人头取景框,鼠标也拖拽,键盘方向键可调整位置)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!