全網最詳bpmn.js教材-自定義contextPad篇

前言

Q: bpmn.js是什麼? 🤔️css

bpmn.js是一個BPMN2.0渲染工具包和web建模器, 使得畫流程圖的功能在前端來完成.前端

Q: 我爲何要寫該系列的教材? 🤔️vue

由於公司業務的須要於是要在項目中使用到bpmn.js,可是因爲bpmn.js的開發者是國外友人, 所以國內對這方面的教材不多, 也沒有詳細的文檔. 因此不少使用方式不少坑都得本身去找.在將其琢磨完以後, 決定寫一系列關於它的教材來幫助更多bpmn.js的使用者或者是期於找到一種好的繪製流程圖的開發者. 同時也是本身對其的一種鞏固.git

因爲是系列的文章, 因此更新的可能會比較頻繁, 您要是無心間刷到了且不是您所須要的還請諒解😊.github

不求贊👍不求心❤️. 只但願能對你有一點小小的幫助.web

自定義ContextPad篇

通過前面幾章的學習, 相信你們都已經掌握了自定義paletterenderer, 這一章節主要講解的是自定義contextPad.hexo

先讓咱們來回顧一下, contextPad是什麼?app

如圖, 能夠看到除了在左側的工具欄處能添加節點以外, 點擊節點的時候也會出現一個小彈窗, 這裏面也能夠添加節點. 這個小彈窗就是 contextPad.編輯器

那麼, 經過閱讀你能夠學習到:ide

在默認的ContextPad基礎上修改

前期準備

讓咱們接着在LinDaiDai/bpmn-vue-custom案例項目上進行開發.

components文件夾下新建一個custom-context-pad.vue文件, 同時配置路由「自定義contextPad」.

components/custom文件夾下新建一個CustomContextPad.vue文件, 用來自定義contextPad.

編寫CustomContextPad.vue代碼

其實自定義contextPadpalette很像, 只不過是使用contextPad.registerProvider(this)來指定它是一個contextPad, 而自定義palette是用platette.registerProvider(this).

代碼以下:

// CustomContextPad.js
export default class CustomContextPad {
    constructor(config, contextPad, create, elementFactory, injector, translate) {
        this.create = create;
        this.elementFactory = elementFactory;
        this.translate = translate;

        if (config.autoPlace !== false) {
            this.autoPlace = injector.get('autoPlace', false);
        }

        contextPad.registerProvider(this); // 定義這是一個contextPad
    }

    getContextPadEntries(element) {}
}

CustomContextPad.$inject = [
    'config',
    'contextPad',
    'create',
    'elementFactory',
    'injector',
    'translate'
];
複製代碼

相信你們都已經看出來了, 重點仍是在於getContextPadEntries這個方法, 接下來讓咱們來構建這個方法.

編寫getContextPadEntries代碼

其實這個方法, 須要返回的也是一個對象, 也就是你要在contextPad這個容器裏顯示哪些自定義的元素, 好比我這裏須要給容器裏添加一個lindaidai-task的元素, 那麼咱們能夠在返回的對象中添加上append.lindaidai-task這個屬性.

而屬性值就是這個元素的一系列配置, 和palette中同樣, 包括:

  • group: 屬於哪一個分組, 好比 tools、event、gateway、activity等等,用於分類
  • className: 樣式類名, 咱們能夠經過它給元素修改樣式
  • title: 鼠標移動到元素上面給出的提示信息
  • action: 用戶操做時會觸發的事件

大概是這樣:

// CustomContextPad.js
getContextPadEntries(element) {
    return {
        'append.lindaidai-task': {
            group: 'model',
            className: 'icon-custom lindaidai-task',
            title: translate('建立一個類型爲lindaidai-task的任務節點'),
            action: {
                click: appendTask,
                dragstart: appendTaskStart
            }
        }
    };
}
複製代碼

接下來就是構建appendTaskappendTaskStart

// CustomContextPad.js
getContextPadEntries(element) {
        const {
            autoPlace,
            create,
            elementFactory,
            translate
        } = this;

        function appendTask(event, element) {
            if (autoPlace) {
                const shape = elementFactory.createShape({ type: 'bpmn:Task' });
                autoPlace.append(element, shape);
            } else {
                appendTaskStart(event, element);
            }
        }

        function appendTaskStart(event) {
            const shape = elementFactory.createShape({ type: 'bpmn:Task' });
            create.start(event, shape, element);
        }

        return {
            'append.lindaidai-task': {
                group: 'model',
                className: 'icon-custom lindaidai-task',
                title: translate('建立一個類型爲lindaidai-task的任務節點'),
                action: {
                    click: appendTask,
                    dragstart: appendTaskStart
                }
            }
        };
    }
}
複製代碼

這裏和palette中有一點不一樣, 就是多了一層autoPlace的判斷, 其實我也沒太搞明白這個autoPlace的做用是什麼, 自動放置? 並且官方給的例子🌰就是這麼寫的, 有知道的小夥伴還請評論區留言哦, 謝謝~

修改contextPad的相關樣式

此時咱們看看效果吧😄...

bpmnCustom16.png
bpmnCustom16.png

咿~ 好像能夠耶, 可是, 這個小積木也過小了一點吧😅, 並且鼠標移上去以後, 黃色的背景色直接就覆蓋它了...

bpmnCustom17.png
bpmnCustom17.png

哇, 這不能忍啊...

得想法子解決它, 還我漂亮的小積木❤️...

接着讓咱們打開控制檯審查元素, 能夠發現這個背景色是一個叫.djs-context-pad .entry的類提供的樣式, 也許, 咱們能夠全局修改這個樣式, 讓咱們試試看:

/* app.css */

/* 自定義 contextPad 的樣式 */ .djs-context-pad .lindaidai-task.entry:hover { background: url('hexo-blog-1256114407.cos.ap-shenzhen-fsi.myqcloud.com/rules.png') center no-repeat!important; background-size: cover!important; }

.djs-context-pad .entry:hover { /* 從新修改了 hover 以後的樣式 */ border: 1px solid #1890ff; }

複製代碼.djs-context-pad .entry { box-sizing: border-box; background-size: 94%; transition: all 0.3s; } 複製代碼

打開頁面看看效果哈.

bpmnCustom18.png
bpmnCustom18.png

不錯, 解決了, 哈哈😄.

(直接修改樣式雖然不是最好的解決辦法, 但這是目前我能想到的辦法, 並且它確實也可以解決問題)

徹底自定義ContextPad

前期準備

一樣的, 若是你已經學會了在默認的ContextPad基礎上修改, 那麼徹底自定義ContextPad也就差很少了😁.

不過徹底自定義ContextPad不是叫contextPad, 而是contextPadProvider, 好像要更厲害一點🤭...

OK👌, 讓咱們在customModeler/custom文件夾下新建一個CustomContextPadProvider.js文件.

編寫CustomContextPadProvider.js代碼

先讓咱們來看下主要的結構:

// CustomContextPadProvider.js
export default function ContextPadProvider(contextPad, config, injector, translate, bpmnFactory, elementFactory, create, modeling, connect) {
  this.create = create
  this.elementFactory = elementFactory
  this.translate = translate
  this.bpmnFactory = bpmnFactory
  this.modeling = modeling
  this.connect = connect
  config = config || {}
  if (config.autoPlace !== false) {
      this._autoPlace = injector.get('autoPlace', false)
  }
  contextPad.registerProvider(this)
}

ContextPadProvider.$inject = [
  'contextPad',
  'config',
  'injector',
  'translate',
  'bpmnFactory',
  'elementFactory',
  'create',
  'modeling',
  'connect'
]

ContextPadProvider.prototype.getContextPadEntries = function(element) {}
複製代碼

別看上面代碼很長的樣子, 其實沒啥東西:

  • 定義一個 ContextPadProvider類, 而後引入一些咱們後面要用到的方法或者屬性
  • 經過 $inject注入進來
  • 重寫原型鏈上的 getContextPadEntries方法

編寫getContextPadEntries代碼

你應該也發現了, 重點仍是重寫getContextPadEntries這個方法.

額, 這裏我先以一個簡單的爲例, 先只是建立一個lindaidai-task. 所以能夠直接把在默認的ContextPad基礎上修改案例中的getContextPadEntries中的代碼複製過來:

// CustomContextPad.js
getContextPadEntries(element) {
        const {
            autoPlace,
            create,
            elementFactory,
            translate
        } = this;

        function appendTask(event, element) {
            if (autoPlace) {
                const shape = elementFactory.createShape({ type: 'bpmn:Task' });
                autoPlace.append(element, shape);
            } else {
                appendTaskStart(event, element);
            }
        }

        function appendTaskStart(event) {
            const shape = elementFactory.createShape({ type: 'bpmn:Task' });
            create.start(event, shape, element);
        }

        return {
            'append.lindaidai-task': {
                group: 'model',
                className: 'icon-custom lindaidai-task',
                title: translate('建立一個類型爲lindaidai-task的任務節點'),
                action: {
                    click: appendTask,
                    dragstart: appendTaskStart
                }
            }
        };
    }
}
複製代碼

此時讓咱們先看看效果哈:

bpmnCustom19
bpmnCustom19

效果好像是實現了, 並且點擊和拖拽它也能實現建立lindaidai-task的效果...

但總感受好像少了什麼, 由於光建立task類型但元素是不夠的呀, 可不能夠建立線或者實現編輯, 刪除元素的功能呢? 固然能夠啦, 哈哈😄.

不過這一章節先說這麼多, 如何建立線和實現編輯, 刪除我會把它放到一下章來細講哈😊, 不用着急.

後語

上面👆案例用的都是同一個項目🦐

項目案例Git地址: LinDaiDai/bpmn-vue-custom 喜歡的小夥伴請給個Star🌟呀, 謝謝😊

系列相關推薦:

《全網最詳bpmn.js教材-基礎篇》

《全網最詳bpmn.js教材-http請求篇》

《全網最詳bpmn.js教材-事件篇》

《全網最詳bpmn.js教材-renderer篇》

《全網最詳bpmn.js教材-編輯、刪除節點篇》

相關文章
相關標籤/搜索