| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- import { ObjectDirective } from 'vue';
- export const bindMoveTool = (el: HTMLElement, binding) => {
- const initScale = binding.value ? binding.value : 1;
- const targetkey = binding.arg ? Number(binding.arg) : 0;
- const transInfo = {
- zoom: initScale,
- toMove: false,
- toScale: false,
- transOriginX: 50,
- transOriginY: 50,
- translateX: 0,
- translateY: 0,
- distance: 1,
- mouseInit: { x: 0, y: 0 },
- curMousePos: { x: 0, y: 0 },
- };
- const setBgStyle = () => {
- el.setAttribute(
- 'style',
- `transform-origin: ${transInfo.transOriginX}% ${transInfo.transOriginY}%; transform: translate(${transInfo.translateX}px, ${transInfo.translateY}px) scale(${transInfo.zoom})`,
- );
- };
- const calcTransOrigin = (mouseX: number, mouseY: number) => {
- const mapBgInfo = el.getBoundingClientRect();
- if (transInfo.zoom !== initScale) {
- transInfo.translateX += (1 - 1 / transInfo.zoom) * (mouseX - transInfo.mouseInit.x);
- transInfo.translateY += (1 - 1 / transInfo.zoom) * (mouseY - transInfo.mouseInit.y);
- }
- transInfo.transOriginX = ((mouseX - mapBgInfo!.left!) / mapBgInfo!.width!) * 100;
- transInfo.transOriginY = ((mouseY - mapBgInfo!.top!) / mapBgInfo!.height!) * 100;
- transInfo.mouseInit = { x: mouseX, y: mouseY };
- };
- const handleScale = (e) => {
- if (e.ctrlKey) {
- e.preventDefault();
- calcTransOrigin(e.clientX, e.clientY);
- if (e.wheelDelta > 0) {
- const newZoom = transInfo.zoom + 0.2;
- transInfo.zoom = newZoom > 10 ? 10 : newZoom;
- } else if (e.wheelDelta < 0) {
- const newZoom = transInfo.zoom - 0.2;
- transInfo.zoom = newZoom < 0.2 ? 0.2 : newZoom;
- }
- setBgStyle();
- }
- };
- const handleMouseDown = (e) => {
- if (e.button === targetkey) {
- transInfo.toMove = true;
- transInfo.curMousePos = { x: e.clientX, y: e.clientY };
- }
- };
- const handleMouseMove = (e) => {
- if (transInfo.toMove) {
- transInfo.translateX += e.clientX - transInfo.curMousePos.x;
- transInfo.translateY += e.clientY - transInfo.curMousePos.y;
- transInfo.mouseInit = {
- x: transInfo.mouseInit.x + (e.clientX - transInfo.curMousePos.x),
- y: transInfo.mouseInit.y + (e.clientY - transInfo.curMousePos.y),
- };
- }
- transInfo.curMousePos = { x: e.clientX, y: e.clientY };
- setBgStyle();
- };
- const handleMouseUp = () => {
- transInfo.toMove = false;
- transInfo.curMousePos = { x: 0, y: 0 };
- };
- // const calcMobileTransOrigin = (mouseX: number, mouseY: number) => {
- // const mapBgInfo = el.getBoundingClientRect();
- // if (transInfo.zoom !== initScale) {
- // transInfo.translateX += (1 - 1 / transInfo.zoom) * (mouseX - transInfo.mouseInit.x);
- // transInfo.translateY += (1 - 1 / transInfo.zoom) * (mouseY - transInfo.mouseInit.y);
- // }
- // transInfo.transOriginX = ((mouseX - mapBgInfo!.top!) / mapBgInfo!.height!) * 100;
- // transInfo.transOriginY = (1 - (mouseY - mapBgInfo!.left!) / mapBgInfo!.width!) * 100;
- // transInfo.mouseInit = { x: mouseX, y: mouseY };
- // };
- // const handleTouchStart = (e) => {
- // const touches = e.touches;
- // if (touches.length == 1) {
- // transInfo.toMove = true;
- // transInfo.toScale = false;
- // transInfo.curMousePos = { x: touches[0].pageY, y: touches[0].pageX };
- // } else if (touches.length == 2) {
- // transInfo.toMove = false;
- // transInfo.toScale = true;
- // // 计算中点
- // const midX = (touches[0].pageY + touches[1].pageY) / 2;
- // const midY = (touches[0].pageX + touches[1].pageX) / 2;
- // calcMobileTransOrigin(midX, midY);
- // // 计算距离
- // const disX = Math.abs(touches[0].pageY - touches[1].pageY);
- // const disY = Math.abs(touches[0].pageX - touches[1].pageX);
- // transInfo.distance = Math.sqrt(disX * disX + disY * disY);
- // }
- // };
- // const handleTouchMove = (e) => {
- // const touches = e.touches;
- // if (touches.length == 1 && transInfo.toMove) {
- // transInfo.toMove = true;
- // transInfo.toScale = false;
- // transInfo.translateX += touches[0].pageY - transInfo.curMousePos.x;
- // transInfo.translateY -= touches[0].pageX - transInfo.curMousePos.y;
- // transInfo.mouseInit = {
- // x: transInfo.mouseInit.x + (touches[0].pageY - transInfo.curMousePos.x),
- // y: transInfo.mouseInit.y - (touches[0].pageX - transInfo.curMousePos.y),
- // };
- // transInfo.curMousePos = { x: touches[0].pageY, y: touches[0].pageX };
- // setBgStyle();
- // } else if (touches.length == 2 && transInfo.toScale) {
- // e.preventDefault();
- // transInfo.toMove = false;
- // transInfo.toScale = true;
- // // 计算距离
- // const disX = Math.abs(touches[0].pageY - touches[1].pageY);
- // const disY = Math.abs(touches[0].pageX - touches[1].pageX);
- // const curDistance = Math.sqrt(disX * disX + disY * disY);
- // transInfo.zoom = transInfo.zoom * (curDistance / transInfo.distance);
- // setBgStyle();
- // transInfo.distance = curDistance;
- // }
- // };
- // const handleTouchEnd = () => {
- // transInfo.toMove = false;
- // transInfo.toScale = false;
- // transInfo.distance = 1;
- // transInfo.curMousePos = { x: 0, y: 0 };
- // };
- setBgStyle();
- el.addEventListener('mousewheel', handleScale);
- el.addEventListener('mousedown', handleMouseDown);
- el.addEventListener('mousemove', handleMouseMove);
- el.addEventListener('mouseup', handleMouseUp);
- };
- export const moveable: ObjectDirective = {
- mounted(el: HTMLElement, binding) {
- bindMoveTool(el, binding);
- },
- };
|