react 实现div缩放、旋转、拖拽的9个控制点
这段时间一个canvas 库所实现的元素拖拽控制,觉得很不错。于是自己用js + div 来实现一个。用了react 框架,练练手。
思路
在被控制的元素的四条边和四个角添加8个控制点控制点。拖拽控制点时判断拖拽的方向,计算偏移量。修改元素的top、left、width、height。
旋转功能是通过三角函数计算鼠标拖动后的角度。动态修改元素的rotate
画板(舞台)
想要对元素进行控制。 我们先定义一个画板,规定元素只能在指定的范围内变化。
然后在画板内插入一个被控制的 div 元素,就定义为drawing-item
类名吧。drawing-item
需要绝对定位于画板
以及八个方向的控制点。这是最简单的结构了
import "./Drawing.css"
// 东南西北, 东北、西北、东南、西南
const points = ['e', 'w', 's', 'n', 'ne', 'nw', 'se', 'sw']
function Drawing() {
// const data = useState()
return <div className="drawing-wrap">
<div className="drawing-item">
{
points.map(item => <div className={
`control-point point-${
item}`}></div>)}
</div>
</div>
}
export default Drawing;
给他们都加上样式
<style>
.drawing-wrap{
width: 500px;
height: 500px;
border: 1px solid red ;
position: relative;
top: 100px ;
left: 100px;
}
.drawing-item {
cursor: move;
width: 100px;
height: 100px;
background-color: #ccc;
position: absolute;
top: 100px;
left: 100px;
box-sizing: border-box;
}
.control-point{
position: absolute;
box-sizing: border-box;
display: inline-block;
background: #fff;
border: 1px solid #c0c5cf;
box-shadow: 0 0 2px 0 rgba(86, 90, 98, .2);
border-radius: 6px;
padding: 8px;
margin-top: -8px !important;
margin-left: -8px !important;
user-select: none; // 注意禁止鼠标选中控制点元素,不然拖拽事件可能会因此被中断
}
.control-point.point-e{
cursor: ew-resize;
left: 100%;
top: 50%;
margin-left: 1px
}
.control-point.point-n{
cursor: ns-resize;
left: 50%;
margin-top: -1px
}
.control-point.point-s{
cursor: ns-resize;
left: 50%;
top: 100%;
margin-top: 1px
}
.control-point.point-w{
cursor: ew-resize;
top: 50%;
left: 0;
margin-left: -1px
}
.control-point.point-ne {
cursor: nesw-resize;
left: 100%;
margin-top: -1px;