吸附功能开发

更新时间: 2021-08-04 15:08:44

上午刚写完辅助线,下午趁热把吸附给写了~先放效果图吧:

# 原理分析

吸附发生在拖动元素的时候,拖动的时候,当前正在拖动的元素抽象出的8个点是图中的白点,和这8个点对比的点是其他元素的绿点

分别对比这些点的x或y的距离,如果小于设定的距离,比如说5px,就改变当前元素的x或y让这个距离变成0。

# 代码

原理很简单,代码如下:

import { getPoints } from '../utils/common'

export function countAdsorb(e,moveX,moveY) {
    const DISTANCE = 5
    if(this.constructor._instanceList.length < 2){
        return false
    }
    //首先找到需要对比的点和被对比的点
    const currentList = [] //当前元素的8个点
    const compareList = [] //其他元素的点
    for(let i = 0;i< this.constructor._instanceList.length; i++) {
        const instance = this.constructor._instanceList[i]
        if(instance.parentEl === this.parentEl && instance.id !== this.id) {
            compareList.push(...getPoints(instance))
        }else if(instance.parentEl === this.parentEl && instance.id == this.id){
            currentList.push(...getPoints(instance))
        }
    }
    if(compareList.length == 0) {
        return false
    }
    let flag = false
    let res = ''
    //计算它们x和y坐标的差值,如果绝对值小于5就吸附上去,吸附了其中一个就退出循环
    for(let i = 0;i < currentList.length; i++) {
        const x = currentList[i].x
        const y = currentList[i].y
        for(let j = 0;j < compareList.length; j++) {
            const cx = compareList[j].x
            if(Math.abs(x - cx) <= DISTANCE) {
                const dis = x - cx
                flag = true
                res += 'x'
                this.x = this.x - dis
                this.xCenter = this.x + (this.width / 2)
                this.x1 = this.x + this.width
                break;
            }
        }
        for(let j = 0;j < compareList.length; j++) {
            const cy = compareList[j].y
            if(Math.abs(y - cy) <= DISTANCE) {
                const dis = y - cy
                flag = true
                res += 'y'
                this.y = this.y - dis
                this.yCenter = this.y + (this.height / 2)
                this.y1 = this.y + this.height
                break;
            }
        }
        if(flag){
            break;
        }
    }
    //根据变动的是x还是y分量来修正this.dragOrigin的值
    if(res == 'x') { 
        if(Math.abs(moveX) > DISTANCE) {
            this.dragOrign.x = e.pageX
        }
        this.dragOrign.y = e.pageY
    }
    if(res == 'y') { 
        if(Math.abs(moveY) > DISTANCE) {
            this.dragOrign.y = e.pageY
        }
        this.dragOrign.x = e.pageX
    }
    if(res == 'xy') {
        if(Math.abs(moveX) > DISTANCE) {
            this.dragOrign.x = e.pageX
        }
        if(Math.abs(moveY) > DISTANCE) {
            this.dragOrign.y = e.pageY
        }
    }
    if(flag) {
        return true
    }else{
        return false
    }
}

export function registerAdsort(_this) {
    _this.countAdsorb = countAdsorb.bind(_this)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86