可视化拖拽组件库一些技术要点原理分析(四)(上)

简介: 可视化拖拽组件库一些技术要点原理分析(四)

本文是可视化拖拽系列的第四篇,比起之前的三篇文章,这篇功能点要稍微少一点,总共有五点:

  1. SVG 组件
  2. 动态属性面板
  3. 数据来源(接口请求)
  4. 组件联动
  5. 组件按需加载

如果你对我之前的系列文章不是很了解,建议先把这三篇文章看一遍,再来阅读本文(否则没有上下文,不太好理解):

另附上项目、在线 DEMO 地址:

SVG 组件

目前项目里提供的自定义组件都是支持自由放大缩小的,不过他们有一个共同点——都是规则形状。也就是说对它们放大缩小,直接改变宽高就可以实现了,无需做其他处理。但是不规则形状就不一样了,譬如一个五角星,你得考虑放大缩小时,如何成比例的改变尺寸。最终,我采用了 svg 的方案来实现(还考虑过用 iconfont 来实现,不过有缺陷,放弃了),下面让我们来看看具体的实现细节。

用 SVG 画一个五角星

假设我们需要画一个 100 * 100 的五角星,它的代码是这样的:

<svg 
    version="1.1" 
    baseProfile="full" 
    xmlns="http://www.w3.org/2000/svg"
>
    <polygon 
        points="50 0,62.5 37.5,100 37.5,75 62.5,87.5 100,50 75,12.5 100,25 62.5,0 37.5,37.5 37.5" 
        stroke="#000" 
        fill="rgba(255, 255, 255, 1)" 
        stroke-width="1"
    ></polygon>
</svg>

svg 上的版本、命名空间之类的属性不是很重要,可以先忽略。重点是 polygon 这个元素,它在 svg 中定义了一个由一组首尾相连的直线线段构成的闭合多边形形状,最后一点连接到第一点。也就是说这个多边形由一系列坐标点组成,相连的点之间会自动连上。polygon 的 points 属性用来表示多边形的一系列坐标点,每个坐标点由 x y 坐标组成,每个坐标点之间用 ,逗号分隔。

上图就是一个用 svg 画的五角星,它由十个坐标点组成 50 0,62.5 37.5,100 37.5,75 62.5,87.5 100,50 75,12.5 100,25 62.5,0 37.5,37.5 37.5。由于这是一个 100*100 的五角星,所以我们能够很容易的根据每个坐标点的数值算出它们在五角星(坐标系)中所占的比例。譬如第一个点是 p1(50,0),那么它的 x y 坐标比例是 50%, 0;第二个点 p2(62.5,37.5),对应的比例是 62.5%, 37.5%...

// 五角星十个坐标点的比例集合
const points = [
    [0.5, 0],
    [0.625, 0.375],
    [1, 0.375],
    [0.75, 0.625],
    [0.875, 1],
    [0.5, 0.75],
    [0.125, 1],
    [0.25, 0.625],
    [0, 0.375],
    [0.375, 0.375],
]

既然知道了五角星的比例,那么要画出其他尺寸的五角星也就易如反掌了。我们只需要在每次对五角星进行放大缩小,改变它的尺寸时,等比例的给出每个坐标点的具体数值即要。

<div class="svg-star-container">
    <svg
        version="1.1"
        baseProfile="full"
        xmlns="http://www.w3.org/2000/svg"
    >
        <polygon
            ref="star"
            :points="points"
            :stroke="element.style.borderColor"
            :fill="element.style.backgroundColor"
            stroke-width="1"
        />
    </svg>
    <v-text :prop-value="element.propValue" :element="element" />
</div>
<script>
function drawPolygon(width, height) {
    // 五角星十个坐标点的比例集合
    const points = [
        [0.5, 0],
        [0.625, 0.375],
        [1, 0.375],
        [0.75, 0.625],
        [0.875, 1],
        [0.5, 0.75],
        [0.125, 1],
        [0.25, 0.625],
        [0, 0.375],
        [0.375, 0.375],
    ]
    const coordinatePoints = points.map(point => width * point[0] + ' ' + height * point[1])
    this.points = coordinatePoints.toString() // 得出五角星的 points 属性数据
}
</script>

其他 SVG 组件

同理,要画其他类型的 svg 组件,我们只要知道它们坐标点所占的比例就可以了。如果你不知道一个 svg 怎么画,可以网上搜一下,先找一个能用的 svg 代码(这个五角星的 svg 代码,就是在网上找的)。然后再计算它们每个坐标点所占的比例,转成小数点的形式,最后把这些数据代入上面提供的 drawPolygon() 函数即可。譬如画一个三角形的代码是这样的:

function drawTriangle(width, height) {
    const points = [
        [0.5, 0.05],
        [1, 0.95],
        [0, 0.95],
    ]
    const coordinatePoints = points.map(point => width * point[0] + ' ' + height * point[1])
    this.points = coordinatePoints.toString() // 得出三角形的 points 属性数据
}

动态属性面板

目前所有自定义组件的属性面板都共用同一个 AttrList 组件。因此弊端很明显,需要在这里写很多 if 语句,因为不同的组件有不同的属性。例如矩形组件有 content 属性,但是图片没有,一个不同的属性就得写一个 if 语句。

<el-form-item v-if="name === 'rectShape'" label="内容">
   <el-input />
</el-form-item>
<!-- 其他属性... -->

幸好,这个问题的解决方案也不难。在本系列的第一篇文章中,有讲解过如何动态渲染自定义组件:

<component :is="item.component"></component> <!-- 动态渲染组件 -->

在每个自定义组件的数据结构中都有一个 component 属性,这是该组件在 Vue 中注册的名称。因此,每个自定义组件的属性面板可以和组件本身一样(利用 component 属性),做成动态的:

<!-- 右侧属性列表 -->
<section class="right">
    <el-tabs v-if="curComponent" v-model="activeName">
        <el-tab-pane label="属性" name="attr">
            <component :is="curComponent.component + 'Attr'" /> <!-- 动态渲染属性面板 -->
        </el-tab-pane>
        <el-tab-pane label="动画" name="animation" style="padding-top: 20px;">
            <AnimationList />
        </el-tab-pane>
        <el-tab-pane label="事件" name="events" style="padding-top: 20px;">
            <EventList />
        </el-tab-pane>
    </el-tabs>
    <CanvasAttr v-else></CanvasAttr>
</section>

同时,自定义组件的目录结构也需要做下调整,原来的目录结构为:

- VText.vue
- Picture.vue
...

调整后变为:

- VText
    - Attr.vue <!-- 组件的属性面板 -->
    - Component.vue <!-- 组件本身 -->
- Picture
    - Attr.vue
    - Component.vue

现在每一个组件都包含了组件本身和它的属性面板。经过改造后,图片属性面板代码也更加精简了:

<template>
    <div class="attr-list">
        <CommonAttr></CommonAttr> <!-- 通用属性 -->
        <el-form>
            <el-form-item label="镜像翻转">
                <div style="clear: both;">
                    <el-checkbox v-model="curComponent.propValue.flip.horizontal" label="horizontal">水平翻转</el-checkbox>
                    <el-checkbox v-model="curComponent.propValue.flip.vertical" label="vertical">垂直翻转</el-checkbox>
                </div>
            </el-form-item>
        </el-form>
    </div>
</template>

这样一来,组件和对应的属性面板都变成动态的了。以后需要单独给某个自定义组件添加属性就非常方便了。

目录
相关文章
|
4月前
|
JavaScript
从零开始写一套广告组件【一】搭建基础框架并配置UI组件库
其实这个从零有点歧义,因为本质上是要基于`tdesign-vue-next`来进行二次封装为一套广告UI组件库,现在让我们在一起快乐的搭建自己的广告UI库之前,先对以下内容做出共识:
112 0
从零开始写一套广告组件【一】搭建基础框架并配置UI组件库
|
5月前
|
C# 开发者 数据处理
WPF开发者必备秘籍:深度解析数据网格最佳实践,轻松玩转数据展示与编辑大揭秘!
【8月更文挑战第31天】数据网格控件是WPF应用程序中展示和编辑数据的关键组件,提供排序、筛选等功能,显著提升用户体验。本文探讨WPF中数据网格的最佳实践,通过DevExpress DataGrid示例介绍其集成方法,包括添加引用、定义数据模型及XAML配置。通过遵循数据绑定、性能优化、自定义列等最佳实践,可大幅提升数据处理效率和用户体验。
75 0
|
5月前
|
数据处理 开发者 C#
WPF数据绑定实战:从零开始,带你玩转数据与界面同步,让你的应用程序更上一层楼!
【8月更文挑战第31天】在WPF应用开发中,数据绑定是核心技能之一,它能实现界面元素与数据源的同步更新。本文详细介绍了WPF数据绑定的概念与实现方法,包括属性绑定、元素绑定及路径绑定等技术,并通过示例代码展示了如何创建数据绑定。通过数据绑定,开发者不仅能简化代码、提高可维护性,还能提升用户体验。无论初学者还是有经验的开发者,都能从中受益,更好地掌握WPF数据绑定技巧。
118 0
|
数据可视化 JavaScript
可视化拖拽组件库一些技术要点原理分析(二)(上)
可视化拖拽组件库一些技术要点原理分析(二)
117 1
|
数据可视化 API
可视化拖拽组件库一些技术要点原理分析(三)(二)
可视化拖拽组件库一些技术要点原理分析(三)(二)
112 0
|
数据可视化 索引
可视化拖拽组件库一些技术要点原理分析(二)
可视化拖拽组件库一些技术要点原理分析(二)
171 0
|
前端开发 C# 开发工具
Unity快手上手【熟悉unity编辑器,C#脚本控制组件一些属性之类的】
Unity快手上手【熟悉unity编辑器,C#脚本控制组件一些属性之类的】
167 0
|
容器
从零开始设计一个右键菜单组件
从零开始设计一个右键菜单组件
100 0
|
数据可视化 API 索引
可视化拖拽组件库一些技术要点原理分析(三)(三)
可视化拖拽组件库一些技术要点原理分析(三)(三)
150 0
|
JSON 数据可视化 前端开发
可视化拖拽组件库一些技术要点原理分析(二)(下)
可视化拖拽组件库一些技术要点原理分析(二)(下)
116 0

热门文章

最新文章