自制 Markdown 編輯器增長圖牀功能

使用 markdown,最方便的莫過於利用圖牀功能,將圖片保存到雲端,而後轉換成 ![]() 結構。避免擔憂圖片存在某一臺電腦設備上,這樣就能夠把文章內容複製到任何一個地方和平臺,繼續無縫的寫做下去。vue

今天,咱們就來講一說怎麼在自建 markdown 編輯器上,增長圖牀功能。linux

咱們的主角是:「PicGo」。web

安裝 PicGo

npm install picgo --save
複製代碼

配置 PicGo

picgo 的默認配置文件爲~/.picgo/config.json。其中~爲用戶目錄。不一樣系統的用戶目錄不太同樣。npm

linux和macOS均爲 ~/.picgo/config.json。json

windows則爲 C:\Users\你的用戶名.picgo\config.jsonwindows

固然也能夠根據本身的須要,將配置文件放在不一樣路徑下,主要參考 picgo 官網描述來配置便可,下面是是 upyun 配置內容。api

{
  "picBed": {
    "current": "upyun",
    "uploader": "upyun",
    "upyun": {
    	"bucket": "coding", // 存儲空間名,及你的服務名
	  	"operator": "coding01", // 操做員
	  	"password": "**********", // 密碼
	  	"options": "", // 針對圖片的一些後綴處理參數
	  	"path": "blog/", // 自定義存儲路徑,好比img/
	  	"url": "http://***.****.com"
    }
  },
  "picgoPlugins": {}
}

複製代碼

若是沒配置,則可使用默認的 sm.ms 圖牀。bash

觸發上傳圖牀

在寫做過程當中,觸發上傳比較簡單的辦法,我以爲有兩種方法比較便捷,一種是直接複製粘貼圖片,另外一種就是拖拽圖片到編輯器。markdown

今天重點來講說怎麼直接複製粘貼上傳圖片。app

剪切板

首先,必需要藉助 electron 的剪切板讀取複製的圖片信息,clipboard 操做剪切板功能也很簡單,直接看代碼:

const { clipboard } = require('electron')

// 獲取剪切板圖片,type String (optional) - Can be selection or clipboard. selection is only available on Linux.
// 返回 NativeImage- 剪貼板中的圖像內容。

clipboard.readImage([type])
複製代碼

具體參考 electron clipboard electronjs.org/docs/api/cl…

粘貼

咱們只須要「Ctrl + Shift + V」粘貼操做,編輯器會判斷,若是剪切板上是圖片時,咱們就執行上傳操做。

全局快捷鍵

咱們先用 electron 提供的「全局快捷鍵」看看效果。

// 註冊一個 'CommandOrControl+X' 的全局快捷鍵
  const ret = globalShortcut.register('CommandOrControl+v', () => {
    console.log('CommandOrControl+v is pressed')
    // 上傳剪貼板裏的第一張圖片(上傳時會將格式轉爲png)
    let callback = picgo.upload()
    console.log(callback)
  })

  if (!ret) {
    console.log('registration failed')
  }

  // 檢查快捷鍵是否註冊成功
  console.log(globalShortcut.isRegistered('CommandOrControl+v'))
複製代碼

看看打印出來的 log,這裏也能看出默認上傳圖牀爲 SM.MS:

除了使用「全局快捷鍵」,咱們還可使用「本地快捷鍵」方式:

本地快捷鍵

使用「本地快捷鍵」以前,須要建立菜單和菜單項,經過菜單項綁定對應的快捷鍵。

mainMenu(mainWindow);

// 設置快捷鍵和對應的動做
{
    label: '上傳圖片',
    accelerator: process.platform === 'darwin' ? 'Command+Shift+V' : 'Ctrl+Shift+V',
    click: () => { 
        mainWindow.webContents.send('uploadImage');
    }
},
複製代碼

經過 mainWindow.webContents.send 將快捷鍵動做推送給 ipcRenderer,接着能夠在 renderer 中建立監聽事件:

ipcRenderer.on('uploadImage', (event) => {
  console.log('messageBus CommandOrControl+v is pressed')
  ipcRenderer.send('uploadImage');
})
複製代碼

獲取剪切板的圖片推薦放到 ipcMain 上去作,並且上傳圖片也是耗時事件。因此在 ipcMain 建立 uploadImage 事件:

ipcMain.on('uploadImage', function() {
  let img = clipboard.readImage()
  if (!img.isEmpty()) {
    let callback = picgo.upload()
    console.log(callback)
  }
})
複製代碼

好了,到此爲止,咱們執行,經過快捷鍵「Command+Shift+V」看看打印 log:

除了以上兩種方式外,咱們還有第三種使用快捷鍵的方法,就是利用 ace 編輯器自帶的 Command 功能

ace Command

在 EditorPage 的 editorInit(editor) 初始化方法中增長一個 Command,並綁定對應的快捷鍵:

editor.commands.addCommand({
    name: '上傳圖片',
    bindKey: {win: 'Ctrl-Shift-M',  mac: 'Command-Shift-M'},
    exec: function(editor) {
        console.log('上傳圖片');
        messageBus.uploadImage();
    },
    readOnly: true // false if this command should not apply in readOnly mode
});
複製代碼

一樣的,建立 messageBus.uploadImage()

uploadImage() {
  console.log('messageBus ACE Command is pressed')
  ipcRenderer.send('uploadImage');
}
複製代碼

綜上,我的偏向使用 ace Command 方法,把上傳圖片的功能侷限到編輯器範疇內,也符合功能的使用。

到此,咱們初步作到將圖片上傳到默認的 sm.ms 上了,接下來就是顯示的問題了。

上傳圖牀後顯示

首先看看 picgo 提供給咱們幾個和上傳有關的狀態函數:

// 圖牀上傳進度
picgo.on('uploadProgress', progress => {
  console.log('uploadProgress')
  console.log(progress)
})

picgo.on('beforeTransform', ctx => {
  console.log('beforeTransform')
  console.log(ctx.input) // ['/xxx/xxx.jpg']
})

picgo.on('beforeUpload', ctx => {
  console.log('beforeUpload')
  console.log(ctx.output) // [{ base64Image, fileName, width, height, extname }]
})

picgo.on('afterUpload', ctx => {
  console.log('afterUpload')
  console.log(ctx.output) // [{fileName, width, height, extname, imgUrl}] <- 注意有imgUrl了。
})

picgo.on('finished', ctx => {
  console.log('finished')
  console.log(ctx.output) // [{fileName, width, height, extname, imgUrl}] <- 注意有imgUrl了。
})

picgo.on('failed', error => {
  console.log('failed')
  console.log(error) // 錯誤信息
})

picgo.on('notification', notice => {
  console.log('notification')
  console.log(notice) // { title, body, text? }
})
複製代碼

其中,咱們須要用到的有:uploadProgressafterUploadfailednotification

若是上傳錯誤的話,能夠經過多方面來判斷:1. 能夠利用 progress = -1;2. error;3. notification 也會輸出錯誤提示和內容,這裏推薦直接使用notification。

咱們先看 afterUpload 返回的數據,須要將 imgUrl 內容填充給編輯器。

picgo.on('afterUpload', ctx => {
  console.log('afterUpload')
  console.log(ctx.output.imgUrl) // [{fileName, width, height, extname, imgUrl}] <- 注意有imgUrl了。
  // 將 imgUrl 內容發給編輯器。
  mainWindow.webContents.send('imgUrl', ctx.output[0].imgUrl);
})
複製代碼

接收端直接接收該事件,並 emit 給 vue 頁面:

// renderer/main.js
ipcRenderer.on('imgUrl', (event, imgUrl) => {
  messageBus.$emit('imgUrl', imgUrl);
})

// EditorPage.vue
messageBus.$on('imgUrl', (imgUrl) => {
    console.log(`imgUrl ${imgUrl}`);
    // 格式化爲 markdown 格式,insert 到編輯器中
    this.editor.editor.insert(`![](${imgUrl})`);
});
複製代碼

直接看結果

總結

接下來還有不少東西須要作,如:

  1. 增長各個圖牀 (七牛、又拍雲等)的配置設置;
  2. 將上傳圖牀的功能封裝;
  3. 增長拖拽圖片上傳圖牀功能;
  4. 增長圖片上傳進度和成功與否的提示等。

固然,咱們的目標是在寫出知足本身寫做須要的 markdown 編輯器的同時,也學習如何使用 Electron 框架。

學會了

  1. electron 菜單項 electronjs.org/docs/api/me…
  2. electron「本地快捷鍵」和「全局快捷鍵」electronjs.org/docs/tutori…
  3. electron 剪貼板 electronjs.org/docs/api/cl…

「Markdown編輯器」系列

  1. 利用Electron簡單擼一個Markdown編輯器 (1) mp.weixin.qq.com/s/lXESP6Sa0…
相關文章
相關標籤/搜索