轻松教你搞定组件的拖拽, 缩放, 多控制点伸缩和拖拽数据上报

徐小夕 等级 721 0 1

最近笔者专注于研究可视化搭建平台的解决方案, 分析了很多拖拽组件和页面动态化技术, 也在 H5-Dooring 项目中做了很多技术实现, 包括:

  • 搭建平台的组件设计和分类模式
  • 拖拽生成页面方案
  • 动态表单编辑器设计
  • 页面实时预览编译技术
  • 自定义组件和自定义模版方案
  • 多人协作的可视化搭建模式实现

还有很多技术细节这里不一一举例了, 最近在研究自由布局时发现有这样一个需求, 我们可以自由拖拽和缩放组件, 并能从组件的不同纬度拖拽, 如下图所示: 轻松教你搞定组件的拖拽, 缩放, 多控制点伸缩和拖拽数据上报

由于我们的技术栈采用的是 React, 目前还没有一个成熟库可以同时支持自由拖拽和缩放, 我们不得不用 react-dragablereact-resiable两个库来实现拖拽和缩放, 但是这样我们要维护的数据结构就相当复杂了(当然vue生态有成熟的vue-dragable等来支持自由拖拽和缩放), 所以最后笔者决定自己来实现一个.

我们从可视化搭建平台的实际业务出发, 可以分析出拖拽缩放有如下几个功能点:

  • 自由拖拽
  • 支持控制点, 多方位缩放
  • 支持自由控制层级
  • 支持组件静态化(即为了实现固定, 预览页面等效果)
  • 拖拽缩放的数据能回传给上层组件并提供受控机制

实现以上四点我们就可以实现一个可用的拖拽缩放组件. 接下来笔者就来介绍一下实现的开源拖拽缩放组件rc-drag.

实现自由拖拽

rc-drag未压缩的体积只有20多k, 去除注释核心代码不到200行, 可以说是一个非常轻量的拖拽缩放组件库了, 我们要想让自己的组件能自由拖拽, 只需要使用如下方式:

  1. 安装
    npm i @alex_xu/rc-drag
    # 或
    yarn add @alex_xu/rc-drag
  2. 基本使用
    <div id="box" style={{position: 'relative', width: '500px', height: '260px'}}>
    <Drag container="#box" size={[200, 200]}>
     <p>Mr xu</p>
    </Drag>
    </div>
    我们只需要以上几行代码就能实现组件的自由拖拽. 效果如下: 轻松教你搞定组件的拖拽, 缩放, 多控制点伸缩和拖拽数据上报

解决可视化搭建平台页面层级的问题

目前在 h5-dooring 是通过横向扩展来解决组件层级和嵌套的问题, 如果我们采用自由拖拽布局, 层级和嵌套的问题就很好解决了. 在 @alex_xu/rc-drag 这个库中笔者实现设置层级的功能, 所以我们可以通过给拖拽组件设置不同的层级, 来实现页面元素叠加和层的概念. 如下设置:

<Drag container="#box" size={[10, 50]} zIndex={10}>
  <p>Mr xu</p>
</Drag>

轻松教你搞定组件的拖拽, 缩放, 多控制点伸缩和拖拽数据上报

我们通过给组件设置更高的层级来实现组件堆叠的效果.

实现组件静态化

我们往往会在编辑页面时对组件进行拖拽等操作, 但是有些场景我们需要让组件固定, 比如头部或者页脚, 或者锁定某个元素, 类似于 PS 里图层锁定. 另一个场景是我们要实现公共的页面渲染器, 在编辑状态下可以自由拖动缩放, 但是在预览状态下需要让元素固定, 不能出现自有拖拽等功能, 类似 h5-dooring 那种模式, 这个时候我们需要让拖拽组件@alex_xu/rc-drag支持静态化. 这个时候我们可以设置isStatic属性为true, 如下图: 轻松教你搞定组件的拖拽, 缩放, 多控制点伸缩和拖拽数据上报 代码如下:

<Drag container="#box" isStatic={true}><p>static item</p></Drag>

我们可以利用这个属性, 写个页面渲染器, 用户在预览时将组件的isStatic设置为true即可, 源码的底层实现其实也很简单, 就是利用react-hoooks的组件编写方式写个判断即可:

{
   isStatic ? 
      <div className="x-drag-item" style={style}>{ children }</div>
      :
      <div 
        className="x-drag-item" 
        style={style} 
        onMouseDown={(e) => onMouseDown('move', e)} 
        onMouseUp={onMouseUp} onMouseMove={onMouseMove}
      >
      </div>
}

实现组件数据上报

我们都知道组件单纯只有拖拽缩放能力远远不能满足业务需求, 对于可视化拖拽组件, 更重要的是要能保留拖拽后的数据, 比如宽高,位置,层级等数据, 所以我们需要监控几个事件, 并将数据传给对应的事件来让外层能监听和获取. 这里笔者提供了两个拖拽回传方法:

  • onDrapStart
  • onDrapStop

后面根据实际情况可以对应添加. 我们可以在父组件中绑定对应的方法, 如下:

<Drag 
  container="#box" 
  size={[200, 200]} 
  zIndex={2} 
  onDragStart={(item) => console.log('start', item)} 
  onDragStop={(item) => console.log('stop', item)}
>
  <p>Mr xu</p>
</Drag>

这样我们就能在父层拿到对应的数据并保存下来了, 进而也就能实现我们的预览页面的功能了. 具体可以参考H5-Dooring 渲染器的部分.

以上几个技术点和技术实现是可视化拖拽组件必备的要素, 大家可以使用参考一下. 轻松教你搞定组件的拖拽, 缩放, 多控制点伸缩和拖拽数据上报

github地址: 传送门

如果大家对可视化搭建平台感兴趣, 可以参考 H5-Dooring 相关的技术文章来了解更多lowcodenocode 的知识.

最后

觉得有用 ?喜欢就收藏,顺便点个吧,你的支持是我最大的鼓励!微信搜 “趣谈前端”,发现更多有趣的H5游戏, webpack,node,gulp,css3,javascript,nodeJS,canvas数据可视化等前端知识和实战.

收藏
评论区

相关推荐

我的python多线程和多进程
线程存在空闲 from multiprocessing.dummy import Poolfrom multiprocessing.dummy import Pool as ThreadPool pool ThreadPool(20) pool.map(job_worker, result_cursor)
京东面试真题解析,手撕面试官
第1章快速入门1.1 Kafka简介1.2 以Kafka为中心的解决方案1.3 Kafka核心概念1.4 Kafka源码环境 第2章生产者2.1 KafkaProducer 使用示例2.2 KafkaProducer 分析 ProducerInterceptors&cProducerInterceptor Kafka 集群元数据 Serializ
HTTPS
### 最近网站更新为https,于是做个笔记 ### 将域名 [www.domain.com](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fwww.domain.com) 的证书文件1\_www.domain.com\_bundle.crt 、 ### 私钥文件2\_www.doma
HTTPS
楔子 谣言粉碎机前些日子发布的《[用公共WiFi上网会危害银行账户安全吗?](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fwww.guokr.com%2Farticle%2F100110%2F)》,文中介绍了在使用HTTPS进行网络加密传输的一些情况,从回复来看,争议还是有的。随着网络越
HTTPS、SSL、TLS三者之间的联系和区别
**SSL(Secure Socket Layer 安全套接层)**是基于HTTPS下的一个协议加密层,最初是由网景公司(Netscape)研发,后被IETF(The Internet Engineering Task Force - 互联网工程任务组)标准化后写入(RFCRequest For Comments 请求注释),RFC里包含了很多互联网技术的规
HTTPS和HTTP的区别
HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议 它是一个安全通信通道,它基于HTTP开发,用于在客户计算机和服务器之间交换信息。它使用安全套接字层(SSL)进行信息交换,简单来说它是HTTP的安全版。  它是由Netscape开发并内置于其浏览器中,用于对数据进行压缩和解压操作,并返回网络上传送回的
HTTPS的工作原理
**目的** http就是我们平时浏览网页时候使用的一种协议(网站是以http://开头)。http协议传输的数据都是未加密的(明文),一次http协议传输隐私信息非常不安全。为了保证这些隐私数据能加密传输,出现了https,下面讨论一下https的工作原理: **概述** HTTPS在传输数据之前需要客户端(浏览器)与服务端(网站)之间进行一
HTTPS请求
##HTTPS请求## > **HttpsUtils代码** package com.ices.utils.httpsHelp; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader;
Golang代码实现HTTPs(HTTPS证书生成和部署)
在win7下试试: 1.**实现一个最简单的HTTPS Web Server** // gohttps/2-https/server.go package main import ( "fmt" "net/http" ) func handler(w http.R
Nginx配置https
一、开启nginx的ssl模块 1.未安装过nginx,编译安装配置参数如下: ./configure \--prefix=/usr/local/nginx \--with-pcre \--with-http\_ssl\_module #ssl模块 \--with-http\_stub\_status\_module \--wit
Rust的多继承和mixin机制
先上一段Rust代码: trait A { fn say(self); } trait B { fn say(self); } struct S; impl A for S { fn say(self) {
springboot2 配置 https
package cn.xiaojf.aibus.configure; import org.apache.catalina.Context; import org.apache.catalina.connector.Connector; import org.apache.coyote.http11.Http11Ni
tomcat https访问和使用域名访问网站
版本: centos 6.5 tomcat 9.0 java 1.8 1.首先使用keytool工具生成证书: keytool 命令的目录是:/usr/local/java/bin下 配置了java的环境就可以直接使用. keytool -genkeypair -alias "tomcat" -keyalg "RSA" -keystore "/usr/lo