Vue 页面放大缩小,且放大后可以拖拽
Vue.js简单的放大组件,放大倍数现在为hardCode, 可更改为根据两指之间距离重新计算倍数。缩小到一倍后不可继续缩小且页面也无法移动。放大后可移动整个页面用来聚焦某部分。
·
简单的放大组件,放大倍数现在为hardCode, 可更改为根据两指之间距离重新计算倍数。
放大后可移动整个页面用来聚焦某部分
缩小到一倍后不可继续缩小且页面也无法移动
<template>
<div class="home-root">
<div
class="city"
ref="chmap"
style="transform: scale(1)"
@dblclick="enlarge"
id='imageWrapper'
@touchstart="touchstart($event)"
@touchmove="touchmove($event)"
@touchend="touchend($event)"
:style="{'backgroundImage': `url(${fireBackground})`}"
>
<img :src="cityImages.lightedIcon" alt="">
</div>
</div>
</template>
<script>
import { Toast } from 'vant';
import fireBackground from '@/assets/images/city/fire_background.png';
import cityImages from '@/assets/images/city';
export default {
data() {
return {
fireBackground,
cityImages,
offsetWidth: document.documentElement.clientWidth,
offsetHeight: document.documentElement.clientHeight,
pageX: '',
pageY: '',
initX: '',
initY: '',
start: '',
isTouch: false,
currentScale: 1,
canTouchMove: false,
};
},
methods: {
enlarge() {
this.canTouchMove = true;
this.$nextTick(() => {
const self = this;
if (this.currentScale === 1) {
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(1.2)';
}, 50);
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(1.4)';
}, 50);
this.currentScale = 1.4;
} else if (this.currentScale === 1.4) {
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(1.6)';
}, 50);
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(1.8)';
}, 50);
this.currentScale = 1.8;
} else if (this.currentScale === 1.8) {
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(2.0)';
}, 50);
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(2.2)';
}, 50);
this.currentScale = 2.2;
} else {
Toast('不能再放大了');
return;
}
this.$refs.chmap.style.transformOrigin = `${this.offsetWidth / 2} ${this.offsetHeight / 2}`;
});
},
narrow() {
this.canTouchMove = true;
this.$nextTick(() => {
const self = this;
if (this.currentScale === 2.2) {
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(2.0)';
}, 50);
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(1.8)';
}, 50);
this.currentScale = 1.8;
} else if (this.currentScale === 1.8) {
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(1.6)';
}, 50);
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(1.4)';
}, 50);
this.currentScale = 1.4;
} else if (this.currentScale === 1.4) {
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(1.2)';
}, 50);
setTimeout(() => {
self.$refs.chmap.style.transform = 'scale(1.0)';
}, 50);
this.currentScale = 1;
} else {
Toast('不能再缩小了');
return;
}
this.$refs.chmap.style.transformOrigin = `${this.offsetWidth / 2} ${this.offsetHeight / 2}`;
this.$refs.chmap.style.top = '0px';
this.$refs.chmap.style.left = '0px';
});
},
touchstart(e) {
this.pageX = e.targetTouches[0].pageX; // 获取手指点的x坐标
this.pageY = e.targetTouches[0].pageY; // 获取手指点的Y坐标
this.initX = this.$refs.chmap.offsetLeft; // 获取div的left
this.initY = this.$refs.chmap.offsetTop; // 获取div的top
// 一根手指 移动事件
if (e.touches.length > 0 && e.touches.length < 2) {
this.isTouch = true; // 开启手指操作
// 两根手指 缩放事件
} else if (e.touches.length >= 2) {
this.start = e.touches;
}
},
// 手势操作中
touchmove(e) {
const self = this;
const chmapScale = this.$refs.chmap.style.transform.slice(6, -1); // 获取scale值
e.preventDefault(); // 取消事件的默认动作。
// 移动操作
if (e.touches.length === 1 && this.isTouch) {
if (!this.canTouchMove) return;
const touchMoveX = e.targetTouches[0].pageX; // 移动后的left值
const touchMoveY = e.targetTouches[0].pageY; // 移动后的top值
const top = parseInt(touchMoveY, 10) - parseInt(this.pageY, 10) + parseInt(this.initY, 10);
const left = parseInt(touchMoveX, 10) - parseInt(this.pageX, 10) + parseInt(this.initX, 10);
if (this.currentScale === 1) {
this.$refs.chmap.style.left = '0px';
this.$refs.chmap.style.top = '0px';
return;
}
if (Math.abs(left) < (this.$refs.chmap.offsetWidth * (this.currentScale - 1)) / 2) {
this.$refs.chmap.style.left = `${left}px`;
}
if (Math.abs(top) < (this.$refs.chmap.offsetHeight * (this.currentScale - 1)) / 2) {
this.$refs.chmap.style.top = `${top}px`;
}
}
// 放大操作 两个点以上,为了不无限放大造成负担,最大2.3倍
if (e.touches.length >= 2 && self.isTouch && chmapScale < 2.3) {
const now = e.touches; // 获取手指点的参数
let scale = self.getDistance(now[0], now[1]) / self.getDistance(self.start[0], self.start[1]); // 调用算法算出偏移量
// 最大值
if (scale > 1.1) {
scale = 2;
this.isTouch = false;
this.enlarge();
}
// 最小值
if (scale < 1) {
// 缩放后回归原位
scale = 1;
this.isTouch = false;
this.narrow();
}
}
},
// 手势操作结束
touchend(e) {
if (this.isTouch) {
this.isTouch = false;
}
},
getDistance(p1, p2) {
const x = p2.pageX - p1.pageX;
const y = p2.pageY - p1.pageY;
return Math.sqrt(x * x + y * y);
},
},
};
</script>
<style lang="scss" scoped>
.city {
position: relative;
min-width: 100vw;
min-height: 100vh;
color: white;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.home {
&-root {
color: white;
min-height: 100vh;
position: relative;
img {
width: 80px;
height: 80px;
position: absolute;
top: 200px;
right: 150px;
}
}
}
</style>
更多推荐
已为社区贡献1条内容
所有评论(0)