项目中有个需求,需要实现div的拖动和缩放功能,可以通过监听鼠标事件、计算位移和缩放比例,并更新div的样式来实现。
思路:
1、要实现拖拽功能,需要监听鼠标的按下、移动和松开事件。在拖动过程中,需要计算鼠标的位移并更新div的位置。
const dragging = ref(false);
const position = ref({ x: 0, y: 0 });
const startMousePos = ref({ x: 0, y: 0 });
const startElementPos = ref({ x: 0, y: 0 });
const onMouseDown = (event) => {
dragging.value = true;
startMousePos.value = { x: event.clientX, y: event.clientY };
startElementPos.value = { x: position.value.x, y: position.value.y };
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
};
const onMouseMove = (event) => {
if (!dragging.value) return;
const deltaX = event.clientX - startMousePos.value.x;
const deltaY = event.clientY - startMousePos.value.y;
console.log(deltaX, deltaY);
position.value = {
x: startElementPos.value.x + deltaX,
y: startElementPos.value.y + deltaY,
};
};
const onMouseUp = () => {
dragging.value = false;
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
2、缩放比较简单,可以监听鼠标滚轮事件,根据滚轮的滚动方向来调整div的缩放比例。
const scaling = ref(false);
const scale = ref(1);
const scaleSteps = ref(0.2);
const scaleHandle = (event) => {
scaling.value = true;
//获取滚轮滚动方向
let delta = Math.sign(event.deltaY);
scale.value += delta * scaleSteps.value;
// 设置缩放范围
if (scale.value < 0.5) scale.value = 0.5;
if (scale.value > 2) scale.value = 2;
scaling.value = false;
};
附完整代码(基于vue开发)
<template>
<div
class="drag-scale-container"
@mousedown="onMouseDown"
@wheel.prevent="scaleHandle"
:style="{ left: `${position.x}px`, top: `${position.y}px`, transform: `scale(${scale})` }"
>
<slot></slot>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
/**
* 设置拖拽功能
*/
const dragging = ref(false);
const position = ref({ x: 0, y: 0 }); //dom现在坐标
const startMousePos = ref({ x: 0, y: 0 }); //鼠标按下去的坐标
const startElementPos = ref({ x: 0, y: 0 }); //dom上次的坐标
const onMouseDown = (event) => {
dragging.value = true;
startMousePos.value = { x: event.clientX, y: event.clientY };
startElementPos.value = { x: position.value.x, y: position.value.y };
document.addEventListener('mousemove', onMouseMove);
document.addEventListener('mouseup', onMouseUp);
};
const onMouseMove = (event) => {
if (!dragging.value) return;
const deltaX = event.clientX - startMousePos.value.x;
const deltaY = event.clientY - startMousePos.value.y;
console.log(deltaX, deltaY);
position.value = {
x: startElementPos.value.x + deltaX,
y: startElementPos.value.y + deltaY,
};
};
const onMouseUp = () => {
dragging.value = false;
document.removeEventListener('mousemove', onMouseMove);
document.removeEventListener('mouseup', onMouseUp);
};
/**
* 设置拖拽功能
*/
const scaling = ref(false);
const scale = ref(1); //缩放比例
const scaleSteps = ref(0.2); //缩放系数
const scaleHandle = (event) => {
if (dragging.value) return;
scaling.value = true;
//获取滚轮滚动方向
let delta = Math.sign(event.deltaY);
scale.value += delta * scaleSteps.value;
// 设置缩放范围
if (scale.value < 0.5) scale.value = 0.5;
if (scale.value > 2) scale.value = 2;
scaling.value = false;
};
</script>
<style lang="less" scoped>
.drag-scale-container {
position: absolute;
cursor: move;
transform-origin: center;
}
</style>