最近花了两天的时间做了一个极简的可视化,也可以勉强叫作低代码平台。
应用的方向是针对某一业务的专题活动这一类的有固定模块展示的需求。
目的就是由前端同学提供足够丰富的组件模块,可以由产品或者运营同学来自主完成页面的拼凑,然后生成项目地址与预览的界面。
因为这类的专题活动页生命周期很短,加上每一期需求代码量都较少,最少的可能只有一张图片便是一个页面的所有内容,所以在一期放弃了自动创建项目代码,以至于后续的项目自动部署等等操作。
一期只采用了在生产/测试环境固定一个已经完成部署的项目,项目中接收url中的参数来请求接口数据,将页面内容配置文件由接口返回,之后渲染页面即可。
这样的好处也不是没有,大概有以下几点:
1、项目无需部署,保存即生效,环节操作流畅,无需等待,体验友好
2、线上只有一个项目,无需过多的占用资源,否则每生成一个项目,都需要一份代码部署,而项目周期很短,会造成无形中的资源浪费。
3、无需自动创建项目代码,开发成本与时间大大降低。
当然,也有一些弊端,例如:
1、只有一个项目,如果遇到段时间无法支持(一般是组件模块不满足需求),需要二次开发的时候,只能手动创建项目
2、因为共用一个项目,每一次组件库的更改(会使用到同一个组件库),都会影响所有的项目,如果要统一测试难度太大,所有在每次组件更新的时候都要做到“万无一失”
以上只是交代一下项目的前因后果,并非本文重点,可自行略过,如果有相关需求可以参考,下文也会简单介绍该平台的简单组成部分
首先,是这个平台如果要打通流程,前端这边要由三部分组成:
一、一个组件库
二、一个配置平台,也就是可视化平台
三、一个线上的项目
组件库
- 首先是组件库,因为某些原因,我们的可视化平台使用的vue3,而线上的项目则使用的是vue2,所以遇到的第一个小问题是组件库的兼容性。
- 这里使用了vue-demi,以vue2+compisition-api为主包的方式开发,使用同一套代码,最后会同时产生vue2和vue3的组件代码,这样只需要维护一套代码即可。
- 另一个问题是pc端样式与移动端样式的兼容。
因为使用同一套组件库,既要在移动端正常使用,也要在pc端的可视化区域正常预览。
这里是将pc的可视化区域固定为750px,设置html的font-size属性,与移动端保持一套计算逻辑,组件库使用rem来进行响应式布局。
vue-demi地址
线上的项目
- 这里很简单,只需要根据url的参数值来进行数据请求,数据会返回组件的列表,以及每个组件的props配置,遍历即可,前提是要安装好组件库,数据结构如下
data: {
components: [
{
id: '1', // 组件id,一方面用于v-for的key,一方面用于可视化平台的组件聚焦
type: 'ImageComponent', // 组件类型,提前注册组件即可在component中使用
props: { // 组件所需要的props
src: 'http://xxxx.xxx/xx/xx'
}
}
]
}
<!-- 项目中使用数据 -->
<template>
<component
v-for="component in components"
:key="component.id"
:is="component.type"
v-bind="component.props" />
</template>
配置平台
这里是本文想要分享的地方
配置平台的页面大致都分为三部分。
1、组件的展示选择区
2、页面的预览/拖拽/拼接,也就是画布区域
3、单个组件的配置区
1和3没有太多可以说的东西,这里重点分享一下页面的画布区域
画布的操作首先是中央可视区域组件的操作,为了追求极简,又是应用在移动端,所以只提供了组件上下拖拽切换顺序的功能。
中央可视区域的组件渲染与线上项目的组件渲染完全一致即可,如下:
<!-- 可视化区域中渲染组件 -->
<template>
<component
v-for="component in components"
:key="component.id"
:is="component.type"
v-bind="component.props" />
</template>
完整交互是,用户选择组件加入中央可视区域,并拖拽改变组件顺序,随后配置组件数据,如下图:
其次是可视区域的交互操作,上图中红框的操作,例如拖拽移动,缩放等,因为这段时间经常会用墨刀去画些原型图,个人觉得墨刀的画布区域交互还是很不错的。
交互拆分一下:
1、ctrl+鼠标 移动
2、alt+鼠标滚轮 缩放
3、笔记本触摸板两指 缩放
3、笔记本触摸板+鼠标滚轮 移动
上图中也可以看到画布的外围区域也需要一个标尺,随着页面缩放来进行位置标识
ctrl+鼠标 / 笔记本触摸板+鼠标滚轮 移动
在mousedown事件触发的同时,记录鼠标位置X与Y,在mousemove事件中每次鼠标移动获取到新的位置X1和Y1,X1-X即横坐标上鼠标移动的距离,以此来改变中央画布区域的移动距离即可
alt+鼠标滚轮 / 笔记本触摸板两指 移动
在墨刀的缩放交互上有个有意思的地方
当鼠标悬停在某一个位置的时候,缩放页面就会以这个点为圆心进行放大缩小
这个如何来做呢?
可以简单画个草图
图中可以看到,假设某一时刻,鼠标悬停的位置坐标为(x1,y1),而页面的区域为(x2,y2),如果以鼠标位置缩放的话,假设缩放比例为Z,那么理论上页面区域的每个的点距离鼠标位置的距离都会变为Z倍。
也就是说当以点(x1,y1)放大Z倍后,页面区域的位置变化的距离为
(x2 - x1) * Z - (x2 - x1)
要注意,是变化的距离
原先x轴的距离是x2 - x1,放大Z倍后,会变成(x2 - x1) * Z,那么对比原先的距离应该移动多少呢,就是(x2 - x1) * Z - (x2 - x1)
最后化简为(Z - 1)* (x2 - x1)
y轴原理一样。
第一次成功了,当缩放成功之后,第二次继续缩放的时候,这里举个例子。
例如默认比例为1,第一次缩放为了1.2,第二次缩放肯定是在1.2的基础上再次缩放,例如变为了1.4,那么最后页面区域应该移动的距离是多少呢?
这里就不能再简单用1.4来通过上面的计算来得出结果了。
当我们缩放到1.4的时候,针对于原先的基础1.2缩放了几倍呢?
是(1.4 / 1.2)倍
最后,总结一下
当页面区域由Z1倍大小缩放到Z2倍大小的时候,页面区域的移动距离为。
X:(Z1 / Z2 - 1)* (x2 - x1)
Y:(Z1 / Z2 - 1)* (y2 - y2)
然后利用transform去改变页面区域的位置便能模拟出任意点为圆心放大缩小的效果了。
至于标尺部分,只需根据当前缩放以及页面区域的位置来计算刻度间距即可。
分享完毕,感谢您的阅读!