欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

怎么實現(xiàn)Web端自定義截屏

這篇文章主要講解了“怎么實現(xiàn)Web端自定義截屏”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“怎么實現(xiàn)Web端自定義截屏”吧!

十年的峨山縣網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。全網(wǎng)整合營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整峨山縣建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“峨山縣網(wǎng)站設(shè)計”,“峨山縣網(wǎng)站推廣”以來,每個客戶項目都認真落實執(zhí)行。

搭建開發(fā)環(huán)境

我想使用ts、scss、eslint、prettier來提升插件的可維護性,又嫌麻煩,不想手動配置webpack環(huán)境,于是我決定使用Vue  CLI來搭建插件開發(fā)環(huán)境。

本文不細講Vue CLI搭建插件開發(fā)環(huán)境的過程,對此感興趣的開發(fā)者請移步:使用CLI開發(fā)一個Vue3的npm庫。

移除vue相關(guān)依賴

我們搭建好插件的開發(fā)環(huán)境后,CLI默認會在package.json中添加Vue的相關(guān)包,我們的插件不會依賴于vue,因此我們把它刪除即可。

{ - "vue": "^3.0.0-0", - "vue-class-component": "^8.0.0-0" }

創(chuàng)建DOM

為了方便開發(fā)者使用dom,這里選擇使用js動態(tài)來創(chuàng)建dom,最后將其掛載到body中,在vue3版本的截圖插件中,我們可以使用vue組件來輔助我們,這里我們就要基于組件來使用js來創(chuàng)建對應(yīng)的dom,為其綁定對應(yīng)的事件。

部分實現(xiàn)代碼如下,完整代碼請移步:CreateDom.ts

import toolbar from "@/lib/config/Toolbar"; import { toolbarType } from "@/lib/type/ComponentType"; import { toolClickEvent } from "@/lib/split-methods/ToolClickEvent"; import { setBrushSize } from "@/lib/common-methords/SetBrushSize"; import { selectColor } from "@/lib/common-methords/SelectColor"; import { getColor } from "@/lib/common-methords/GetColor";  export default class CreateDom {   // 截圖區(qū)域canvas容器   private readonly screenShortController: HTMLCanvasElement;   // 截圖工具欄容器   private readonly toolController: HTMLDivElement;   // 繪制選項頂部ico容器   private readonly optionIcoController: HTMLDivElement;   // 畫筆繪制選項容器   private readonly optionController: HTMLDivElement;   // 文字工具輸入容器   private readonly textInputController: HTMLDivElement;    // 截圖工具欄圖標   private readonly toolbar: Array<toolbarType>;        constructor() {     this.screenShortController = document.createElement("canvas");     this.toolController = document.createElement("div");     this.optionIcoController = document.createElement("div");     this.optionController = document.createElement("div");     this.textInputController = document.createElement("div");     // 為所有dom設(shè)置id     this.setAllControllerId();     // 為畫筆繪制選項角標設(shè)置class     this.setOptionIcoClassName();     this.toolbar = toolbar;     // 渲染工具欄     this.setToolBarIco();     // 渲染畫筆相關(guān)選項     this.setBrushSelectPanel();     // 渲染文本輸入     this.setTextInputPanel();     // 渲染頁面     this.setDomToBody();     // 隱藏所有dom     this.hiddenAllDom();   }      /** 其他代碼省略 **/    }

插件入口文件

在開發(fā)vue插件時我們需要暴露一個install方法,由于此處我們不需要依賴vue,我們就無需暴露install方法,我的預想效果是:用戶在使用我插件時,直接實例化插件就能正常運行。

因此,我們默認暴露出一個class,無論是使用script標簽引入插件,還是在其他js框架里使用import來引入插件,都只需要在使用時new一下即可。

部分代碼如下,完整代碼請移步:main.ts

import CreateDom from "@/lib/main-entrance/CreateDom"; // 導入截圖所需樣式 import "@/assets/scss/screen-short.scss"; import InitData from "@/lib/main-entrance/InitData"; import {   cutOutBoxBorder,   drawCutOutBoxReturnType,   movePositionType,   positionInfoType,   zoomCutOutBoxReturnType } from "@/lib/type/ComponentType"; import { drawMasking } from "@/lib/split-methods/DrawMasking"; import { fixedData, nonNegativeData } from "@/lib/common-methords/FixedData"; import { drawPencil, initPencil } from "@/lib/split-methods/DrawPencil"; import { drawText } from "@/lib/split-methods/DrawText"; import { drawRectangle } from "@/lib/split-methods/DrawRectangle"; import { drawCircle } from "@/lib/split-methods/DrawCircle"; import { drawLineArrow } from "@/lib/split-methods/DrawLineArrow"; import { drawMosaic } from "@/lib/split-methods/DrawMosaic"; import { drawCutOutBox } from "@/lib/split-methods/DrawCutOutBox"; import { zoomCutOutBoxPosition } from "@/lib/common-methords/ZoomCutOutBoxPosition"; import { saveBorderArrInfo } from "@/lib/common-methords/SaveBorderArrInfo"; import { calculateToolLocation } from "@/lib/split-methods/CalculateToolLocation";  export default class ScreenShort {   // 當前實例的響應(yīng)式data數(shù)據(jù)   private readonly data: InitData;    // video容器用于存放屏幕MediaStream流   private readonly videoController: HTMLVideoElement;   // 截圖區(qū)域canvas容器   private readonly screenShortController: HTMLCanvasElement | null;   // 截圖工具欄dom   private readonly toolController: HTMLDivElement | null;   // 截圖圖片存放容器   private readonly screenShortImageController: HTMLCanvasElement;   // 截圖區(qū)域畫布   private screenShortCanvas: CanvasRenderingContext2D | undefined;   // 文本區(qū)域dom   private readonly textInputController: HTMLDivElement | null;   //  截圖工具欄畫筆選項dom   private optionController: HTMLDivElement | null;   private optionIcoController: HTMLDivElement | null;   // 圖形位置參數(shù)   private drawGraphPosition: positionInfoType = {     startX: 0,     startY: 0,     width: 0,     height: 0   };   // 臨時圖形位置參數(shù)   private tempGraphPosition: positionInfoType = {     startX: 0,     startY: 0,     width: 0,     height: 0   };   // 裁剪框邊框節(jié)點坐標事件   private cutOutBoxBorderArr: Array<cutOutBoxBorder> = [];   // 當前操作的邊框節(jié)點   private borderOption: number | null = null;    // 點擊裁剪框時的鼠標坐標   private movePosition: movePositionType = {     moveStartX: 0,     moveStartY: 0   };    // 鼠標點擊狀態(tài)   private clickFlag = false;   private fontSize = 17;   // 最大可撤銷次數(shù)   private maxUndoNum = 15;   // 馬賽克涂抹區(qū)域大小   private degreeOfBlur = 5;    // 文本輸入框位置   private textInputPosition: { mouseX: number; mouseY: number } = {     mouseX: 0,     mouseY: 0   };   constructor() {     // 創(chuàng)建dom     new CreateDom();     this.videoController = document.createElement("video");     this.videoController.autoplay = true;     this.screenShortImageController = document.createElement("canvas");     // 實例化響應(yīng)式data     this.data = new InitData();     // 獲取截圖區(qū)域canvas容器     this.screenShortController = this.data.getScreenShortController() as HTMLCanvasElement | null;     this.toolController = this.data.getToolController() as HTMLDivElement | null;     this.textInputController = this.data.getTextInputController() as HTMLDivElement | null;     this.optionController = this.data.getOptionController() as HTMLDivElement | null;     this.optionIcoController = this.data.getOptionIcoController() as HTMLDivElement | null;     this.load();   }      /** 其他代碼省略 **/ }

對外暴露default屬性

做完上述配置后我們的插件開發(fā)環(huán)境就搭建好了,我執(zhí)行build命令打包插件后,在vue2項目中使用import形式正常運行,在使用script標簽時引入時卻報錯了,于是我將暴露出來的screenShotPlugin變量打印出來后發(fā)現(xiàn)他還有個default屬性,default屬性才是我們插件暴露出來的東西。

求助了下我朋友@_Dreams找到了解決方案,需要配置下webpack中的output.libraryExport屬性,我們的插件是使用Vue  CLI開發(fā)的,有關(guān)webpack的配置需要在需要在vue.config.js中進行配置,代碼如下:

module.exports = {     // 自定義webpack配置   configureWebpack: {     output: {       // 對外暴露default屬性       libraryExport: "default"     }   } }

這一塊的配置在Vue  CLI文檔中也有被提到,感興趣的開發(fā)者請移步:build-targets.html#vue-vs-js-ts-entry-files

使用webrtc截取整個屏幕

插件一開始使用的是html2canvas來將dom轉(zhuǎn)換為canvas的,因為他要遍歷整個body中的dom,然后再轉(zhuǎn)換成canvas,而且圖片還不能跨域,如果頁面中圖片一多,它會變得非常慢。

在上一篇文章的評論區(qū)中有位開發(fā)者 @名字什么的都不重要  建議我使用webrtc來替代html2canvas,于是我就看了下webrtc的相關(guān)文檔,最終實現(xiàn)了截屏功能,它截取出來的東西更精確、性能更好,不存在卡頓問題也不存在css問題,而且它把選擇權(quán)交給了用戶,讓用戶決定來共享屏幕的那一部分內(nèi)容。

實現(xiàn)思路

接下來就跟大家分享下我的實現(xiàn)思路:

  • 使用getDisplayMedia來捕獲屏幕,得到MediaStream流

  • 將得到的MediaStream流輸出到video標簽中

  • 使用canvas將video標簽中的內(nèi)容繪制到canvas容器中

有關(guān)getDisplayMedia的具體用法,請移步:使用屏幕捕獲API

實現(xiàn)代碼

接下來,我們來看下具體的實現(xiàn)代碼,完整代碼請移步:main.ts

// 加載截圖組件   private load() {     // 設(shè)置截圖區(qū)域canvas寬高     this.data.setScreenShortInfo(window.innerWidth, window.innerHeight);     // 設(shè)置截圖圖片存放容器寬高     this.screenShortImageController.width = window.innerWidth;     this.screenShortImageController.height = window.innerHeight;     // 顯示截圖區(qū)域容器     this.data.showScreenShortPanel();     // 截取整個屏幕     this.screenShot();   }    // 開始捕捉屏幕   private startCapture = async () => {     let captureStream = null;      try {       // eslint-disable-next-line @typescript-eslint/ban-ts-ignore       // @ts-ignore       // 捕獲屏幕       captureStream = await navigator.mediaDevices.getDisplayMedia();       // 將MediaStream輸出至video標簽       this.videoController.srcObject = captureStream;     } catch (err) {       throw "瀏覽器不支持webrtc" + err;     }     return captureStream;   };    // 停止捕捉屏幕   private stopCapture = () => {     const srcObject = this.videoController.srcObject;     if (srcObject && "getTracks" in srcObject) {       const tracks = srcObject.getTracks();       tracks.forEach(track => track.stop());       this.videoController.srcObject = null;     }   };    // 截屏   private screenShot = () => {     // 開始捕捉屏幕     this.startCapture().then(() => {       setTimeout(() => {         // 獲取截圖區(qū)域canvas容器畫布         const context = this.screenShortController?.getContext("2d");         if (context == null || this.screenShortController == null) return;          // 賦值截圖區(qū)域canvas畫布         this.screenShortCanvas = context;         // 繪制蒙層         drawMasking(context);         // 將獲取到的屏幕截圖繪制到圖片容器里         this.screenShortImageController           .getContext("2d")           ?.drawImage(             this.videoController,             0,             0,             this.screenShortImageController?.width,             this.screenShortImageController?.height           );         // 添加監(jiān)聽         this.screenShortController?.addEventListener(           "mousedown",           this.mouseDownEvent         );         this.screenShortController?.addEventListener(           "mousemove",           this.mouseMoveEvent         );         this.screenShortController?.addEventListener(           "mouseup",           this.mouseUpEvent         );         // 停止捕捉屏幕         this.stopCapture();       }, 300);     });   };

感謝各位的閱讀,以上就是“怎么實現(xiàn)Web端自定義截屏”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對怎么實現(xiàn)Web端自定義截屏這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

網(wǎng)站標題:怎么實現(xiàn)Web端自定義截屏
瀏覽路徑:http://chinadenli.net/article12/pgjpdc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版面包屑導航外貿(mào)建站品牌網(wǎng)站設(shè)計建站公司全網(wǎng)營銷推廣

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)