(十)、kityminder支持富文本的编辑

news2025/7/9 17:39:36

前段时间,去试用了下processon 上的脑图功能,发现人家这块确实已经做的好强大了。而且他的节点竟然还可以支持单独某个文本的颜色字体的设置,这个可是连xmind,本身都没有实现的功能的。所以想着学习下人家的实现看看是否能够借鉴到我们的平台上来。

现实很残酷

看了下process on的实现, 发现它跟百度的kityminder差别还是很大的,因为他的每个节点其实都是div的方式实现的,但是百度脑图的节点其实一个个都是svg。 我们可以看下。

ProcessOn

在这里插入图片描述

百度脑图

在这里插入图片描述

所以这块的参考意义就真的不大了,目前是没有能力去改动到脑图的底层内容的,所以还是只能顺着现有的框架改是最方便快捷的了。

具体变更点

要让原本的antd组件的 TextArea 支持富文本内容是不太可能的,所以我们这里更多还是需要引入一个富文本的组件才可以,这里我们直接就考虑用 braft-editor , 主要是这个组件在我们其他项目中用过,所以用的其实会比较多一些了。

现在我们要考虑一个问题,新的富文本组件需要满足哪些我们特殊的需求,然后我们需要考虑如何进行改造。

这里关键的因素其实就是我们需要做如下的内容 富文本转换后的html的内容,如何让 kityminder-core 识别到并且针对这个文本做相应的颜色标识出来。我们发现富文本转换后的html样式如果带有颜色的情况下基本上这样子的内容: <span style="color:#cccccc">太阳</span>

但是我们需要将这样子的文本内容转换成类似于 <text fill="#cccccc">太阳</text> 这样子的内容。那直接用一些正则替换的方式不就可以了吗?

问题其实那么简单,最关键的一个问题先出来了,我们举个栗子来说明下。

svg的一个文本标签,是默认就进行换行的我们可以看下:

在这里插入图片描述

但是如果我们通过富文本进行颜色以后如 下图所示

在这里插入图片描述

这样子的一个富文本内容其实应该要放到同一行, 但是对于svg来说由于需要将这两个文本变成两个svg, 同时还要在同一行,这个就是我们需要去解决的问题了。

另外: 替换为富文本的情况还需要满足一下的内容:

  1. 仅支持文本颜色修改,暂时不支持其他的富文本内容:字体大小,图片,音频等内容。
  2. 需要响应一些特殊按键操作
    1. 回车不是换行,而是完成文本输出
    2. 通过shift+enter进行换行
    3. 选中文本的时候才显示出工具栏的颜色修改按钮

解决

最重点是要解决富文本内容转换到svg节点的逻辑,这里我们需要改动到的是 text 这块的代码

var textArrTemp = nodeText ? nodeText.split(/\r\n|\n/) : [" "];
// 这里存储包含有富文本的内容
var textArr = [];

for (var index in textArrTemp) {
    if (textArrTemp[index].indexOf("<span style") !== -1 || textArrTemp[index].indexOf("</span>") !== -1) {
        var newArray = textArrTemp[index].split(/<span\s|<\/span>/)
        if (newArray.length > 1) {
            newArray = newArray.filter(function (item) {
                return item != "";
            });
        }
        for (var i in newArray) {
            textArr.push(newArray[i]);
        }
    } else {
        textArr.push(textArrTemp[index]);
    }
}

var originTextArr = nodeText ? nodeText.split(/\r\n|\n/) : [" "];
for (var index in originTextArr) {
    // 这个是富文本的标签切割了,需要提取出真正的内容出来
    if (originTextArr[index].indexOf("<span style") !== -1 || originTextArr[index].indexOf("</span>") !== -1) {
        originTextArr[index] = originTextArr[index].replace(/<span style(.*?)>/g, "").replace(/<\/span>/g, "");
    }
}

// 这里将带有<span>格式的做过滤将颜色跟实际的文本做一个map存储起来。
for (var i = 0; i < textArr.length; i++) {
    if (textArr[i].indexOf("style=") !== -1) {
        var m = textArr[i].match(/style="color:(.*?)">/);
        var n = textArr[i].match(/>(.*)/);
        colorMap[i] = {
            color: m[1],
            text: n[1]
        };
    }
}

以上这块就是针对文本的预处理的情况。下来还要到渲染处

return function () {
  var isContainOriginText = function (originTextArr, text) {
      for (var i in originTextArr) {
          if (originTextArr[i].indexOf(text) === 0) {
              return true;
          }
      }
      return false
  }

  var line = 0;
  var keys = Object.keys(colorMap);
  textGroup.eachItem(function (i, textShape) {
      // 这里要判断自己在不在里面 同时要判断我的上一个节点在不在里面
      var y;
      // 如果这个节点是在colorMap中,说明他是一个颜色标签的,  另外  还需要把颜色标签后面的文本也放到同一行去。
      if (i in colorMap && i === 0 || i !== 0 && i - 1 in colorMap && !isContainOriginText(originTextArr, textShape.getContent()) || i !== 0 && i in colorMap && !isContainOriginText(originTextArr, textShape.getContent())) {
          y = yStart + i * fontSize * lineHeight;
          var lastTextShape = textGroup.getItem(i == 0 ? 0 : i - 1);
          var lastBbox = textGroup.getItem(i == 0 ? 0 : i - 1).getBoundaryBox();
          textShape.setX(i === 0 ? 0 : lastBbox.width == 0 ? (parseFloat(lastTextShape.getAttr("x")) + 10) : lastBbox.x + lastBbox.width);
          textShape.setY(i === 0 ? y : lastBbox.y == 0 ? lastTextShape.getAttr('y') : lastBbox.y);
          if (i in colorMap) {
              textShape.setAttr("fill", colorMap[i].color);
          } else {
              textShape.setAttr("fill", "");
          }
          if (i === 0) {
              line++;
          }
          rBox = rBox.merge(new kity.Box(0, textShape.getY(), textShape.getX() + textShape.getBoundaryBox().width || 1, fontSize));
      } else {
          y = yStart + line * fontSize * lineHeight;
          textShape.setY(y);
          textShape.setX(0);
          textShape.setAttr("fill", i in colorMap ? colorMap[i].color : "");
          var bbox = textShape.getBoundaryBox();
          line++;
          rBox = rBox.merge(new kity.Box(0, y, bbox.height && bbox.width || 1, fontSize));
      }
  });
  var nBox = new kity.Box(r(rBox.x), r(rBox.y), r(rBox.width), r(rBox.height));
  node._currentTextGroupBox = nBox;
  return nBox;
};

逻辑有点小复杂了,但是其实就是针对svg做设置颜色,同时需要处理好,如果是富文本且为换行的话,需要通过x, y的属性去设置svg的位置。这样子就可以做到svg在同一行的情况了这里主要 通过上一个box x坐标以及宽度,然后算出当前的svg的box 应该放置的位置的位置

至于富文本其他功能就比较简单了,很多都是通过监听document的事件来满足一些特殊的需求即可了。

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

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

相关文章

会声会影2023电脑版下载及系统配置要求

平时大家可能会经常听到有人说会声会影&#xff0c;但是很多人都不知道这是什么软件。其实听它的名字就知道这是一款和声音、影像有关系的软件。下面&#xff0c;小编就来给大家具体介绍一下这款软件吧。 会声会影是一套操作简单的DV、HDV影片剪辑软件。会声会影不仅完全符合家…

Python并发编程-事件驱动模型

一、事件驱动模型介绍 1、传统的编程模式 例如&#xff1a;线性模式大致流程 开始--->代码块A--->代码块B--->代码块C--->代码块D--->......---&…

利用InceptionV3实现图像分类

最近在做一个机审的项目&#xff0c;初步希望实现图像的四分类&#xff0c;即&#xff1a;正常&#xff08;neutral&#xff09;、涉政&#xff08;political&#xff09;、涉黄&#xff08;porn&#xff09;、涉恐&#xff08;terrorism&#xff09;。有朋友给推荐了个github上…

ubuntu:20.04编译arrow

1)拉取代码 git clone https://github.com/apache/arrow.git 2&#xff09;切换分支 git checkout apache-arrow-11.0.0 3)拉入测试数据并设置环境变量 pushd arrow git submodule update --init export PARQUET_TEST_DATA"${PWD}/cpp/submodules/parquet-testing/da…

java程序员要了解的sql语句优化技巧大全

sql语句规范 MySQL在Linux系统下数据库名&#xff0c;表名&#xff0c;存储过程名&#xff0c;函数名称&#xff0c;触发器名称等区分大小写&#xff0c;列名不区分大小写&#xff0c;原因是这些操作系统下文件名称区分大小写。 MySQL在Windows系统下全部不区分大小写&#xf…

算法设计与分析期末考试复习(一)

递归 程序调用自身的编程技巧称为递归。 在调用函数时系统需要完成3件事&#xff1a; 将所有实参&#xff08;指针&#xff09;&#xff0c;返回地址传递给被调用的函数为被调用函数的局部变量分配存储区将控制转移到被调用函数的入口 从被调用函数返回时系统也要做3件事&am…

最近一直在做优化

大家好啊&#xff0c;好久没写文章了&#xff0c;最近收到了一些朋友的微信&#xff0c;问还写不写文章。 当然会继续写&#xff0c;只不过最近工作和生活忙的焦头烂额&#xff0c;一直没抽出时间来好好整理下自己&#xff0c;重整旗鼓继续写文。 总的来说&#xff0c;被两件…

C语言的学习小结——数组

一、一维数组的创建与初始化 1、格式&#xff1a; type_t arr_name[const_n];//type_t 是指数组的元素类型 //const_n 是一个常量表达式&#xff0c;用来指定数组的大小 注&#xff1a; 数组是使用下标来访问的&#xff0c;下标从0开始。 数组的大小可以通过计算得到&…

问卷调查设计-SurveyJS的使用(定制)

前言 距离上一次记录SurveyJS的文章已经过去大半个月了&#xff0c;也该完结一下子了&#xff0c;正好项目结束&#xff0c;抽出时间记录一下使用SurveyJS过程中的做的一些自定义配置需要哪些方法及属性&#xff08;这里根据个人项目需要做的一些方法总结&#xff0c;不包含全…

【2023】华为OD机试真题Java-题目0221-AI处理器组合

AI处理器组合 题目描述 某公司研发了一款高性能AI处理器。每台物理设备具备8颗AI处理器,编号分别为0、1、2、3、4、5、6、7。编号0-3的处理器处于同一个链路中,编号4-7的处理器处于另外一个链路中,不通链路中的处理器不能通信,如下图所示。现给定服务器可用的处理器编号数…

这才叫装机必备,这3款高质量电脑软件,内存满了也绝不卸载

闲话少说&#xff0c;直上狠货。 1、quicker quicker是一款指尖电脑工具&#xff0c;使用它实现常用操作&#xff0c;就在手边&#xff0c;点击鼠标中键&#xff0c;即可弹出&#xff0c;位置跟随鼠标&#xff0c;面板窗口的下半部分&#xff0c;它会随当前操作的软件自动加载设…

【Yolov5】保姆级别源码讲解之-推理部分detect.py文件

推理部分之detect.py文件讲解1.下载Yolov5的源码2. 主函数讲解3.文件标头的注释4. main函数的5. run函数5.1 第一块参数部分5.2第二块&#xff0c;传入数据预处理5.3 第三块创建文件夹5.4 第四块 加载模型的权重5.5 第五块 Dataloader 加载模块5.6 第六块 推理部分 Run inferen…

python 魔法方法之 __ slots __

python 魔法方法之 __ slots __ __ slots __ __slots__是python class的一个特殊attribute&#xff0c;能够节省内存空间。正常情况下&#xff0c;一个类的属性是以字典的形式来管理, 每个类都会有__ dict__ 方法。但是我们可以通过 设置 __ slots__ 来将类的属性构造成一个静…

input 子系统

简介 先来了解什么是输入设备&#xff1f; 常见的输入设备有键盘、 鼠标、 遥控杆、 书写板、 触摸屏等等,用户通过这些输入设备与 Linux 系统进行数据交换。 什么是输入系统&#xff1f; 输入设备种类繁多&#xff0c; 能否统一它们的接口&#xff1f; 既在驱动层面统一&…

springboot+vue邯郸地标美食导游平台

设计者应有软件程序开发方面的专业理论基础知识&#xff0c;有一定的分析和解决问题的能力&#xff0c;有一定的收集、整理、信息检索等方面的能力&#xff0c;善于综合、勤于思考&#xff0c;具有一丝不苟&#xff0c;精益求精&#xff0c;刻苦钻研的工作精神&#xff0c;勇于…

基于遗传算法的柔性生产调度研究(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…

S-Paper电子纸在生产车间中的应用

S-Paper电子纸在生产车间中的应用应用背景在传统的制造企业的生产流程中&#xff0c;生产线上的工件信息&#xff0c;加工信息等等在生产前都需要生产车间打印出来&#xff0c;然后再分发至生产线上对应的工件工位&#xff0c;纸张都是使用完后都是作废销毁&#xff0c;这样下来…

SQL零基础入门学习(九)

SQL零基础入门学习&#xff08;八&#xff09; SQL UNION 操作符 UNION 操作符用于合并两个或多个 SELECT 语句的结果集。 请注意&#xff0c;UNION 内部的每个 SELECT 语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时&#xff0c;每个 SELECT 语句中的列的顺序…

Xmake v2.7.7 发布,支持 Haiku 平台,改进 API 检测和 C++ Modules 支持

layout: post.cn title: “Xmake v2.7.7 发布&#xff0c;支持 Haiku 平台&#xff0c;改进 API 检测和 C Modules 支持” tags: xmake lua C/C package modules haiku cmodules categories: xmake Xmake 是一个基于 Lua 的轻量级跨平台构建工具。 它非常的轻量&#xff0c;没…

Android仿京东金融的数值滚动尺功能

自定义数值滚动尺,这个用的还是挺多的&#xff0c;例如京东金融的通过滚动尺选择金额等,而这次就是高仿京东金融的数值滚动尺。首先看看下效果图&#xff0c;如下&#xff1a;首先先给你们各个变量的含义&#xff0c;以免在后面的讲解中不知变量的意思&#xff0c;代码如下://最…