国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Svg Flow Editor 原生svg流程圖編輯器(五)

這篇具有很好參考價值的文章主要介紹了Svg Flow Editor 原生svg流程圖編輯器(五)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

系列文章

Svg Flow Editor 原生svg流程圖編輯器(一)

Svg Flow Editor 原生svg流程圖編輯器(二)

Svg Flow Editor 原生svg流程圖編輯器(三)

Svg Flow Editor 原生svg流程圖編輯器(四)

Svg Flow Editor 原生svg流程圖編輯器(五)

協(xié)同編輯

? ? ? ? 對協(xié)同這塊已經(jīng)寫了很多篇文章了,如果還是不了解,可以看看之前的文章哈,我們還是使用Yjs實現(xiàn)協(xié)同的底層支持,Websocket 還是以插件的形式支持:

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow? ? ? ? ?這次的協(xié)同,并沒有直接使用 y-websocket 插件支持,而是自己實現(xiàn)了websocket 相關(guān)的連接、異常、重連操作,y-websocket 插件無非就是內(nèi)部對協(xié)同數(shù)據(jù)做了合并,監(jiān)聽消息后觸發(fā) update更新:

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

?????????我們手動實現(xiàn),只需要對協(xié)同的數(shù)據(jù)進行底層的一致性沖突處理、合并就可以達到一樣的目的,如下:

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

? ? ? ? 在發(fā)送數(shù)據(jù)之前,需要先獲取本地的所有yjs數(shù)據(jù)狀態(tài) state,攜帶著一起發(fā)送給 websocket 服務(wù)器,其他客戶端收到后,先執(zhí)行解析合并操作,然后再從最終結(jié)果解析數(shù)據(jù),以達到數(shù)據(jù)一致性的目的。下列就是 yjs 的核心方法:

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

? ? ? ? 發(fā)送數(shù)據(jù)之前,進行數(shù)據(jù)映射:

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow? ? ? ? ?此類,我們就可以不基于 y-websocket插件,自身實現(xiàn)websocket服務(wù),也能使用yjs實現(xiàn)協(xié)同,保持?jǐn)?shù)據(jù)一致性,關(guān)鍵就是使用?encodeStateAsUpdate 進行本地數(shù)據(jù)獲取,applyUpdate 進行應(yīng)用更新,詳細(xì)解釋:

Document Updates | Yjs DocsHow to sync documents with other peers.https://docs.yjs.dev/api/document-updates#syncing-clients? ? ? ? 效果如下:Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

搜索替換

? ? ? ? 之前我們文本的實現(xiàn)方案是創(chuàng)建?contenteditable,然后移出時,創(chuàng)建了svg text,使得文本能顯示在元件上,但是這樣有些問題,不能進行搜索替換,因為svg的樣式與css樣式還不一致,因此在搜索結(jié)果的高亮顯示上還有些難以實現(xiàn)。

? ? ? ? 因此,我們替換方案為直接使用?contenteditable,移出時,控制樣式 point-event:none;user-select:none即可,在搜索高亮中,替換字符串為 b 標(biāo)簽,并加上css 控制,即可實現(xiàn)。

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

????????封裝搜索替換組件,并綁定快捷鍵 Ctrl + F

// 可以用 getSelection 獲取用戶目前選中的文本
const { anchorOffset, focusOffset, baseNode } = window.getSelection() as Selection;

// 搜索的核心就是遍歷目前頁面上的文本,判定內(nèi)容是否包含了搜索框文本
editorBox.querySelectorAll(".sf-editor-box-graphs-main-contenteditable").forEach((item) =>{
    // item 是 contenteditableBox 里面的 div 才是內(nèi)容
    const editor = item.querySelector("div") as HTMLDivElement;
    editor.innerHTML = editor.innerHTML.replace(/<|>|\/|b|span/g, "");
    const findFlag = editor.innerText.includes(this.keyword);
    findFlag &&this.keyword &&this.conformList.push(item as HTMLDivElement);
});

? ? ? ? ?在 數(shù)量上,則是記錄全局變量 index all,all是搜索匹配到的所有文本項,index 則是匹配到的當(dāng)前索引,替換的方案就是直接 replace 即可,實現(xiàn)效果如下:

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

表格

? ? ? ? 本來想用 luckysheet 實現(xiàn)表格的,但是想了想,還是太冗余了,流程圖中的表格盡量簡單就好了,主要做數(shù)據(jù)展示,不涉及復(fù)雜的計算,因此,還是用原生的table 實現(xiàn)吧。

  this.table = draw.createHTMLElement("table") as HTMLTableElement;
  this.table.classList.add("sf-editor-table");

  // 創(chuàng)建頭部 head
  private createHead(draw: Draw) {
    const thead = draw.createHTMLElement("thead");
    const tr = draw.createHTMLElement("tr");
    for (let i = 0; i < this.col; i++) {
      const th = draw.createHTMLElement("th");
      const div = draw.createHTMLElement("div");
      div.innerText = `標(biāo)題${i + 1}`;
      th.appendChild(div);
      tr.appendChild(th);
    }
    thead.appendChild(tr);
    this.table.appendChild(thead);
  }

  // 創(chuàng)建 tbody
  private createBody(draw: Draw) {
    const body = draw.createHTMLElement("tbody");
    for (let i = 0; i < this.row; i++) {
      const tr = draw.createHTMLElement("tr");
      for (let i = 0; i < this.col; i++) {
        const td = draw.createHTMLElement("td");
        const div = draw.createHTMLElement("div");
        td.appendChild(div);
        tr.appendChild(td);
      }
      body.appendChild(tr);
    }
    this.table.appendChild(body);
  }

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

? ? ? ? 文本編輯上,使用?contenteditable 實現(xiàn):

// 初始化 雙擊編輯事件
  private initEvent() {
    const divs = this.table.querySelectorAll("div");
    divs.forEach((item) => {
      item.addEventListener("dblclick", () => {
        item.setAttribute("contenteditable", "true");
        item.focus();
        this.setRange(item);
        item.addEventListener("blur", () =>
          divs.forEach((i) => i.removeAttribute("contenteditable"))
        );
      });
    });
  }

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow?? ? ? ? 效果與markdown的表格類似:

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

圖片導(dǎo)出

? ? ? ? 導(dǎo)出使用的是html2canva庫,在一些細(xì)節(jié)的處理上,需要看官網(wǎng)的說明,比如處理跨域圖片問題,寬高尺寸問題,還有的就是循環(huán)遍歷導(dǎo)致截圖過慢問題等,可以看出,每次使用插件導(dǎo)出圖片,都會從 HTML head 開始遍歷DOM結(jié)構(gòu),在我們的項目中影響不大,但是用戶的環(huán)境,可能有很多的dom,肯定會影響效率,我們導(dǎo)出圖片僅需要在 sf-editor-box 中做處理即可,因此,需要使用?ignoreElements 進行元素過濾。

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

? ? ? ? 沒有做過濾,整體的時間大概在435毫秒:

const option = {
      ignoreElements: (ele: HTMLElement) => {
        // this.editorBox compareDocumentPosition
        // 1: 沒有關(guān)系,這兩個節(jié)點不屬于同一個文檔
        // 2: 第一節(jié)點(P1)位于第二個節(jié)點后(P2)
        // 4: 第一節(jié)點(P1)定位在第二節(jié)點(P2)前
        // 8: 第一節(jié)點(P1)位于第二節(jié)點內(nèi)(P2)
        // 16:第二節(jié)點(P2)位于第一節(jié)點內(nèi)(P1)
        // 還可能是上訴值的和!返回 20 意味著在 p2 在 p1 內(nèi)部(16),并且 p1 在 p2 之前(4)
        const box = this.draw.getEditorBox();
        const index = box.compareDocumentPosition(ele);
        if ([1, 2, 4].includes(index)) return false;
      },
    };

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

? ? ? ? 優(yōu)化后的平均耗時 250毫秒,如果在大體量DOM結(jié)構(gòu)中,這個優(yōu)化會更加明顯。

  /**
   * 利用 html2canvas 截圖
   *  1. ignoreElements 處理截圖慢問題: (element) => false 與 root 進行位置比較
   *  2. x y width height 處理最佳寬高,不出現(xiàn)大量空白
   *  3. proxy、useCORS、allowTaint 處理跨域圖片問題
   *  4. backgroundColor 支持透明、白色背景(設(shè)置null為透明)
   * @param filetype 保存的文件類型,支持 png svg jpg json
   */
  public async screenShot(filetype: string) {
    await nextTick();
    const box = this.draw.getEditorBox();
    // const width = box.clientWidth;
    // const height = box.clientHeight;

    this.draw.showLoading();
    // 處理x y height width - 相對于 editor box 的位置關(guān)系
    var minx = 0;
    var miny = 0;
    var maxx = 0;
    var maxy = 0;
    // 獲取 editor box 的寬高
    const graphlist = this.draw.getGraphEvent().getAllGraphMain();
    if (graphlist.length) {
      const firstGraph = new Graph(
        this.draw,
        graphlist[0].getAttribute("graphid") as string
      );
      minx = firstGraph.getX();
      miny = firstGraph.getY();

      graphlist.forEach((item) => {
        // 需要得到最小和最大位置的graph
        const nodeID = item.getAttribute("graphid") as string;
        const graph = new Graph(this.draw, nodeID);
        minx = Math.min(minx, graph.getX());
        miny = Math.min(miny, graph.getY());
        maxx = Math.max(maxx, graph.getX() + graph.getWidth() + 20);
        maxy = Math.max(maxy, graph.getY() + graph.getHeight() + 20);
      });
    }

    const option = {
      x: minx,
      y: miny,
      width: maxx - minx,
      height: maxy - miny,
      ignoreElements: (ele: HTMLElement) => {
        // this.editorBox compareDocumentPosition
        // 1: 沒有關(guān)系,這兩個節(jié)點不屬于同一個文檔
        // 2: 第一節(jié)點(P1)位于第二個節(jié)點后(P2)
        // 4: 第一節(jié)點(P1)定位在第二節(jié)點(P2)前
        // 8: 第一節(jié)點(P1)位于第二節(jié)點內(nèi)(P2)
        // 16:第二節(jié)點(P2)位于第一節(jié)點內(nèi)(P1)
        // 還可能是上訴值的和!返回 20 意味著在 p2 在 p1 內(nèi)部(16),并且 p1 在 p2 之前(4)
        const index = box.compareDocumentPosition(ele);
        if ([1, 2, 4].includes(index)) return false;
      },
    };

    // @ts-ignore
    const canvas = await html2canvas(this.draw.getEditorBox(), option);
    // base64 使用服務(wù)器存儲方案  const base64 = canvas.toDataURL("image/png");

    canvas.toBlob((b: File) => {
      const url = toBlob(b, "image/png") as string;
      const a = this.draw.createHTMLElement("a");
      a.setAttribute("href", url);
      a.setAttribute("download", "測試");
      this.draw.hideLoading();
      window.open(url);
      // a.click(); // 觸發(fā)下載
      a.remove();
    });
  }

Svg Flow Editor 原生svg流程圖編輯器(五),svg-flow-editor流程圖,流程圖,編輯器,html2canvas,svg flow

總結(jié)

? ? ? ? 至此,該實現(xiàn)的功能基本上都已經(jīng)具備雛形了,后面就不再更新文章咯,但是還是會持續(xù)更新這個庫,大家有什么想法,需要什么BUG,都可以在git、文章下留言,我會持續(xù)關(guān)注大家的意見,維護這個庫。

? ? ? ? 即將發(fā)布的 1.0.15 版本,是1.0版本的最后一版,后續(xù)的版本將更替為 1.1 ,主要實現(xiàn)協(xié)同、相關(guān)工具類、以及關(guān)鍵的 history歷史記錄。目前市面上也有很多成熟的產(chǎn)品,做這個主要不是為了超越他們,而是熟悉流程圖的底層實現(xiàn)、TypeScript的應(yīng)用、以及主要的提升自我能力,望大家理性看待~

? ? ? ? 感謝大家的支持與理解!文章來源地址http://www.zghlxwxcb.cn/news/detail-849143.html

到了這里,關(guān)于Svg Flow Editor 原生svg流程圖編輯器(五)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 流程圖實現(xiàn),基于vue2實現(xiàn)的流程圖

    流程圖實現(xiàn),基于vue2實現(xiàn)的流程圖

    flex布局 + 偽元素實現(xiàn)豎直的連接線+組件遞歸 2.1基礎(chǔ)的(未截全,大致長這樣) ?2.2帶有收縮功能的,可以展開和收縮并顯示數(shù)量 ? ? 4.項目源碼地址 GitHub - yft-code/flow: 流程圖 純css實現(xiàn)流程圖

    2024年02月16日
    瀏覽(27)
  • 流程圖如何制作?5步快速畫出好看的流程圖!

    流程圖如何制作?5步快速畫出好看的流程圖!

    流程圖是一種圖形化工具,描述某個過程或者操作的步驟,以及某種業(yè)務(wù)系統(tǒng)的具體流程。流程圖通常由各種圖形符號、形狀、箭頭組成,可以清晰的表示出流程或系統(tǒng)中各種步驟、每個環(huán)節(jié)之間的關(guān)系、條件判斷、數(shù)據(jù)的流動和處理過程等。 ? ? ? ? ? 對于負(fù)責(zé)策劃的職場

    2024年02月14日
    瀏覽(19)
  • Qt (高仿Visio)流程圖組件開發(fā)(七) 流程圖 簡單操作界面搭建

    Qt (高仿Visio)流程圖組件開發(fā)(七) 流程圖 簡單操作界面搭建

    Qt (高仿Visio)流程圖組件開發(fā)(一) 效果展示及基本開發(fā)框架構(gòu)思 Qt (高仿Visio)流程圖組件開發(fā)(二) 基本圖元繪制 圖元間連線繪制 Qt (高仿Visio)流程圖組件開發(fā)(三) 圖元基類如何定義,流程圖多種圖元類型實現(xiàn) Qt (高仿Visio)流程圖組件開發(fā)(四) 流程圖 圖元

    2023年04月25日
    瀏覽(26)
  • Python 代碼一鍵轉(zhuǎn)流程圖---python=>flowchart-dsl=>流程圖

    Python 代碼一鍵轉(zhuǎn)流程圖---python=>flowchart-dsl=>流程圖

    這個項目是基于大名鼎鼎的 flowchart.js。 下面貼幾張運行圖片: ?如果直接輸入dsl代碼,再進行轉(zhuǎn)化就可以很好的畫出流程圖 ? ? ? 如果你使用 Typora,可能知道在 Typora 中用?flow?可以用一種簡單的文本語言來寫流程圖,根據(jù)?Typora 的文檔,這個功能來自開源的?flowchart.js。

    2024年02月08日
    瀏覽(35)
  • 提升繪圖效率不再難,看看這8款A(yù)I流程圖軟件,一鍵快速生成流程圖!

    提升繪圖效率不再難,看看這8款A(yù)I流程圖軟件,一鍵快速生成流程圖!

    流程圖是表示流程、系統(tǒng)和思想的重要視覺輔助工具。在當(dāng)今數(shù)字時代,AI技術(shù)的出現(xiàn)已經(jīng)徹底改變了制作流程圖的方式。 在本文中,我們將與各位分享 8款好用的AI流程圖軟件 ,借助每款軟件內(nèi)置的AI能力,可以快速繪制出一份完整的流程圖,以簡化和增強你的繪圖體驗。

    2024年02月03日
    瀏覽(29)
  • springboot啟動流程源碼解析(帶流程圖)

    springboot啟動流程源碼解析(帶流程圖)

    本文自己寫的(頭條也有這篇文章),若有問題,請指正。 大致流程如下: 1. 初始化SpringApplication,從META-INF下的spring.factories讀取 ApplicationListener/ApplicationContextInitializer 2.運行SpringApplication的run方法 3.讀取項目中環(huán)境變量、jvm配置信息、配置文件信息等 4.創(chuàng)建Spring容器對象(

    2024年02月08日
    瀏覽(26)
  • 純css流程圖

    純css流程圖

    ? ?

    2024年02月11日
    瀏覽(22)
  • Mermaid流程圖

    Mermaid流程圖

    mermaid簡介 Mermaid是一個基于JavaScript的繪圖工具,使用類似于Markdown的語法,允許用戶通過代碼創(chuàng)建各種圖表,包括流程圖、狀態(tài)圖、時序圖和甘特圖等。它可以將代碼塊轉(zhuǎn)化為HTML代碼,并支持多種圖表的方向。Mermaid極大地簡化了復(fù)雜圖的繪制和維護,對于熟悉Markdown語法的用

    2024年01月19日
    瀏覽(55)
  • 產(chǎn)品流程圖

    產(chǎn)品流程圖

    3.1業(yè)務(wù)流程圖 | 泳道圖(給產(chǎn)品經(jīng)理看) 3.2任務(wù)流程圖(給程序員看) 3.3頁面流程圖(給UI設(shè)計人員看) 4.1調(diào)查研究 4.2梳理提煉 4.3 確認(rèn)評估 4.4 維護更新 3.1業(yè)務(wù)流程圖 | 泳道圖(給產(chǎn)品經(jīng)理看) 3.2任務(wù)流程圖(給程序員看) 3.3頁面流程圖(給UI設(shè)計人員看) 4.1調(diào)查研究

    2024年02月16日
    瀏覽(23)
  • 讓流程圖動起來

    讓流程圖動起來

    我們平時畫流程,然后貼到文檔,就完事了。但是過程演示的時候,如果只是一張靜態(tài)圖,很難吸引到聽眾的注意力,表達效果并不太好。常用的方法是可以用PPT進行動態(tài)演示,做PPT也是需要花一些時間,同時表達也比較有限。下面介紹一下基于突突圖(Procviz)的流程圖動畫生

    2024年04月28日
    瀏覽(54)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包