精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

圖形編輯器開發:模塊間如何通信?

開發 前端
本文簡單介紹了圖形編輯器架構中,如何進行模塊間的通信。對于某個模塊間,可以通過入口 Editor 對象,輕松主動訪問任何其他模塊。此外還可以用事件發布訂閱的方式綁定監聽器,在對應模塊狀態更新后被動地獲得通知。

大家好,我是前端西瓜哥。

圖形編輯器,隨著功能的增加,通常都會愈發復雜,良好的架構是保證圖形編輯器持續開發高效的重要技術。

根據功能拆分成一個一個的小模塊基本是家常便飯。那么模塊之間是如何配合以及進行數據傳輸的呢?

編輯器 github 地址:

https://github.com/F-star/suika

線上體驗:

https://blog.fstars.wang/app/suika/

注入 Editor 實例

首先我們有一個主模塊,也是入口模塊,叫做 Editor。

為了高內聚低耦合,其下會根據功能拆分出很多的子模塊。

這是為了讓我們要改造特定的功能時,只需要改對應模塊的小范圍代碼,不會被其他模塊代碼干擾,也不需要去理解它們。

子模塊會在 Editor 初始化的時候,將 Editor 實例對象注入(大概算是一種依賴注入)。

class Editor {
  sceneGraph: SceneGraph;
  setting: Setting;
  viewportManager: ViewportManager;
  toolManager: ToolManager;
  commandManager: CommandManager;
  zoomManager: ZoomManager;
  hostEventManager: HostEventManager;
  selectedElements: SelectedElements;

  // ...

  constructor(options: IEditorOptions) {
    // 也有些模塊不需要和其他模塊通信
    this.setting = new Setting();
    
    // 將 Editor 示例作為子模塊的構造參數
    this.sceneGraph = new SceneGraph(this);
    this.viewportManager = new ViewportManager(this);
    this.toolManager = new ToolManager(this);
    this.commandManager = new CommandManager(this);
    this.zoomManager = new ZoomManager(this);
    this.selectedElements = new SelectedElements(this);
    // ...
    this.hostEventManager = new HostEventManager(this);
    
    this.hostEventManager.bindHotkeys();
    this.zoomManager.zoomToFit(1);
  }
}

子模塊會將其保存為一個私有成員屬性。

以子模塊 ZoomManger 類為例,它大概是這樣的:

export class ZoomManager {
 private editor: Editor
  // ...

  constructor(editor: Editor) {
    // 將傳入的 Editor 對象保存為私有屬性
    this.editor = editor
    // ...
  }
  
  zoomIn(cx?: number, cy?: number) {
    // 通過 this.editor 訪問到其他模塊
    const zoomStep = this.editor.setting.get('zoomStep');
   // ...
}

子類的子類如果也要用 editor,我們就再傳,主打一個透傳,人手一份 Editor。

這樣所有的子模塊就都能拿到 Editor 對象,然后通過這個 Editor 對象去訪問其他的子類。

最小知識原則

其實這種做法并不滿足設計模式的 最小知識原則(或者叫迪米特法則)。

所謂最小知識原則,指的是每個模塊只和應該要用到的模塊要交流,不要和用不到的模塊發生關系。

甚至你可以抽一層接口或類繼承的方式,將細粒度達到被關聯模塊的某幾個需要用到的方法。

目前我的項目還處于早期階段,復雜度很低,所以沒必要這么做,之后會不斷添加功能中讓關聯模塊發生著變化。不應該過早優化。這是項目變得非常復雜,且開發人員非常多的時候才需要考慮優化。

事件發布訂閱

前面注入的方式,都是通過 主動的方式 去訪問其他模塊。

有時候我們需要用 被動的方式 去拿到其他模塊的數據,這時候我們常常會用 發布訂閱 模式。

發布訂閱模式,就是對象間存在一對多的依賴時,但一個對象改變狀態,所有的依賴對象會自動收到通知。

做法通常就是模塊加入的事件(event)的概念,并提供一些方法接受監聽器(函數),當這個模塊的某些狀態發生改變時,就會這些監聽器一一執行,并將最新狀態傳入。

這個其實我們并不陌生,像是定時器(setTimeout)、DOM 元素的事件(click、mouseover 等)都是用了這個設計模式。

Nodejs 也有個專門的 EventEmitter 類,來支持事件訂閱。

const { EventEmitter } = require('events');

// 創建事件觸發器實例
const emitter = new EventEmitter();

// 給 event-1 事件添加監聽器
emitter.on('event-1', (a, b) => {
  console.log('收到事件1消息,參數為:', a, b);
});

// 觸發事件,并提供參數。
emitter.emit('event-1', 3, 4);

// 移除指定監聽器
// emitter.off('event-1', handler);

可惜 Web 端并沒有這個輪子,得自己造或者找個輪子。

因為輪子實現并不復雜,我是更建議自己實現,方便修改和擴展。

通常我們只要實現 on、off、emit 三個方法就好了。

我們如果用 TypeScript 實現的話,需要用類型編程,讓事件名是類型安全的,即事件名對應的監聽器函數參數類型要匹配。

實現后的用法:

const ee = new EventEmitter<{
  // 指定事件和對應的函數類型
  update(newVal: string, prevVal: string): void;
  destroy(): void;
}>();
const handler = (newVal: string, prevVal: string) => {
  console.log(newVal, prevVal)
}
ee.on("update", handler);
ee.emit('update', '前端西瓜哥上班前的精神狀態', '前端西瓜哥上班后的精神狀態')
ee.off("update", handler);

// 編譯報錯(數字不匹配字符串類型)
// 'number' is not assignable to parameter of type 'string'
ee.emit('update', 1, 2)

// (val: number) => void' is not assignable to parameter of type '() => void
ee.on('destroy', (val: number) => {})

輪子的話我建議 mitt,同時這個輪子是 Vue3 官方推薦的(實現跨組件通信的一種方式),主要原因是它也是 類型安全 的。

這個輪子很簡單,高級方法也很少,源碼實現也就 100 多行,你完全可以拷貝過去自己改。

模塊如何使用事件

在 Nodejs 的內部模塊,是通過繼承的方式使用 EventEmitter 的,它的做法是:

class A extends EventEmitter {
  // ...
}

A.on('event-1', () => {})

但我更建議用 **組合 **而不是繼承的方式。

class A {
  emitter = new Emitter()
}

A.emitter.on('event-1', () => {})

繼承并不是好文明,不加限制可能導致復雜的多層繼承。我們應該多用組合,少用繼承。

這樣做的另一個次要好處是 EventEmitter 的方法不會污染 A 對象。

除了模塊間用發布訂閱方式通信,內核層(Editor對象)也常常利用它和 UI 層通信。

因為狀態源保存在 Editor 對象中,所以需要用發布訂閱的方式去同步狀態給 UI 層。

以畫布縮放的功能為例。

畫布縮放管理類的實現如下:

class ZoomManager {
  private zoom = 1;
  // 自己造的 EventEmitter 輪子
  private emitter = new EventEmitter<{
    zoomChange(zoom: number, prevZoom: number): void;
  }>();
  
  setZoom(zoom: number) {
    const prevZoom = this.zoom;
    this.zoom = zoom;

    // 觸發 “zoom改變” 事件
    this.emitter.emit('zoomChanged', zoom, prevZoom);
  }
}

對應的需要拿到 zoom 值的 React 組件,會在組件掛載時綁定監聽器(Vue 也是類似邏輯)。

const ZoomActions = () => {
  const editor = useContext(EditorContext);
  const [zoom, setZoom] = useState(1);
  
  // 組件掛載 hook
  useEffect(() => {
    if (editor) {
      // 初始化時要主動獲取 zoom 值
      setZoom(editor.zoomManager.getZoom());

      // 通過事件同步 core 層的狀態
      const handler = (zoom: number) => {
        setZoom(zoom);
      };
      editor.zoomManager.emitter.on('zoomChanged', handler);
  
      // 組件銷毀時解綁
      return () => {
        editor.zoomManager.emitter.off('zoomChanged', handler);
      };
    }
  }, []);
}

結尾

本文簡單介紹了圖形編輯器架構中,如何進行模塊間的通信。

對于某個模塊間,可以通過入口 Editor 對象,輕松主動訪問任何其他模塊。此外還可以用事件發布訂閱的方式綁定監聽器,在對應模塊狀態更新后被動地獲得通知。

責任編輯:姜華 來源: 前端西瓜哥
相關推薦

2023-10-19 10:12:34

圖形編輯器開發縮放圖形

2023-09-07 08:24:35

圖形編輯器開發繪制圖形工具

2023-08-31 11:32:57

圖形編輯器contain

2023-09-26 07:39:21

2024-01-08 08:30:05

光標圖形編輯器開發游標

2023-10-08 08:11:40

圖形編輯器快捷鍵操作

2023-10-10 16:04:30

圖形編輯器格式轉換

2023-08-28 08:10:50

Hex圖形編輯器

2023-07-07 13:56:01

圖形編輯器畫布縮放

2024-01-03 08:43:17

圖形編輯器旋轉控制點縮放控制點

2023-07-31 08:46:07

圖形編輯器圖形自動對齊

2023-02-06 16:59:57

Canvas編輯器

2023-04-07 08:02:30

圖形編輯器對齊功能

2023-01-18 08:30:40

圖形編輯器元素

2023-02-01 09:21:59

圖形編輯器標尺

2023-06-12 08:22:56

圖形編輯器工具

2023-05-09 08:15:32

圖形編輯器撤銷重做功能

2023-04-10 08:45:44

圖形編輯器排列移動功能

2023-02-09 07:02:30

圖形編輯器修改圖形

2022-12-02 07:24:46

點贊
收藏

51CTO技術棧公眾號

亚洲精品福利免费在线观看| 亚洲国产成人一区二区三区| 国内精品一区二区三区| 中文字幕在线免费看线人| 玖玖在线播放| 国产精品色呦呦| 国产精品视频免费一区| 黄色片视频网站| 成人看的羞羞网站| 精品国产99国产精品| 手机看片福利盒子久久| 久草福利资源在线| 欧产日产国产v| 卡通动漫精品一区二区三区| 91久久一区二区| www国产免费| 国产日本在线观看| 国产乱子伦一区二区三区国色天香| 97视频网站入口| 免费中文字幕日韩| 精品久久影院| 日韩电影中文 亚洲精品乱码| 精品视频无码一区二区三区| 男女啪啪在线观看| 久久只精品国产| 动漫美女被爆操久久久| 一区二区三区亚洲视频| 午夜综合激情| 久久久久亚洲精品| 精品国产视频一区二区三区| 国产91精品对白在线播放| 精品免费一区二区三区| 在线看免费毛片| 日韩一级二级| 欧美性猛交xxxx免费看漫画| youjizz.com在线观看| 秋霞午夜在线观看| 精品区在线观看| 亚洲国产网站| 不卡av日日日| 九九热视频在线免费观看| 欧美激情在线精品一区二区三区| 欧美精品一区二区三区蜜桃| 日韩av加勒比| 成人av在线播放| 欧美区一区二区三区| av免费中文字幕| 在线天堂新版最新版在线8| 亚洲成人久久影院| 免费一级淫片aaa片毛片a级| 18+激情视频在线| 亚洲免费观看在线观看| 影音欧美亚洲| 超碰人人干人人| 亚洲国产剧情在线观看| 日韩高清不卡一区| 国产精品www色诱视频| 亚洲av无码精品一区二区| 亚洲一区二区伦理| 日韩免费在线看| aaa在线视频| 日本免费新一区视频| 国产精品久久久91| 怡春院在线视频| 韩国毛片一区二区三区| 亚洲一区二区三区成人在线视频精品| 国产模特av私拍大尺度| 国产成人午夜电影网| 不卡日韩av| 婷婷伊人综合中文字幕| 久久午夜电影网| 色姑娘综合av| 成人在线免费看黄| 亚洲mv在线观看| 日本免费一级视频| 成人网ww555视频免费看| 欧美精品乱码久久久久久| 网站在线你懂的| 国产成人在线中文字幕| 日韩高清有码在线| jizz日本在线播放| 国产精品激情电影| 国模吧一区二区| 天天干天天操天天操| 久久电影网电视剧免费观看| 91情侣在线视频| 天堂中文资源在线观看| 久久精品人人做| 国产一二三四五| 亚洲人成在线网站| 91麻豆精品国产91久久久更新时间 | 久久久亚洲国产天美传媒修理工| 欧美三级韩国三级日本三斤在线观看| 老司机亚洲精品| 91免费看蜜桃| 成黄免费在线| 成人精品国产亚洲| 亚洲色图丝袜美腿| 午夜精品久久久久久久无码| 国产私拍福利精品视频二区| 精品久久久三级丝袜| 免费看日本黄色片| 在线精品亚洲| 成人在线一区二区| 青青操在线视频| 一区二区三区中文免费| 成人观看免费完整观看| 亚洲2区在线| 国产亚洲精品美女久久久| 久久97人妻无码一区二区三区| 日韩在线观看一区二区| 国外成人在线视频网站| 成人影院在线观看| 在线免费av一区| 国产十八熟妇av成人一区| 999精品视频| 国产999精品| 色婷婷中文字幕| 亚洲精品欧美综合四区| 国产九九热视频| 天堂一区二区三区四区| 欧美国产激情18| 国产精品亚洲欧美在线播放| 国产清纯白嫩初高生在线观看91| 日韩中字在线观看| 视频一区日韩| 久久人人爽人人爽爽久久| 中文字幕在线天堂| 91麻豆.com| 久久久久久免费看| 亚洲综合影院| 九色精品免费永久在线| 91在线公开视频| 国产精品福利在线播放| 亚洲欧美另类动漫| 国产一区二区三区四区二区| 欧美在线免费观看| 色网站在线免费观看| 性欧美大战久久久久久久久| 一区二区三区人妻| 欧美日韩国产成人精品| 4444kk亚洲人成电影在线| 久草资源在线观看| 欧美精品 国产精品| 美国黄色片视频| 久久精品99久久久| 中文字幕一区二区三区5566| 蜜臀尤物一区二区三区直播| 激情小说亚洲图片| 欧美激情久久久久久| 精品毛片在线观看| 亚洲一区中文在线| 国产a√精品区二区三区四区| 欧美永久精品| 高清国语自产拍免费一区二区三区| 欧美另类tv| 亚洲国产精品小视频| 日韩福利片在线观看| 成人视屏免费看| 国产综合av在线| 亚洲欧洲色图| 国产精品丝袜白浆摸在线| 黄网站在线免费看| 欧美sm美女调教| 日韩美女一级片| 久久嫩草精品久久久精品| 中文久久久久久| 亚洲自拍偷拍网| 韩国成人一区| 姬川优奈av一区二区在线电影| 亚洲精品永久免费精品| 中文字幕av免费观看| 亚洲视频精选在线| 小毛片在线观看| 日本亚洲视频在线| 在线观看18视频网站| 国产精品午夜av| 国产不卡av在线免费观看| 欧洲不卡视频| 亚洲国产91色在线| 波多野结衣视频在线观看| 亚洲欧美乱综合| 国产a级黄色片| 日本亚洲一区二区| 日本中文字幕在线视频观看| 一本久久青青| 91在线观看免费| 一级毛片久久久| 久久久999精品| 亚洲欧洲国产综合| 91精品国产高清一区二区三区 | 国产成人精品日本亚洲11| 天堂电影一区| 久久久国产精品视频| 韩国三级hd两男一女| 在线视频自拍| 欧美一级在线视频| chinese国产精品| 一区二区不卡在线视频 午夜欧美不卡在 | 僵尸再翻生在线观看免费国语| 尤物九九久久国产精品的分类| 午夜精品久久久久久久第一页按摩 | 亚洲午夜精品久久久久久性色| 精品国产av 无码一区二区三区| 午夜精品视频一区| 九九热最新地址| 国产日韩在线不卡| 中文字幕天堂网| 狠狠色综合播放一区二区| 欧美牲交a欧美牲交| 亚州av乱码久久精品蜜桃| 免费观看国产成人| 中文在线综合| 国产精品视频不卡| 综合日韩av| 欧美精品videossex88| eeuss影院在线播放| 日韩精品久久久久久福利| www.蜜臀av.com| 欧美日本乱大交xxxxx| 国产成人精品777777| 亚洲v日本v欧美v久久精品| 91免费公开视频| 26uuu亚洲综合色欧美| 99久久久无码国产精品性波多| 久久精品72免费观看| 一区二区成人网| 快she精品国产999| 日本a级片免费观看| 亚洲一级网站| 成人一区二区三区在线观看 | 欧美中文日韩| 自拍日韩亚洲一区在线| 欧美日韩伊人| 毛片av在线播放| 午夜欧美理论片| 日本黄色a视频| 日韩欧美大片| 夜夜春亚洲嫩草影视日日摸夜夜添夜| 欧美女优在线视频| 青青成人在线| 精品国内自产拍在线观看视频| 久久综合一区| 九九亚洲视频| 欧美一级日本a级v片| 少妇一区二区视频| 日韩视频在线观看国产| 精品视频免费| 亚洲精品中文字幕在线| 欧美1级片网站| 自拍另类欧美| 欧美在线网站| 男女啪啪免费视频网站| 国产日韩1区| 国产裸体舞一区二区三区| 巨乳诱惑日韩免费av| 亚洲国产高清av| 国产乱码精品一区二区三区av| 制服下的诱惑暮生| 成人动漫一区二区在线| 国产艳俗歌舞表演hd| 国产网站一区二区| 人人澡人人澡人人看| 一区二区三区国产豹纹内裤在线| 九九九国产视频| 成人免费在线播放| 国产精品高潮呻吟视频| 国产精品久久久久久久久久齐齐 | 久久中文字幕国产| 在线观看中文| 欧美一级高清免费| 国产情侣一区二区三区| 2014亚洲精品| 色婷婷av一区二区三区丝袜美腿| 日韩精品最新在线观看| 永久91嫩草亚洲精品人人| 五十路熟女丰满大屁股| 日韩和欧美的一区| 视频区 图片区 小说区| 成人高清视频在线观看| 久久久久久久毛片| 夜夜爽夜夜爽精品视频| 国产精品免费精品一区| 欧美老肥妇做.爰bbww| 色一情一乱一乱一区91av| 亚洲午夜激情免费视频| 性欧美1819sex性高清大胸| 欧美亚洲日本黄色| 国产美女视频一区二区| 精品免费视频123区| 日韩三级在线| 欧美视频在线播放一区| 国产一区在线精品| 91精品人妻一区二区三区蜜桃欧美| 国产精品国产馆在线真实露脸| 亚洲国产成人精品激情在线| 欧美日韩成人一区| 手机福利在线| 欧美福利视频在线观看| 免费污视频在线一区| 成人羞羞视频免费| 日韩成人a**站| 丰满爆乳一区二区三区| 国产一区二区三区四区五区入口| 波多野结衣一本| 亚洲一二三级电影| 97国产成人无码精品久久久| 日韩电影中文 亚洲精品乱码| a免费在线观看| 国产精品女主播| 精品在线观看入口| 国内精品在线观看视频| 国产精品一二三四区| 国产无遮挡在线观看| 色综合 综合色| 五月激情丁香婷婷| 久久免费在线观看| 国产精品一区二区精品视频观看 | 精品久久久三级| 香蕉国产精品| 无限资源日本好片| 久久久久久久久久看片| 久久国产精品系列| 亚洲精品在线电影| 久草在线资源站资源站| 91探花福利精品国产自产在线| 精品国产乱码久久久久久果冻传媒| 欧美日韩亚洲一| 99国产精品视频免费观看| 久一视频在线观看| 日韩视频免费观看高清在线视频| 日本网站在线免费观看视频| 国产精品久久久久久一区二区| 久9久9色综合| 日韩精品无码一区二区三区免费 | 日本 欧美 国产| 欧美性猛片aaaaaaa做受| 精品视频二区| 国产精品69久久久久| 国产日产一区| 毛片毛片毛片毛片毛片毛片毛片毛片毛片| 99精品国产99久久久久久白柏| 五月天婷婷丁香| 日韩成人中文字幕| 亚洲优女在线| 日本免费一区二区三区| 日韩精品久久理论片| 一区二区三区久久久久| 欧美性感一区二区三区| 3d成人动漫在线| 成人黄在线观看| 欧美精品一区二区三区久久久竹菊| 无码人妻少妇色欲av一区二区| 亚洲精品成人少妇| 丰满少妇在线观看bd| 亚州成人av在线| 久久av中文| 国产区二区三区| 亚洲欧美综合另类在线卡通| 国产手机视频在线| 欧美激情亚洲综合一区| 美国一区二区| 91看片就是不一样| 中文字幕一区二区三区蜜月| 国产绳艺sm调教室论坛| 欧美激情久久久久| 蜜桃一区二区| 成年人三级黄色片| 亚洲综合一区在线| 人成在线免费视频| 国产精品免费看久久久香蕉 | 操日韩av在线电影| 波多野结衣在线一区二区| 男人靠女人免费视频网站| 中文字幕av一区二区三区高| 超碰在线播放91| 国产精品7m凸凹视频分类| 伊人成人免费视频| 午夜精品福利一区二区三区av | 国产91精品对白在线播放| 亚洲美女爱爱视频| 亚洲香肠在线观看| 久草在线免费福利资源| 91天堂在线视频| 欧美在线综合| 午夜免费激情视频| 亚洲免费影视第一页| 国产亚洲字幕| 岳毛多又紧做起爽| 1024成人网| 毛片网站在线观看| 97神马电影| 男人操女人的视频在线观看欧美| 免费国产羞羞网站美图| 日韩福利在线播放| 天堂久久av| 国产免费又粗又猛又爽| 婷婷中文字幕综合| h片在线免费观看| 日本午夜精品一区二区三区|