原文链接: vue websocket draw_board 客户端
上一篇: vue websocket draw_board flask
效果
展示页面
使用socketio实现客户端websocket
在连接成功后,将会受到服务端的数据,然后进行渲染
<template>
<div>
<h1>drawing board</h1>
<h2>-by 阿豪 & 魏刚林 & 琚智杰</h2>
<h1>display</h1>
<canvas class="cvs"
ref="cvs"
></canvas>
</div>
</template>
<script>
import io from 'socket.io-client';
import {HOST} from "../config";
const socket = io.connect(HOST);
const width = 500
const height = 500
export default {
name: "Display",
data() {
return {
mat: [],
cvs: null,
ctx: null,
}
},
watch: {
mat(oldVal, newVal) {
console.log('watch', oldVal.length, newVal.length)
this.ctx.clearRect(0, 0, width, height)
for (let [x, y] of this.mat) {
this.ctx.fillRect(x - 3, y - 3, 6, 6);
}
}
},
mounted() {
this.cvs = this.$refs.cvs
console.log(this.cvs.height, this.cvs.width)
this.cvs.height = height
this.cvs.width = width
console.log(this.cvs.height, this.cvs.width)
this.ctx = this.cvs.getContext('2d')
// socket.on('connect', () => {
// console.log('connect')
// })
// socket.emit('send_msg', {
// 'mat': [1, 2, 3],
// })
socket.on('get_msg', (data) => {
console.log('get msg', data)
this.mat = data['mat']
console.log(this.mat.length)
})
},
}
</script>
<style scoped>
.cvs {
height: 500px;
width: 500px;
box-sizing: border-box;
border: 1px solid black;
}
</style>
控制页面
移动端的手写实现,需要使用touch的位置,减去在目标上的偏移来得到真实的位置,否则得到的是具有偏移的位置,这个和pc端有点不同,需要额外处理
if (e.offsetX) {
p = [e.offsetX, e.offsetY]
} else {
// touch 事件
// 使用touch位置减去target的偏移得到实际的坐标
let left = e.target.offsetLeft
let top = e.target.offsetTop
let x = e.changedTouches[0].clientX
let y = e.changedTouches[0].clientY
p = [x - left, y - top]
}
<template>
<div>
<h1>drawing board</h1>
<h2>-by 阿豪 & 魏刚林 & 琚智杰</h2>
<h1>control</h1>
<canvas class="cvs"
ref="cvs"
@mousedown="isDraw=true"
@mouseup="isDraw=false"
@mousemove="draw"
></canvas>
</div>
</template>
<script>
import io from 'socket.io-client';
import {HOST} from "../config";
const socket = io.connect(HOST);
const width = 500
const height = 500
function detectZoom() {
var ratio = 0,
screen = window.screen,
ua = navigator.userAgent.toLowerCase();
if (window.devicePixelRatio !== undefined) {
ratio = window.devicePixelRatio;
} else if (~ua.indexOf('msie')) {
if (screen.deviceXDPI && screen.logicalXDPI) {
ratio = screen.deviceXDPI / screen.logicalXDPI;
}
} else if (window.outerWidth !== undefined && window.innerWidth !== undefined) {
ratio = window.outerWidth / window.innerWidth;
}
if (ratio) {
ratio = Math.round(ratio * 100);
}
return ratio;
};
export default {
name: "Control",
data() {
return {
isDraw: false,
cvs: null,
ctx: null,
mat: []
}
},
watch: {
mat(oldVal, newVal) {
console.log('watch', oldVal.length, newVal.length)
this.ctx.clearRect(0, 0, width, height)
for (let [x, y] of this.mat) {
this.ctx.fillRect(x - 3, y - 3, 6, 6);
}
this.send()
}
},
methods: {
send() {
socket.emit('send_msg', {
'mat': this.mat,
})
},
draw(e) {
let p
if (e.offsetX) {
p = [e.offsetX, e.offsetY]
} else {
// touch 事件
// 使用touch位置减去target的偏移得到实际的坐标
let left = e.target.offsetLeft
let top = e.target.offsetTop
let x = e.changedTouches[0].clientX
let y = e.changedTouches[0].clientY
p = [x - left, y - top]
}
console.log('draw', this.isDraw, p)
if (this.isDraw)
this.mat.push(p)
}
},
mounted() {
this.cvs = this.$refs.cvs
console.log(this.cvs.height, this.cvs.width)
this.cvs.height = height
this.cvs.width = width
console.log(this.cvs.height, this.cvs.width)
this.ctx = this.cvs.getContext('2d')
// socket.on('connect', (data) => {
// console.log('connect', data)
// })
//
// socket.on('get_msg', (data) => {
// console.log('get msg', data)
// this.mat = data['mat']
// console.log(this.mat.length)
// socket.on('get_msg', () => {
// })
// })
this.send()
let cvs = this.$refs['cvs']
console.log(cvs)
cvs.addEventListener('touchmove', (e) => {
console.log('touchmove', e)
this.draw(e)
})
cvs.addEventListener('touchstart', (e) => {
console.log('touchstart', e)
this.draw(e)
this.isDraw = true
})
cvs.addEventListener('touchend', (e) => {
console.log('touchend', e)
this.isDraw = false
this.draw(e)
})
// socket.emit('send_msg', {
// 'mat': [1, 2, 3],
// })
//
// socket.on('get_msg', (data) => {
// console.log('get msg', data)
// })
}
}
</script>
<style scoped>
.cvs {
height: 500px;
width: 500px;
box-sizing: border-box;
border: 1px solid black;
}
</style>