事件区分
pc端:
- onmousedown
- onmousemove
- onmouseup
- onmousewheel
mobile端:
- ontouchstart
- ontouchmove
- ontouchend
- 没有wheel函数,要通过touch的手指数目和趋势去做区分
代码
项目集合成vue框架中了
<template>
<div class="box">
<canvas ref="mapCanvas" :width="canvasWidth" :height="canvasHeight" style="border: red solid 1px; margin: 10px" />
<div style="color: #fff; font-size: 22px;text-align:left">其他信息:{{ posStr }}</div>
</div>
</template>
<script>
export default {
name: 'Map',
data() {
return {
canvasWidth: document.body.clientWidth - 20, // 画布大小
canvasHeight: document.body.clientHeight - 200,
myCanvas: null,
ctx: null,
imgX: -300, // 图片在画布中渲染的起点x坐标
imgY: -50,
MINIMUM_SCALE: 0.2,
imgScale: 0.6, // 图片启示的缩放大小
extraImg: { url: require('../../assets/map.png') },
loadImgObj: null,
img: null,
flag: false,
pos: {},
posl: {},
flagPC: true,
posStr: ''
}
},
watch: {
},
mounted() {
this.flagPC = this.IsPC()
this.myCanvas = this.$refs.mapCanvas
this.ctx = this.myCanvas.getContext('2d')
this.loadImg()
this.canvasEventsInit()
// 定位
if (navigator.geolocation) {
navigator.geolocation.watchPosition((position) => {
var lat = position.coords.latitude
var lng = position.coords.longitude
this.posStr = '维度:' + lat + ', 经度:' + lng
})
}
},
destroyed() {
},
methods: {
loadImg() {
this.img = new Image()
this.img.src = this.extraImg.url
const that = this
this.img.onload = function() {
that.drawImage()
}
},
drawImage() {
const ctx = this.ctx
ctx.clearRect(0, 0, this.myCanvas.width, this.myCanvas.height)
ctx.drawImage(
this.img, // 规定要使用的图像、画布或视频。
0, 0, // 开始剪切的 x 坐标位置。
this.img.width, this.img.height, // 被剪切图像的高度。
this.imgX, this.imgY, // 在画布上放置图像的 x 、y坐标位置。
this.img.width * this.imgScale, this.img.height * this.imgScale // 要使用的图像的宽度、高度
)
// 放置中心点
ctx.beginPath()
ctx.arc(this.canvasWidth / 2 - 20, this.canvasHeight / 2 - 20, 20, Math.PI * 2, 0, true)
ctx.fillStyle = 'green'
ctx.fill()
ctx.fillStyle = '#fff' // 设置填充颜色为紫色
ctx.font = '20px "微软雅黑"' // 设置字体
ctx.textBaseline = 'middle' // 设置字体底线对齐绘制基线
ctx.textAlign = 'center'
ctx.fillText('我', this.canvasWidth / 2 - 20, this.canvasHeight / 2 - 20)
ctx.closePath()
},
canvasEventsInit() {
// eslint-disable-next-line no-unused-vars
let pageX, pageY, initX, initY
var start = []
const canvas = this.myCanvas
const that = this
if (this.flagPC) {
// PC
// 使用mouse事件
} else {
// Phone
canvas.ontouchstart = function(event) {
that.flag = true
if (event.touches && event.touches.length < 2) {
const touch = event.touches[0]
that.pos = that.windowToCanvas(touch.clientX, touch.clientY) // 坐标转换,将窗口坐标转换成canvas的坐标
} else {
const touches = event.touches
// 手指按下时的手指所在的X,Y坐标
pageX = touches[0].pageX
pageY = touches[0].pageY
// 初始位置的X,Y 坐标
initX = event.target.offsetLeft
initY = event.target.offsetTop
// 记录初始 一组数据 作为缩放使用
if (touches.length >= 2) { // 判断是否有两个点在屏幕上
start = touches // 得到第一组两个点
}
}
}
canvas.ontouchmove = function(evt) {
if (that.flag) {
if (evt.touches && evt.touches.length < 2) { // 移动
// console.log(evt)
const touch = evt.touches[0]
that.posl = that.windowToCanvas(touch.clientX, touch.clientY)
var x = that.posl.x - that.pos.x; var y = that.posl.y - that.pos.y
that.imgX += x
that.imgY += y
that.pos = JSON.parse(JSON.stringify(that.posl))
} else { // 缩放
event.preventDefault() // 禁止缩放
const touches = evt.touches
// 2 根 手指执行 目标元素放大操作
// 得到第二组两个点
var now = touches
var pos = that.windowToCanvas(now[0].clientX, now[0].clientY)
var newPos = {
x: ((pos.x - that.imgX) / that.imgScale).toFixed(2),
y: ((pos.y - that.imgY) / that.imgScale).toFixed(2)
}
// 当前距离变小, getDistance 是勾股定理的一个方法
if (that.getDistance(now[0], now[1]) < that.getDistance(start[0], start[1])) {
// 缩小
that.imgScale -= 0.03
if (that.imgScale < that.MINIMUM_SCALE) { // 最小缩放1
that.imgScale = that.MINIMUM_SCALE
}
that.imgX = (1 - that.imgScale) * newPos.x + (pos.x - newPos.x)
that.imgY = (1 - that.imgScale) * newPos.y + (pos.y - newPos.y)
// console.log(that.imgX,that.imgY);
} else if (that.getDistance(now[0], now[1]) > that.getDistance(start[0], start[1])) {
// 放大
if (that.imgScale < 1) {
that.imgScale += 0.03
that.imgX = (1 - that.imgScale) * newPos.x + (pos.x - newPos.x)
that.imgY = (1 - that.imgScale) * newPos.y + (pos.y - newPos.y)
}
}
start = now
}
that.drawImage() // 重新绘制图片
}
}
canvas.ontouchend = function() {
that.flag = false
}
}
},
/* 坐标转换*/
windowToCanvas(x, y) {
var box = this.myCanvas.getBoundingClientRect() // 这个方法返回一个矩形对象,包含四个属性:left、top、right和bottom。分别表示元素各边与页面上边和左边的距离
return {
x: x - box.left - (box.width - this.myCanvas.width) / 2,
y: y - box.top - (box.height - this.myCanvas.height) / 2
}
},
// 缩放 勾股定理方法-求两点之间的距离
getDistance(p1, p2) {
var x = p2.pageX - p1.pageX
var y = p2.pageY - p1.pageY
return Math.sqrt((x * x) + (y * y))
},
IsPC() {
var userAgentInfo = navigator.userAgent
var Agents = ['Android', 'iPhone',
'SymbianOS', 'Windows Phone',
'iPad', 'iPod']
var flag = true
for (var v = 0; v < Agents.length; v++) {
if (userAgentInfo.indexOf(Agents[v]) > 0) {
flag = false
break
}
}
return flag
}
}
}
</script>
<style scoped>
* {
font-size: 0;
touch-action: pan-y;
}
.box {
width: 100%;
height: 100vh;
overflow: hidden;
text-align: center;
}
</style>