精读《自由布局吸附线的实现》

news2024/11/16 15:47:01

目录

判断 box 离哪条边最近

产生吸附效果

resize 时中间对齐线需要放大双倍吸附力

总结


自由布局吸附线的效果如下图所示:

图片

那么如何实现吸附线呢?我们先归纳一下吸附线的特征:

  • 正在拖动的 box 与其他 box 在水平或垂直位置距离接近时,会显示对齐线。

  • 当吸附作用产生时,鼠标在一定范围内移动都不会改变组件位置,这样鼠标对齐就产生了一定的容错性,用户不需要一像素一像素的调整位置。

  • 当鼠标拖动的足够远时,吸附作用消失,此时 box 跟手移动。

根据这些规则,我们首先要实现的就是判断当前拖动 box 与哪些组件的边足够接近。

判断 box 离哪条边最近

        距离最近的边可能不止一条,水平与垂直位置要分别判断。我们以水平位置为例,垂直同理。

        拖动 box 在水平位置可能有 上、中、下 三条边可以产生吸附,而其他 box 同样也有 上、中、下 三条边可以与之产生交互,因此对于每一个目标 box,我们需要计算 9 个距离:

  • source 上 vs target 上

  • source 上 vs target 中

  • source 上 vs target 下

  • source 中 vs target 上

  • source 中 vs target 中

  • source 中 vs target 下

  • source 下 vs target 上

  • source 下 vs target 中

  • source 下 vs target 下

        因为 source 的每条边最多只能出现一条吸附线,所以按照 source 聚合一下每条边的最近 target 边:

  • source 上 vs min(target 上、中、下) = min 上

  • source 中 vs min(target 上、中、下) = min 中

  • source 下 vs min(target 上、中、下) = min 下

        可以想象,当 source 与 target box 完全一样大时,最多产生三条吸附线(上 vs 上,中 vs 中,下 vs 下)。但一旦 box 高度不同,结果就不一样了,所以我们还需要计算 source 上、中、下 最接近的距离是多少:

        source 所有位置最小距离 = min(min 上、min 中、min 下)

        然后按照 source 所有位置最小距离筛选 min 上、min 中、min 下,留下来的就是要 source 距离 target 水平位置最近的吸附线。

        我们还需要设置吸附阈值,否则所有鼠标位置都会产生吸附。所以当 source 所有位置最小距离大于吸附阈值时,就不产生吸附效果了。

产生吸附效果

        吸附的实现方式与拖拽的实现方式有关。

        假设拖拽的实现方式是:dragStart 时记录鼠标的起始位置 mouseStartX(Y 同理),在 drag 时产生了位移 movementX,那么组件当前位置就是 mouseStartX + movementX

        如果我们可以拿到吸附产生的反向位移 snapX,那么组件位置就可以实现为:

        mouseStartX + movementX + snapX

        可以想象当鼠标从上往下移动时,当产生吸附时,snapX 会产生反向作用抵消 box 的向下位移,从而保证 box 在吸附时在垂直方向没有产生移动,这样吸附效果就实现了。

    snapX 的值如何计算呢?其实就是上一步的 “source 所有位置最小距离” 取反。

resize 时中间对齐线需要放大双倍吸附力

        resize 与 drag 不同,设想鼠标拖动 box 的下方边缘向下做 resize,此时除了组件移动外,还产生了组件高度变高的效果,那么从上、中、下三段观察 box,其位置与鼠标位移的变化关系是:

  • 上:位置不变。

  • 中:位置向下位移为鼠标位移 * 0.5

  • 下:位置向下位移为鼠标位移 * 1

        因此如果中间位置产生了吸附线,为了抵消鼠标向下移动,需要产生两倍的 snap 反向位移:

        mouseStartX + movementX + snapX * 2

总结

        我们梳理了吸附的判断条件与吸附作用如何生效,以及 resize 时中间线吸附的特殊处理逻辑。

        自由布局除了吸附之外,还有哪些边界的交互,如何实现呢?希望大家思考与留言。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/807642.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring之BeanDefinition(二)

Spring之BeanDefinition 文章目录 Spring之BeanDefinition1、对象和bean的区别2、BeanDefinition作用AutowireCandidate说明Primary说明ConstructorArgumentValues说明第一种使用方式第二种使用方式 MutablePropertyValuesabstract小结 3、BeanDefinition的发展历程3、BeanDefi…

RedHat7.9安装mysql8.0.32 ↝ 二进制方式

RedHat7.9安装mysql8.0.32 ↝ 二进制方式 一、rpm方式安装1、检查是否安装了mariadb2、下载mysqlmysql8.0.323、上传解压4、创建安装目录,拷贝解压后的文件至安装目录/usr/local/mysql8.0/5、创建相关目录,开始安装6、创建mysql组和用户7、更改安装目录归…

SpringAOP的相关概念

文章目录 一.什么是AOP二.AOP的组成部分三.SpringAOP的实现3.1 增加SpringAOP依赖3.2 创建切面3.2 创建切点3.3 创建通知3.4 创建连接点 四.SpringAOP的实现原理4.1 JDK动态代理4.2 CGLIB 动态代理总结 一.什么是AOP AOP,全称为Aspect-Oriented Programming&#x…

创建jupyterlab的快捷启动的一种方式

1、找Jupyter Notebook的快捷图标 首先,找到Jupyter Notebook的快捷图标,打开其文件位置。 2、复制Jupyter Notebook快捷方式 复制Jupyter Notebook的快捷方式 将复制Jupyter Notebook的快捷方式的这两处的Noetbook修改为lab。 如下图 3、找Jupy…

RocketMQ概论

目录 前言: 1.概述 2.下载安装、集群搭建 3.消息模型 4.如何保证吞吐量 4.1.消息存储 4.1.1顺序读写 4.1.2.异步刷盘 4.1.3.零拷贝 4.2.网络传输 前言: RocketMQ的代码示例在安装目录下有全套详细demo,所以本文不侧重于讲API这种死…

Git的常用命令以及使用场景

文章目录 1.前言2.工作区,暂存区,版本库简介3.Git的常用命令4.版本回退5.撤销修改6.删除文件7.总结 1.前言 在学习Git命令之前,需要先了解工作区,暂存区和版本库这三个概念 2.工作区,暂存区,版本库简介 在使用Git进行版本控制时,有三个重要的概念:工作…

day48-ajax+SSM分页

AjaxSSM分页 非分页版controller及html: 分页模糊查询controller: Postman测试(无网页): 分页网页: 分页网页中添加模糊查询: 分页网页中实现添加功能: (1&am…

VUE3-04

1. 编写代码过程中的问题与解决 1.1 错误:cant read property of undefined(name) (1)首先定位错误的位置 (2)逐一排查问题:注释代码;debugger;console.log (3&#xff0…

10.Docker安全和https

文章目录 Docker安全Docker存在的安全问题Docker架构缺陷与安全机制Docker 安全基线标准Docker安全总结 HTTPSHTTPS访问过程生成证书方式openssL生成证书过程 Docker安全 容器的安全性问题的根源在于容器和宿主机共享内核。如果容器里的应用导致Linux内核崩溃,那么…

Spring Tool Suite 4

参考:Spring tool suite4 安装及配置_springtoolsuite4_猿界零零七的博客-CSDN博客 下载:Spring | Tools 将下载的JAR进行解压两次,直至解压出contents中的sts 双击启动 第一次打开需要指定工作区文件夹 配置Maven的config 安装插件

C++ new/delete的使用

1.虚拟地址空间 可执行程序(进程)的虚拟地址空间: 内核:操作系统 栈区:函数的形参,非静态的局部变量,函数现场保护数据等等,栈是向下增长的,栈顶是低地址,栈…

基于fpga_EP4CE6F17C8实现的呼吸灯

文章目录 前言实验手册(EP4CE6F17C8)一、实验目的二、实验原理理论原理 三、系统架构设计四、模块说明1.模块端口信号列表2.状态转移图3.时序图 五、仿真波形图六、引脚分配七、代码实现八、仿真代码九、板级验证效果 …

[CrackMe]damn.exe的逆向及注册机编写

1. 脱壳过程 这个crackme有2个文件 发现加了壳 先来脱壳, 使用ESP守恒, pushad后立马下硬件访问断点 F9直接运行, 立马到popad处 接着走几步就到了OEP 下面使用LordPE来转储映像, 为了防止别人修改PE中的ImageSize, 先尝试修正下ImageSize, 然后dump full即可 接着用x6…

《重构的时机和方法》——让你的代码更健壮、更易维护

👏作者简介:大家好,我是爱敲代码的小黄,独角兽企业的Java开发工程师,CSDN博客专家,阿里云专家博主📕系列专栏:Java设计模式、Spring源码系列、Netty源码系列、Kafka源码系列、JUC源码…

简述IO(BIO NIO IO多路复用)

在unix网络变成中的五种IO模型: Blocking IO(阻塞IO) NoneBlocking IO (非阻塞IO) IO mulitplexing(IO多路复用) signal driven IO (信号驱动IO) asynchronous IO (异步IO) BIO BIO(Blocking IO)是一种阻塞IO模型,也是传统的IO操作模型之一…

不管如何吐槽,购买iPhone的用户依然义无反顾,苹果继续增长

市调机构IDC公布的二季度数据显示,苹果成为前五名之中除华为之外第二家取得增长的手机品牌,而其他国产手机品牌的出货量都在下滑,显示出国内的消费者仍然在热烈追捧iPhone。 二季度苹果在国内市场的手机出货量同比增长6%,虽然增速…

查看详细的退货信息!亚马逊在卖家中心推出新页面!

亚马逊欧洲站发布公告称亚马逊在卖家中心推出了一个新页面,为卖家提供详细的退货信息,以下是公告内容: 我们在卖家中心推出了一个新页面,为卖家提供详细的退货信息。 现在卖家可以查看每个退货订单,其中包含有关 ASI…

sky-notes-01

1、DTO类 DTO(Data Transfer Object):数据传输对象,Service 或 Manager 向外传输的对象。 详见阿里巴巴Java开发手册中的DO、DTO、BO、AO、VO、POJO定义 当前端提交的数据和实体类中对应的属性差别比较大时,建议使用…

【信号去噪和正交采样】流水线过程的一部分,用于对L波段次级雷达中接收的信号进行降噪(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

信号的学习笔记二

文章目录 信号捕捉signal信号捕捉sigaction信号集未决信号集和阻塞信号集的工作过程 ![在这里插入图片描述](https://img-blog.csdnimg.cn/b896346af6f1462089779e513a7e237b.png)信号集相关函数sigemptysetsigfillsetsigaddsetsigdelsetsigismember应用 以下函数设置内核信号集…