需求是在一个表格或者什么其他内容点击按钮 开始拍照,拍照需要有人的头像框,可拖动,方框选择的部位就是照片的位置。
拖拽的话 可以使用自定义指令
import Vue from 'vue'
Vue.directive("drag", { //指令的名称
inserted: function (el, binding) { //当被绑定的元素插入到 DOM 中时
el.onmousedown = function (e) {
var x = e.clientX - el.offsetLeft;
var y = e.clientY - el.offsetTop;
document.onmousemove = function (eve) {
el.style.left = eve.clientX - x + "px";
el.style.top = eve.clientY - y + "px";
}
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
})
具体vue代码的实现
<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"
@click="cameraBoxMove"
@keyup.up="cameraBoxMoveUp"
@keyup.down="cameraBoxMoveDown"
@keyup.left="cameraBoxMoveLeft"
@keyup.right="cameraBoxMoveRight"
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,
};
},
methods: {
/*调用摄像头拍照开始*/
onTake() {
this.visible = true;
this.getCompetence();
this.imgSrc = ''
},
/*关闭弹窗,以及关闭摄像头功能*/
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",
});
});
});
},
/* 蒙层鼠标拖动移动 */
cameraBoxMove() {
// console.log('1')
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)
this.dontOut()
},
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'
}
},
// cameraBoxMoveUp(){
// this.$refs.camerabox.style.top +10
// this.dontOut()
// },
// cameraBoxMoveDown(){
// this.$refs.camerabox.style.top --
// this.dontOut()
// },
// cameraBoxMoveLeft(){
// this.$refs.camerabox.style.left --
// this.dontOut()
// },
// cameraBoxMoveRight(){
// this.$refs.camerabox.style.left ++
// this.dontOut()
// },
//调用摄像头 --- 进行绘制图片
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> -->
后续还想通过键盘方向键控制蒙层的移动,还未实现!