markandface
This commit is contained in:
parent
ed4f99eea7
commit
fd76f31953
|
@ -25,6 +25,7 @@
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"path-to-regexp": "^6.2.0",
|
"path-to-regexp": "^6.2.0",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
|
"vue-json-editor": "^1.4.3",
|
||||||
"vue-router": "^3.5.2",
|
"vue-router": "^3.5.2",
|
||||||
"vuex": "^3.6.2",
|
"vuex": "^3.6.2",
|
||||||
"xlsx": "^0.17.1"
|
"xlsx": "^0.17.1"
|
||||||
|
|
|
@ -45,6 +45,11 @@ import Breadcrumb from '@/components/Breadcrumb'
|
||||||
import Hamburger from '@/components/Hamburger'
|
import Hamburger from '@/components/Hamburger'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
data(){
|
||||||
|
return{
|
||||||
|
name:''
|
||||||
|
}
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
Breadcrumb,
|
Breadcrumb,
|
||||||
Hamburger
|
Hamburger
|
||||||
|
|
|
@ -307,6 +307,27 @@ export const asyncRoutes = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/testModel',
|
||||||
|
component: Layout,
|
||||||
|
redirect: '/testModel/faceLogin/',
|
||||||
|
name: 'testModel',
|
||||||
|
meta: { title: '测试模块', icon: 'example' },
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: 'faceLogin',
|
||||||
|
name: 'faceLogin',
|
||||||
|
component: () => import('@/views/testModel/faceLogin'),
|
||||||
|
meta: { title: '人脸识别登录', icon: 'example' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'markImage',
|
||||||
|
name: 'markImage',
|
||||||
|
component: () => import('@/views/testModel/markImage'),
|
||||||
|
meta: { title: '图片标记', icon: 'example' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
// 404 page must be placed at the end !!!
|
// 404 page must be placed at the end !!!
|
||||||
{ path: '*', redirect: '/404', hidden: true }
|
{ path: '*', redirect: '/404', hidden: true }
|
||||||
]
|
]
|
||||||
|
|
|
@ -20,10 +20,10 @@
|
||||||
type="text"
|
type="text"
|
||||||
tabindex="1"
|
tabindex="1"
|
||||||
auto-complete="on"
|
auto-complete="on"
|
||||||
><svg-icon
|
><svg-icon
|
||||||
slot="prefix"
|
slot="prefix"
|
||||||
icon-class="user"
|
icon-class="user"
|
||||||
class="el-input__icon input-icon"
|
class="el-input__icon input-icon"
|
||||||
/></el-input>
|
/></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
|
@ -38,10 +38,10 @@
|
||||||
tabindex="2"
|
tabindex="2"
|
||||||
auto-complete="on"
|
auto-complete="on"
|
||||||
@keyup.enter.native="handleLogin"
|
@keyup.enter.native="handleLogin"
|
||||||
><svg-icon
|
><svg-icon
|
||||||
slot="prefix"
|
slot="prefix"
|
||||||
icon-class="password"
|
icon-class="password"
|
||||||
class="el-input__icon input-icon"
|
class="el-input__icon input-icon"
|
||||||
/></el-input>
|
/></el-input>
|
||||||
<span class="show-pwd" @click="showPwd">
|
<span class="show-pwd" @click="showPwd">
|
||||||
<svg-icon
|
<svg-icon
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
type="primary"
|
type="primary"
|
||||||
style="width: 100%; margin-bottom: 30px"
|
style="width: 100%; margin-bottom: 30px"
|
||||||
@click.native.prevent="handleLogin"
|
@click.native.prevent="handleLogin"
|
||||||
>登录</el-button
|
>登录</el-button
|
||||||
>
|
>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
|
@ -65,168 +65,168 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "Login",
|
name: "Login",
|
||||||
data() {
|
data() {
|
||||||
// const validateUsername = (rule, value, callback) => {
|
// const validateUsername = (rule, value, callback) => {
|
||||||
// if (!validUsername(value)) {
|
// if (!validUsername(value)) {
|
||||||
// callback(new Error('请输入正确账号!'))
|
// callback(new Error('请输入正确账号!'))
|
||||||
// } else {
|
// } else {
|
||||||
// callback()
|
// callback()
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
const validatePassword = (rule, value, callback) => {
|
const validatePassword = (rule, value, callback) => {
|
||||||
if (value.length < 4) {
|
if (value.length < 4) {
|
||||||
callback(new Error("密码长度小于4位!"));
|
callback(new Error("密码长度小于4位!"));
|
||||||
} else {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return {
|
|
||||||
timer: null,
|
|
||||||
buttonmsg: "发送验证码",
|
|
||||||
count: 60,
|
|
||||||
loginForm: {
|
|
||||||
username: "",
|
|
||||||
password: "",
|
|
||||||
},
|
|
||||||
loginRules: {
|
|
||||||
username: [{ required: true, trigger: "blur", message: "请输入账户" }],
|
|
||||||
password: [
|
|
||||||
{
|
|
||||||
required: true,
|
|
||||||
trigger: "blur",
|
|
||||||
validator: validatePassword,
|
|
||||||
message: "请输入密码",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
loading: false,
|
|
||||||
passwordType: "password",
|
|
||||||
redirect: undefined,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getUP();
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
$route: {
|
|
||||||
handler: function (route) {
|
|
||||||
this.redirect = route.query && route.query.redirect;
|
|
||||||
},
|
|
||||||
immediate: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
showPwd() {
|
|
||||||
if (this.passwordType === "password") {
|
|
||||||
this.passwordType = "";
|
|
||||||
} else {
|
|
||||||
this.passwordType = "password";
|
|
||||||
}
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.password.focus();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
handleLogin() {
|
|
||||||
this.$refs.loginForm.validate((valid) => {
|
|
||||||
if (valid) {
|
|
||||||
this.loading = true;
|
|
||||||
this.$store
|
|
||||||
.dispatch("user/login", this.loginForm)
|
|
||||||
.then(() => {
|
|
||||||
this.$router.push({ path: this.redirect || "/" });
|
|
||||||
this.loading = false;
|
|
||||||
localStorage.setItem("rem_username", this.loginForm.username);
|
|
||||||
localStorage.setItem("rem_password", this.loginForm.password);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
console.log("error submit!!");
|
callback();
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
},
|
return {
|
||||||
|
timer: null,
|
||||||
|
buttonmsg: "发送验证码",
|
||||||
|
count: 60,
|
||||||
|
loginForm: {
|
||||||
|
username: "",
|
||||||
|
password: "",
|
||||||
|
},
|
||||||
|
loginRules: {
|
||||||
|
username: [{ required: true, trigger: "blur", message: "请输入账户" }],
|
||||||
|
password: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
trigger: "blur",
|
||||||
|
validator: validatePassword,
|
||||||
|
message: "请输入密码",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
|
||||||
//读取cookie
|
|
||||||
getUP() {
|
|
||||||
|
|
||||||
this.loginForm.username = localStorage.getItem("rem_username");
|
loading: false,
|
||||||
this.loginForm.password = localStorage.getItem("rem_password");
|
passwordType: "password",
|
||||||
|
redirect: undefined,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
},
|
created() {
|
||||||
};
|
this.getUP();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route: {
|
||||||
|
handler: function (route) {
|
||||||
|
this.redirect = route.query && route.query.redirect;
|
||||||
|
},
|
||||||
|
immediate: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
showPwd() {
|
||||||
|
if (this.passwordType === "password") {
|
||||||
|
this.passwordType = "";
|
||||||
|
} else {
|
||||||
|
this.passwordType = "password";
|
||||||
|
}
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.password.focus();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleLogin() {
|
||||||
|
this.$refs.loginForm.validate((valid) => {
|
||||||
|
if (valid) {
|
||||||
|
this.loading = true;
|
||||||
|
this.$store
|
||||||
|
.dispatch("user/login", this.loginForm)
|
||||||
|
.then(() => {
|
||||||
|
this.$router.push({ path: this.redirect || "/" });
|
||||||
|
this.loading = false;
|
||||||
|
localStorage.setItem("rem_username", this.loginForm.username);
|
||||||
|
localStorage.setItem("rem_password", this.loginForm.password);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log("error submit!!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
//读取cookie
|
||||||
|
getUP() {
|
||||||
|
|
||||||
|
this.loginForm.username = localStorage.getItem("rem_username");
|
||||||
|
this.loginForm.password = localStorage.getItem("rem_password");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.login {
|
.login {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-image: url("../../assets/beijing.jpg");
|
background-image: url("../../assets/beijing.jpg");
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
}
|
}
|
||||||
.title {
|
.title {
|
||||||
margin: 30px auto 30px auto;
|
margin: 30px auto 30px auto;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #0174d7;
|
color: #0174d7;
|
||||||
}
|
}
|
||||||
.logo {
|
.logo {
|
||||||
width: 350px;
|
width: 350px;
|
||||||
height: 140px;
|
height: 140px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-form {
|
.login-form {
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
width: 400px;
|
width: 400px;
|
||||||
padding: 25px 25px 5px 25px;
|
padding: 25px 25px 5px 25px;
|
||||||
.el-input {
|
.el-input {
|
||||||
height: 45px;
|
|
||||||
input {
|
|
||||||
height: 45px;
|
height: 45px;
|
||||||
|
input {
|
||||||
|
height: 45px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.input-icon {
|
||||||
|
height: 39px;
|
||||||
|
width: 14px;
|
||||||
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.input-icon {
|
|
||||||
height: 39px;
|
|
||||||
width: 14px;
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.show-pwd {
|
.show-pwd {
|
||||||
height: 39px;
|
height: 39px;
|
||||||
margin-right: 2px;
|
margin-right: 2px;
|
||||||
}
|
}
|
||||||
.login-tip {
|
.login-tip {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #bfbfbf;
|
color: #bfbfbf;
|
||||||
}
|
}
|
||||||
.login-code {
|
.login-code {
|
||||||
width: 33%;
|
width: 33%;
|
||||||
height: 38px;
|
height: 38px;
|
||||||
float: right;
|
float: right;
|
||||||
img {
|
img {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.show-pwd {
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
top: 7px;
|
||||||
|
font-size: 16px;
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.login-code-img {
|
||||||
|
height: 38px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
.show-pwd {
|
|
||||||
position: absolute;
|
|
||||||
right: 10px;
|
|
||||||
top: 7px;
|
|
||||||
font-size: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
.login-code-img {
|
|
||||||
height: 38px;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
<template>
|
||||||
|
<div style="width: 100%;height: 100%;">
|
||||||
|
<div class="testTracking">
|
||||||
|
<canvas style="display:none;" id="myCanvas" ref="canvas" :width="videoWidth" :height="videoHeight"></canvas>
|
||||||
|
<!--图片展示-->
|
||||||
|
<video ref="video" id="myVideo" :width="videoWidth" :height="videoHeight" autoplay style="display: block;margin:0 auto;border: 2px solid #333333;"></video>
|
||||||
|
<!--确认-->
|
||||||
|
<Button type="primary" @click="setImage">拍照</Button>
|
||||||
|
<div id="res"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import "tracking/build/data/face-min.js";
|
||||||
|
import "tracking/build/data/mouth-min.js";
|
||||||
|
import "tracking/build/data/tracking-min.js";
|
||||||
|
import "tracking/examples/assets/stats.min.js";
|
||||||
|
import "tracking/examples/assets/stats.min.js";
|
||||||
|
export default {
|
||||||
|
props:['src'],
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
videoWidth: 900,
|
||||||
|
videoHeight: 700,
|
||||||
|
videoArr:[],//所有的摄像头
|
||||||
|
modelSel:'',//
|
||||||
|
myInterval: null,
|
||||||
|
imgSrc: '',
|
||||||
|
isHasFace:false,//默认没有人脸
|
||||||
|
tracker:null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created(){
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
// this.openUserMedia();
|
||||||
|
this.callCamera();
|
||||||
|
this.changePhoto();
|
||||||
|
// this.checkFace();
|
||||||
|
if(this.src!='user'){
|
||||||
|
// this.myInterval = setInterval(()=>{
|
||||||
|
// this.setImage();
|
||||||
|
// },2000)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 调用摄像头
|
||||||
|
callCamera () {
|
||||||
|
// H5调用电脑摄像头API
|
||||||
|
navigator.mediaDevices.getUserMedia({
|
||||||
|
video: true
|
||||||
|
}).then(success => {
|
||||||
|
// 摄像头开启成功
|
||||||
|
this.$refs['video'].srcObject = success;
|
||||||
|
// 实时拍照效果
|
||||||
|
this.$refs['video'].play()
|
||||||
|
}).catch(error => {
|
||||||
|
alert('摄像头开启失败,请检查摄像头是否可用!')
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 拍照
|
||||||
|
setImage () {
|
||||||
|
let canvas = document.getElementById("myCanvas");
|
||||||
|
let context = canvas.getContext('2d');
|
||||||
|
var video = document.getElementById("myVideo");
|
||||||
|
context.drawImage(video,0,0,this.videoWidth,this.videoHeight);
|
||||||
|
var image = new Image();
|
||||||
|
image = canvas.toDataURL('image/png');
|
||||||
|
document.getElementById('res').innerHTML = '<img style="border: 1px solid #666666;" src="'+image+'">';
|
||||||
|
},
|
||||||
|
// 关闭摄像头
|
||||||
|
closeCamera () {
|
||||||
|
if (!this.$refs['video'].srcObject) return;
|
||||||
|
let stream = this.$refs['video'].srcObject;
|
||||||
|
let tracks = stream.getTracks();
|
||||||
|
tracks.forEach(track => {
|
||||||
|
track.stop()
|
||||||
|
});
|
||||||
|
this.$refs['video'].srcObject = null
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
//切换本地摄像头
|
||||||
|
changePhoto(){
|
||||||
|
/**得到所有的设备*/
|
||||||
|
navigator.mediaDevices.enumerateDevices()
|
||||||
|
.then((devices)=> {
|
||||||
|
this.videoArr = [];
|
||||||
|
devices.forEach((item)=> {
|
||||||
|
if(item.kind == 'videoinput'){
|
||||||
|
this.videoArr.push({
|
||||||
|
'label': item.kind,
|
||||||
|
'id': item.deviceId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err=>{
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**打开摄像头*/
|
||||||
|
getUserMedia(constraints, success, error) {
|
||||||
|
if (navigator.mediaDevices.getUserMedia) {
|
||||||
|
//最新的标准API
|
||||||
|
navigator.mediaDevices.getUserMedia(constraints).then(success=>{
|
||||||
|
// 摄像头开启成功
|
||||||
|
this.$refs['video'].srcObject = success
|
||||||
|
// 实时拍照效果
|
||||||
|
this.$refs['video'].play()
|
||||||
|
}).catch(error);
|
||||||
|
|
||||||
|
} else if (navigator.webkitGetUserMedia) {
|
||||||
|
//webkit核心浏览器
|
||||||
|
navigator.webkitGetUserMedia(constraints,success, error)
|
||||||
|
} else if (navigator.mozGetUserMedia) {
|
||||||
|
//firfox浏览器
|
||||||
|
navigator.mozGetUserMedia(constraints, success, error);
|
||||||
|
} else if (navigator.getUserMedia) {
|
||||||
|
//旧版API
|
||||||
|
navigator.getUserMedia(constraints, success, error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查取景框是否有人脸
|
||||||
|
* */
|
||||||
|
checkFace() {
|
||||||
|
// var video = document.getElementById("video");
|
||||||
|
let canvas = document.getElementById("myCanvas");
|
||||||
|
let context = canvas.getContext('2d');
|
||||||
|
this.tracker = new tracking.ObjectTracker("face");
|
||||||
|
this.tracker.setInitialScale(4);
|
||||||
|
this.tracker.setStepSize(2);
|
||||||
|
this.tracker.setEdgesDensity(0.1);
|
||||||
|
this.trackerTask = tracking.track("#video", this.tracker, { camera: true });
|
||||||
|
let self = this;
|
||||||
|
this.tracker.on("track", event=> {
|
||||||
|
if (event.data.length <= 0) {
|
||||||
|
self.setFace(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.setFace(true);
|
||||||
|
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||||
|
event.data.forEach(function (rect) {
|
||||||
|
context.strokeStyle = '#a64ceb';
|
||||||
|
context.strokeRect(rect.x, rect.y, rect.width, rect.height);
|
||||||
|
context.font = '11px Helvetica';
|
||||||
|
context.fillStyle = "#fff";
|
||||||
|
context.fillText('x: ' + rect.x + 'px', rect.x + rect.width + 5, rect.y + 11);
|
||||||
|
context.fillText('y: ' + rect.y + 'px', rect.x + rect.width + 5, rect.y + 22);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setFace(data){
|
||||||
|
this.isHasFace = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy () {
|
||||||
|
clearInterval(this.myInterval);
|
||||||
|
// 停止侦测
|
||||||
|
// this.trackerTask.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.testTracking {
|
||||||
|
min-height: 700px;
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.buttonDiv {
|
||||||
|
bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -0,0 +1,259 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<button type="button" class="btn btn-warning" @click="error1">错误</button>
|
||||||
|
<button @click="word1()">文字</button>
|
||||||
|
<button @click="restuya()">清除批注</button>
|
||||||
|
<button @click="back()">回退</button>
|
||||||
|
<button @click="saveTu()">保存</button>
|
||||||
|
<hr>
|
||||||
|
<!--<img src="./../../assets/404_images/404.png">-->
|
||||||
|
<div style="position: relative;">
|
||||||
|
<canvas id="canvas" width="700" height="500" >
|
||||||
|
您的浏览器不支持绘图,请升级或更换浏览器!
|
||||||
|
</canvas>
|
||||||
|
<input type="text" value="" class="hide" id="txt" placeholder="请输入文字">
|
||||||
|
<textarea class="hide" id="word" cols="30" rows="10" placeholder="请输入文字" autofocus></textarea>
|
||||||
|
<input id="inputV" type="hidden" value="1">
|
||||||
|
<span>保存的图片</span>
|
||||||
|
<div id="res"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
let preDrawAry = [];
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
canvas:null,
|
||||||
|
ctx:null,
|
||||||
|
myCanvas_rect:null,
|
||||||
|
Txt:null,
|
||||||
|
word:null,
|
||||||
|
widths:0,
|
||||||
|
heights:0,
|
||||||
|
lineW:3,
|
||||||
|
colorF:"#e42343",
|
||||||
|
imgData:'',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted(){
|
||||||
|
this.canvas = document.getElementById('canvas');
|
||||||
|
this.ctx = this.canvas.getContext('2d');
|
||||||
|
this.myCanvas_rect = this.canvas.getBoundingClientRect();
|
||||||
|
this.Txt = document.getElementById('txt');
|
||||||
|
this.word = document.getElementById('word');
|
||||||
|
this.widths = this.myCanvas_rect.width;
|
||||||
|
this.heights = this.myCanvas_rect.height;
|
||||||
|
let imgs = new Image();
|
||||||
|
imgs.src = "./../../assets/404_images/404.png";
|
||||||
|
this.ctx.drawImage(imgs,0,0,this.widths,this.heights);
|
||||||
|
preDrawAry = [];
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 叉号
|
||||||
|
error1(){
|
||||||
|
let canvas1 = document.getElementById('canvas');
|
||||||
|
let ctx1 = canvas1.getContext('2d');
|
||||||
|
this.Txt.style.display="none";
|
||||||
|
this.word.style.display="none";
|
||||||
|
ctx1.closePath();
|
||||||
|
this.canvas.onmousedown=function () {
|
||||||
|
this.imgData= ctx1.getImageData(0,0,canvas1.width,canvas1.height);
|
||||||
|
preDrawAry.push(this.imgData);
|
||||||
|
ctx1.beginPath();
|
||||||
|
ctx1.strokeStyle = "#e42343";
|
||||||
|
ctx1.lineWidth = "3";
|
||||||
|
ctx1.lineJoin="round";
|
||||||
|
};
|
||||||
|
//鼠标按下的位置
|
||||||
|
this.canvas.onmouseup=function (ev) {
|
||||||
|
let oldX = ev.offsetX;
|
||||||
|
let oldY = ev.offsetY;
|
||||||
|
ctx1.moveTo(oldX,oldY);
|
||||||
|
ctx1.lineTo(ev.offsetX+10,ev.offsetY+10);
|
||||||
|
ctx1.moveTo(ev.offsetX+10,ev.offsetY);
|
||||||
|
ctx1.lineTo(ev.offsetX,ev.offsetY+10);
|
||||||
|
ctx1.stroke();
|
||||||
|
};
|
||||||
|
this.ctx.closePath();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 文字先写字
|
||||||
|
text(){
|
||||||
|
let canvas2 = document.getElementById('canvas');
|
||||||
|
let ctx2 = canvas2.getContext('2d');
|
||||||
|
let Txt2 = document.getElementById('txt');
|
||||||
|
Txt2.style.display="block";
|
||||||
|
this.word.style.display="none";
|
||||||
|
ctx2.font="16px Microsoft Yahei";
|
||||||
|
canvas2.onmousedown=function (ev) {
|
||||||
|
this.imgData=ctx2.getImageData(0,0,canvas2.width,canvas2.height);
|
||||||
|
preDrawAry.push(this.imgData);
|
||||||
|
var v = Txt2.value;
|
||||||
|
// console.log(v);
|
||||||
|
if (v != '') {
|
||||||
|
var oldX = ev.offsetX;
|
||||||
|
var oldY = ev.offsetY;
|
||||||
|
// console.log(oldX,oldY);
|
||||||
|
ctx2.moveTo(oldX,oldY);
|
||||||
|
canvas2.onmouseup=function () {
|
||||||
|
ctx2.fillStyle=this.colorF;
|
||||||
|
ctx2.fillText(v,oldX,oldY);
|
||||||
|
canvas2.TextAutoLine(v,canvas2,oldX,oldY,20);
|
||||||
|
// Txt.value = "";
|
||||||
|
Txt2.style.display="none";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 文字
|
||||||
|
word1(){
|
||||||
|
let canvas3 = document.getElementById('canvas');
|
||||||
|
let ctx3 = canvas3.getContext('2d');
|
||||||
|
let Txt3 = document.getElementById('txt');
|
||||||
|
let word3 = document.getElementById('word');
|
||||||
|
Txt3.style.display="none";
|
||||||
|
ctx3.font="16px Microsoft Yahei";
|
||||||
|
canvas3.onmousedown=function () {
|
||||||
|
ctx3.closePath();
|
||||||
|
}
|
||||||
|
canvas3.onmouseup=function (ev) {
|
||||||
|
var inputV= document.getElementById('inputV').value;
|
||||||
|
if(inputV == 1){
|
||||||
|
document.getElementById('word').focus();
|
||||||
|
// console.log(ev.offsetX,ev.offsetY);
|
||||||
|
var oldX = ev.offsetX;
|
||||||
|
var oldY = ev.offsetY;
|
||||||
|
word3.style.display="block";
|
||||||
|
word3.style.left=oldX+'px';
|
||||||
|
word3.style.top =oldY+'px';
|
||||||
|
|
||||||
|
word3.onblur=function () {
|
||||||
|
let v = word3.value;
|
||||||
|
if(v != '' && v != ' '){
|
||||||
|
this.imgData=ctx3.getImageData(0,0,canvas3.width,canvas3.height);
|
||||||
|
let img = ctx3.getImageData(0,0,canvas3.width,canvas3.height);
|
||||||
|
debugger;
|
||||||
|
preDrawAry.push(img);
|
||||||
|
ctx3.moveTo(oldX,oldY);
|
||||||
|
ctx3.fillStyle="#e42343";
|
||||||
|
// ctx3.fillText(v,oldX,oldY+10);
|
||||||
|
// this.canvasTextAutoLine(v,canvas3,oldX,oldY,20);
|
||||||
|
|
||||||
|
let lineWidth = 0;
|
||||||
|
let canvasWidth = canvas3.width;
|
||||||
|
let lastSubStrIndex= 0;
|
||||||
|
for(let i=0;i<v.length;i++){
|
||||||
|
lineWidth+=ctx3.measureText(v[i]).width;
|
||||||
|
if(lineWidth>canvasWidth-oldX){
|
||||||
|
ctx3.fillText(v.substring(lastSubStrIndex,i),oldX,oldY);
|
||||||
|
oldY+=20;
|
||||||
|
lineWidth=0;
|
||||||
|
lastSubStrIndex=i;
|
||||||
|
}
|
||||||
|
if(i==v.length-1){
|
||||||
|
ctx3.fillText(v.substring(lastSubStrIndex,i+1),oldX,oldY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inputV ="2";
|
||||||
|
word3.value = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 文字过长超出换行toDataURL()
|
||||||
|
canvasTextAutoLine(str,canvas,initX,initY,lineHeight){
|
||||||
|
let ctx = canvas.getContext("2d");
|
||||||
|
let lineWidth = 0;
|
||||||
|
let canvasWidth = canvas.width;
|
||||||
|
let lastSubStrIndex= 0;
|
||||||
|
for(let i=0;i<str.length;i++){
|
||||||
|
lineWidth+=ctx.measureText(str[i]).width;
|
||||||
|
if(lineWidth>canvasWidth-initX){
|
||||||
|
ctx.fillText(str.substring(lastSubStrIndex,i),initX,initY);
|
||||||
|
initY+=lineHeight;
|
||||||
|
lineWidth=0;
|
||||||
|
lastSubStrIndex=i;
|
||||||
|
}
|
||||||
|
if(i==str.length-1){
|
||||||
|
ctx.fillText(str.substring(lastSubStrIndex,i+1),initX,initY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除批注
|
||||||
|
restuya(){
|
||||||
|
this.word.style.display="none";
|
||||||
|
this.Txt.style.display="none";
|
||||||
|
this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
|
||||||
|
window.location.reload();
|
||||||
|
},
|
||||||
|
|
||||||
|
// 撤销
|
||||||
|
back(){
|
||||||
|
this.word.style.display="none";
|
||||||
|
this.Txt.style.display="none";
|
||||||
|
if(preDrawAry.length>0) {
|
||||||
|
// console.log(this.preDrawAry)
|
||||||
|
var popData = preDrawAry.pop();
|
||||||
|
this.ctx.putImageData(popData, 0, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 回退一次
|
||||||
|
put(){
|
||||||
|
this.ctx.putImageData(this.imgData,0,0);
|
||||||
|
},
|
||||||
|
|
||||||
|
//保存
|
||||||
|
saveTu(){
|
||||||
|
var image = new Image();
|
||||||
|
image = this.canvas.toDataURL('image/png');
|
||||||
|
document.getElementById('res').innerHTML = '<img style="border: 1px solid #666666;" src="'+image+'">';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
canvas{
|
||||||
|
border:1px solid #000000;
|
||||||
|
cursor: crosshair;
|
||||||
|
}
|
||||||
|
.hide{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#txt{
|
||||||
|
position: absolute;
|
||||||
|
top: 1%;
|
||||||
|
left: 1%;
|
||||||
|
width: 575px;
|
||||||
|
height: 30px;
|
||||||
|
border:1px solid #e42343;
|
||||||
|
}
|
||||||
|
#word{
|
||||||
|
position: absolute;
|
||||||
|
width: 220px;
|
||||||
|
height: 80px;
|
||||||
|
padding: 0 2px;
|
||||||
|
background:none;
|
||||||
|
color:#e42343;
|
||||||
|
border: 1px dashed #b9b9b9;
|
||||||
|
}
|
||||||
|
#word::-webkit-input-placeholder{
|
||||||
|
color:#e42343;
|
||||||
|
}
|
||||||
|
#word::-moz-placeholder{
|
||||||
|
color:#e42343;
|
||||||
|
}
|
||||||
|
#word::placeholder{
|
||||||
|
color:#e42343;
|
||||||
|
}
|
||||||
|
#res{
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
Loading…
Reference in New Issue