屏幕坐标&窗口通信
1. 拖动元素
<template lang="">
<div class="cardImg">
<img id="imgCard" :src="imgSrc" />
</div>
</template>
<script>
export default {
/*省略*/
methods: {
CardInit() {
const url = new URL(window.location.href);
const type = url.searchParams.get("type") || "12";
this.imgSrc = require(`@/assets/ikun${type}.jpg`);
const imgDom = document.querySelector(".cardImg");
imgDom.onmousedown = (e) => {
let x = e.pageX - imgDom.offsetLeft;
let y = e.pageY - imgDom.offsetTop;
window.onmousemove = (e) => {
const cx = e.pageX - x;
const cy = e.pageY - y;
imgDom.style.left = cx + "px";
imgDom.style.top = cy + "px";
};
window.onmouseup = () => {
window.onmousemove = null;
window.onmouseup = null;
};
};
},
},
};
</script>
2. 视口坐标与屏幕坐标的转化
浏览器窗口距离屏幕最上部分的高度,需要加上地址栏,标签页等一些的高度
// 1. 获取那个浏览器上半部分的宽度(地址栏,标签页等高度)
getBarHeight() {
// 浏览器整个高度 - 浏览器窗口的高度 = [地址栏,标签页等高度]
return window.outerHeight - window.innerHeight;
},
// 2. 视口坐标与屏幕坐标的转化
clientToScreen(x, y) {
const screenX = x + window.screenX;
// 此时的y是视口坐标,需要加上屏幕坐标,加上地址栏,标签页等的高度
const screenY = y + window.screenY + this.getBarHeight();
return [screenX, screenY];
},
// 3. 视口坐标与屏幕坐标的转化
screenToClient(x, y) {
const clientX = x - window.screenX;
const clientY = y - window.screenY - this.getBarHeight();
return [clientX, clientY];
},
3. 窗口通信与设置元素的位置
- 由于是在同一个页面
const channel = new BroadcastChannel("ikun") // 创建一个名为"ikun"的广播通道
- 拖动页面1图片,通知其他页面的元素的位置发生改变
上全部代码:
methods: {
CardInit() {
const url = new URL(window.location.href);
const type = url.searchParams.get("type") || "12";
this.imgSrc = require(`@/assets/ikun${type}.jpg`);
const imgDom = document.querySelector(".cardImg");
imgDom.onmousedown = (e) => {
let x = e.pageX - imgDom.offsetLeft;
let y = e.pageY - imgDom.offsetTop;
window.onmousemove = (e) => {
const cx = e.pageX - x;
const cy = e.pageY - y;
imgDom.style.left = cx + "px";
imgDom.style.top = cy + "px";
// 5. 通过广播通道发送 位置
const screenPoints = this.clientToScreen(cx,cy)
channel.postMessage(screenPoints)
};
window.onmouseup = () => {
window.onmousemove = null;
window.onmouseup = null;
};
};
this.dragElement()
},
// 1. 获取那个浏览器上半部分的宽度(地址栏,标签页等高度)
getBarHeight() {
return window.outerHeight - window.innerHeight;
},
// 2. 视口坐标与屏幕坐标的转化
clientToScreen(x, y) {
const screenX = x + window.screenX;
// 此时的y是视口坐标,需要加上屏幕坐标,但是由于浏览器有一个地址栏,标签页的高度
const screenY = y + window.screenY + this.getBarHeight();
return [screenX, screenY];
},
// 3. 视口坐标与屏幕坐标的转化
screenToClient(x, y) {
const clientX = x - window.screenX;
const clientY = y - window.screenY - this.getBarHeight();
return [clientX, clientY];
},
// 4. 拖动元素--> 通知其他窗口,将元素视口位置设置到拖动元素最后移动的位置
dragElement() {
channel.onmessage = (e) => {
const clientPoints = this.screenToClient(...e.data)
const imgDom = document.querySelector(".cardImg");
imgDom.style.left = clientPoints[0] + "px";
imgDom.style.top = clientPoints[1] + "px";
}
}
},
- 效果展示
短视频看到的,写下来作为记录,大佬见谅。