前言
上週六有個群友@我說Gitee的反饋模組新增了截圖功能,我就去體驗了下,發現他們用的就是我的外掛?,本文就跟大家分享下這個外掛,歡迎各位感興趣的開發者閱讀本文。
外掛地址與實現原理
本外掛採用原生js實現,可以整合在任意一個web專案中,外掛npm地址與GitHub地址請移步:
外掛的實現原理請移步:
線上體驗本外掛,可移步我的開源專案chat-system進行體驗,外掛的執行效果視訊請移步實現web端自定義截圖功能-效果視訊。
Gitee產品經理的青睞
月初的時候,Gitee的產品經理在掘金看到我的截圖外掛js-screen-shot覺得還不錯,他們最近在做這方面的功能,就打算將我的外掛直接整合進去,跟我溝通了下版權相關的事情。
溝通完成後,他問我要不要把外掛在Gitee也放一份,可以幫我推薦下,我毫不猶豫的抱住了大腿,就把外掛搬過去了,得到一波首頁推薦?
Gitee的反饋模組需要登入後,點頁面右側的傳送反饋圖示。
影響體驗的一些小問題
上週二,從GitHub來了個網友,加了我微信,給我的外掛提了兩個issues,因為周內沒時間處理這些問題,就計劃週末統一處理下外掛的issues。
整理有效的issues
時間回到上週六早上,我開啟GitHub瞅了一眼issues,許久不看居然已經有19條了。
經過一番整理,去掉一些無用的和已經修改好了的,最終確定了4條:
- 呼叫者可以在框選區域外繪製問題
- 截圖區域工具欄首次點選時刪除裁剪框的8個可操作點
- 修復框選完成後,滑鼠點選其他位置截圖工具欄跟著移動問題
- 新增可選引數支援單擊截全屏功能
解決issues
問題整理完成,接下來就是解決問題環節了。
選區外繪製問題
正常情況下,截圖區域確立後,使用者都會在裁剪框區域內進行繪製,所以我就沒考慮這個邊界情況?,外掛用的人多了後,自然就有人發現了這個問題,我們拿gitee的反饋模組舉例(gitee目前用的還是我的舊版外掛,肯定存在這個問題),如下所示,我們繪製的4個紅色方框都超出裁剪框了:
實現思路
這個問題解決起來比較簡單,裁剪框已經繪製好了,知道它的座標資訊,我們在進行繪製時,只需要判斷當前滑鼠位置是否超出裁剪框的座標點區域即可。部分實現程式碼如下所示:
// 獲取裁剪框位置資訊
const cutBoxPosition = this.data.getCutOutBoxPosition();
// 繪製中工具的起始x、y座標不能小於裁剪框的起始座標
// 繪製中工具的起始x、y座標不能大於裁剪框的結束座標
// 當前滑鼠的x座標不能小於裁剪框起始x座標,不能大於裁剪框的結束座標
// 當前滑鼠的y座標不能小於裁剪框起始y座標,不能大於裁剪框的結束座標
if (
!getDrawBoundaryStatus(startX, startY, cutBoxPosition) ||
!getDrawBoundaryStatus(currentX, currentY, cutBoxPosition)
)
return;
getDrawBoundaryStatus
函式實現如下所示:
/**
* 獲取工具欄工具邊界繪製狀態
* @param startX x軸繪製起點
* @param startY y軸繪製起點
* @param cutBoxPosition 裁剪框位置資訊
*/
export function getDrawBoundaryStatus(
startX: number,
startY: number,
cutBoxPosition: positionInfoType
): boolean {
if (
startX < cutBoxPosition.startX ||
startY < cutBoxPosition.startY ||
startX > cutBoxPosition.startX + cutBoxPosition.width ||
startY > cutBoxPosition.startY + cutBoxPosition.height
) {
// 無法繪製
return false;
}
// 可以繪製
return true;
}
具體程式碼請移步提交記錄: fix: 修復外掛呼叫者可以在框選區域外繪製問題
實現效果
實現後的效果如下所示:
工具欄跟隨滑鼠移動問題
這個問題可以描述為:裁剪框確定後,工具欄尚未點選,此時滑鼠點其他位置,截圖工具欄就跟著滑鼠重新計算了位置,我們繼續用Gitee來舉例,如下所示:
實現思路
當滑鼠左鍵抬起時,如果工具欄尚未被點選,則會根據當前滑鼠的位置結合裁剪框的大小確立截圖工具欄的位置。使用者只是單純的點選了裁剪框區域的任意位置,工具欄就跟著移動了。
解決這個問題也很簡單,我們只需要在滑鼠移動時新增一個標識,滑鼠抬起時判斷這個標識是否為true即可。部分程式碼如下所示:
// 滑鼠拖動狀態
private dragFlag = false;
// 滑鼠移動事件
private mouseMoveEvent = (event: MouseEvent) => {
// 工具欄未選擇且滑鼠處於按下狀態時
if (!this.data.getToolClickStatus() && this.data.getDragging()) {
// 修改拖動狀態為true;
this.dragFlag = true;
}
}
// 滑鼠抬起事件
private mouseUpEvent = () => {
// 滑鼠尚未拖動且工具欄未選擇則不修改工具欄位置
if (!this.dragFlag && !this.data.getToolClickStatus()) {
// 復原裁剪框的座標
this.drawGraphPosition.startX = this.drawGraphPrevX;
this.drawGraphPosition.startY = this.drawGraphPrevY;
// 顯示截圖工具欄
this.data.setToolStatus(true);
return;
}
}
具體程式碼請移步提交記錄:fix: 修復框選完成後,滑鼠點選其他位置截圖工具欄跟著移動問題
實現結果
修復後的效果如下所示:
刪除8個可操作點
去年截圖外掛剛寫好時,我就發現這個問題了,當截圖工具欄點選後裁剪框就不允許更改了,如果8個可操作點依然存在的話,看起來很奇怪,當時想到的思路是直接刪除邊框的8點,但是這8個點都是繪製上去的,折騰了挺久沒找到方案就擱置了,這個問題如下圖所示:
實現思路
一年後的今天,我知道刪除那8個點的思路肯定行不通,我就一遍又一遍的體驗QQ的截圖,觀察他是怎麼做的,突然,我靈感驚現?,我既然有裁剪框的座標和大小資訊,我重新繪製一下這個裁剪框不就好了?,裁剪框四周的8個可操作點刪除後,我就可以刪掉生成圖片時優化那8個點的計算邏輯,導致範圍不精確問題,從而實現完美截圖。部分實現程式碼如下所示:
// 工具欄尚未點選,當前屬於首次點選,重新繪製一個無畫素點的裁剪框
if (!data.getToolClickStatus()) {
// 獲取裁剪框位置資訊
const cutBoxPosition = data.getCutOutBoxPosition();
// 開始繪製無畫素點裁剪框
drawCutOutBox(
cutBoxPosition.startX,
cutBoxPosition.startY,
cutBoxPosition.width,
cutBoxPosition.height,
screenShortCanvas,
data.getBorderSize(),
screenShortController as HTMLCanvasElement,
ScreenShortImageController,
false
);
}
具體程式碼請移步提交記錄:fix: 截圖區域工具欄首次點選時刪除裁剪框的8個可操作點
實現效果
實現單擊截全屏功能
給我提issues的那個網友希望截圖外掛載入完畢後,使用者不拖拽生成選框,直接滑鼠左鍵單擊就能擷取整個螢幕,我覺得這個需求需要的人不多,就將其做成了可選引數。
實現思路
這個也很簡單,滑鼠抬起時,如果開啟了單擊截全屏,則從座標(0,0)位置繪製一個與畫布同等大小的裁剪框即可,部分程式碼如下所示:
// 滑鼠抬起事件
private mouseUpEvent = () => {
if (
cutBoxPosition.width === 0 &&
cutBoxPosition.height === 0 &&
cutBoxPosition.startX === 0 &&
cutBoxPosition.startY === 0 &&
!this.dragFlag &&
this.clickCutFullScreen
) {
// 設定裁剪框位置為全屏
this.tempGraphPosition = drawCutOutBox(
0,
0,
this.screenShortImageController.width,
this.screenShortImageController.height,
this.screenShortCanvas,
this.data.getBorderSize(),
this.screenShortController,
this.screenShortImageController
) as drawCutOutBoxReturnType;
}
}
具體程式碼請移步提交記錄:feat: 新增可選引數支援單擊截全屏功能
寫在最後
至此,文章就分享完畢了。
我是神奇的程式設計師,一位前端開發工程師。
如果你對我感興趣,請移步我的個人網站,進一步瞭解。
- 文中如有錯誤,歡迎在評論區指正,如果這篇文章幫到了你,歡迎點贊和關注?
- 本文首發於神奇的程式設計師公眾號,未經許可禁止轉載?