【手摸手带你实现可视化系统(二)】如何实现组件的自由变换?

1,136 阅读2分钟

「这是我参与2022首次更文挑战的第11天,活动详情查看:2022首次更文挑战

前言

本文是自己动手实现数据可视化项目-高仿dataV的第二篇--自由变换组件的实现

第一篇: [可视化系统]如何实现编辑面板的动态缩放?

需求分析

首先明确需求:我需要在主舞台上放置组件(文本、表格、图片、各种图表等),组件需要满足自由拖拽、大小变换、缩放旋转等。

最终效果

先来看看最终实现的效果,上下左右锚点控制上下左右拉伸,四个角的锚点可以向角的方向拖拽实现大小变换,放在组件内部(白色蚂蚁线圈定区域)可实现组件拖动。中心正上方的锚点控制组件的旋转。 image.png

image.png

实现方案

原理很简单,其实就是在组件外层套一层自由变换的壳子。

自由变换的盒子的实现逻辑就是每个锚点都对应div,拖动锚点,根据锚点的类实现对应的变换功能就好了。 模板代码结构如下:

image.png

具体实现就是,当鼠标mousedown时记录下组件当前的位置,mousemove时,根据触发的不同锚点和鼠标移动的距离,执行对应的操作。以右侧锚点为例,拖动时应该是组建的width变化。其他的操作类似。

vue-drag-resize-rotate

vue-drag-resize-rotategithub上开源的一个自由变换组件,上面看到的效果就是基于这个组件实现的,他不仅提供了上年提到的变换相关的功能,还有意外惊喜: 它提供了父容器的网格样式。 这个组件好像正是为了我们这种场景设计的,不知道作者是不是也是在做类似的功能。

import VueDragResizeRotate from "@gausszhou/vue-drag-resize-rotate";

<vue-drag-resize-rotate
      v-for="item in pageComponents"
      :key="item.id"
      :parent="true"
      :grid="[20, 20]"
      :rotatable="true"
      :w="item.width"
      :h="item.height"
      :x="item.posX"
      :y="item.posY"
      :r="item.romate"
      @resizing="(x, y, w, h) => resizing({ x, y, w, h }, item)"
    >
      <div class="component-event" @click.stop="loadSetting('widget', item.id)">
        <component :is="item.name" :data="item"> </component>
      </div>
</vue-drag-resize-rotate>

中文在线演示地址

总结

以上就是自由变换组件的实现思路。

本篇文章也是从零实现可视化系统(仿阿里dataV) 的系列文章的第二篇,后续会持续分享在实现中遇到的难点和解决思路。

第一篇: [可视化系统]如何实现编辑面板的动态缩放?

参考链接: github.com/gausszhou/v…

写在最后

我是Back,一个热爱分享的前端开发者。如果觉得本文还不错,记得三连+关注,说不定哪天就用得上!您的鼓励是我坚持下去的最大动力❤️。