
Security News
GitHub Actions Checkout Now Blocks Risky pull_request_target Checkouts
GitHub Actions checkout now blocks risky pull_request_target checkouts by default to help prevent pwn request supply chain attacks.
js-web-screen-shot-vv
Advanced tools
web端自定义截屏插件(原生JS版),运行视频:实现web端自定义截屏功能 ,效果图如下:
关于此插件的更多介绍以及实现原理请移步:
yarn add js-web-screen-shot
# or
npm install js-web-screen-shot --save
由于插件采用原生js编写且不依赖任何第三方库,因此它可以在任意一台支持js的设备上运行。
注意⚠️: 如果需要使用插件的webrtc模式或者截图写入剪切板功能,需要你的网站运行在
https环境或者localhost环境。当然,也可以通过修改浏览器设置的方式实现在所有环境下都能运行。步骤如下: 1.打开谷歌浏览器,在地址栏输入chrome://flags/#unsafely-treat-insecure-origin-as-secure2.在打开的界面中:下拉框选择enabled,地址填写你的项目访问路径。
import ScreenShot from "js-web-screen-shot";
new ScreenShot();
⚠️注意:实例化插件时一定要等dom加载完成,否则插件无法正常工作。
dist文件夹复制到你的项目中script标签引入dist目录下的screenShotPlugin.umd.js文件<script src="./screenShotPlugin.umd.js"></script>
// 截图确认按钮回调函数
const callback = (base64) =>{
console.log(base64);
}
// 截图取消时的回调函数
const closeFn = ()=>{
console.log("截图窗口关闭");
}
new screenShotPlugin({enableWebRtc: true, completeCallback: callback,closeCallback: closeFn});
⚠️注意:实例化插件时一定要等dom加载完成,否则插件无法正常工作。
由于electron环境下无法直接调用webrtc来获取屏幕流,因此需要调用者自己稍作处理,具体做法如下所示:
// electron主线程
import { desktopCapturer, webContents } from "electron";
// 修复electron18.0.0-beta.5 之后版本的BUG: 无法获取当前程序页面视频流
const selfWindws = async () =>
await Promise.all(
webContents
.getAllWebContents()
.filter(item => {
const win = BrowserWindow.fromWebContents(item);
return win && win.isVisible();
})
.map(async item => {
const win = BrowserWindow.fromWebContents(item);
const thumbnail = await win?.capturePage();
// 当程序窗口打开DevTool的时候 也会计入
return {
name:
win?.getTitle() + (item.devToolsWebContents === null ? "" : "-dev"), // 给dev窗口加上后缀
id: win?.getMediaSourceId(),
thumbnail,
display_id: "",
appIcon: null
};
})
);
// 获取设备窗口信息
ipcMain.handle("IPC消息名称", async (_event, _args) => {
return [
...(await desktopCapturer.getSources({ types: ["window", "screen"] })),
...(await selfWindws())
];
});
// xxx.ts
export const getDesktopCapturerSource = async () => {
return await window.electron.ipcRenderer.invoke<Electron.DesktopCapturerSource[]>("IPC消息名称", []);
}
// yyy.ts
export function getInitStream(source: any): Promise<MediaStream | null> {
return new Promise((resolve, _reject) => {
// 获取指定窗口的媒体流
// 此处遵循的是webRTC的接口类型 暂时TS类型没有支持 只能断言成any
(navigator.mediaDevices as any).getUserMedia({
audio: false,
video: {
mandatory: {
chromeMediaSource: 'desktop',
chromeMediaSourceId: source.id
},
}
}).then((stream: MediaStream) => {
resolve(stream);
}).catch((error: any) => {
console.log(error);
resolve(null);
})
});
}
import { getDesktopCapturerSource } from "xxx.ts";
import { getInitStream } from "yyy.ts";
import ScreenShot from "js-web-screen-shot";
export const doScreenShot = async ()=>{
// 下面这两块自己考虑
const sources = await getDesktopCapturerSource(); // 这里返回的是设备上的所有窗口信息
// 这里可以对`sources`数组下面id进行判断 找到当前的electron窗口 这里为了简单直接拿了第一个
const stream = await getInitStream(sources[0]);
new ScreenShot({
enableWebRtc: true, // 启用webrtc
screenFlow: stream!, // 传入屏幕流数据
level: 999,
});
}
感谢 @Vanisper 提供的在electron环境下使用本插件的兼容思路。
如果你看完上个章节的使用方法,依然不是很理解的话,这里准备了一份在electron环境下使用本插件的demo,请移步electron-js-web-screen-shot-demo。
截图插件有一个可选参数,它接受一个对象,对象每个key的作用如下:
enableWebRtc 是否启用webrtc,值为boolean类型,值为false则使用html2canvas来截图screenFlow 设备提供的屏幕流数据(用于electron环境下自己传入的视频流数据),需要将enableWebRtc属性设为truecompleteCallback 截图完成回调函数,值为Function类型,最右侧的对号图标点击后会将图片的base64地址回传给你定义的函数,如果不传的话则会将图片的base64地址放到sessionStorage中,你可以通过下述方式拿到他:sessionStorage.getItem("screenShotImg");
closeCallback 截图关闭回调函数,值为Function类型。triggerCallback 截图响应回调函数,值为Function类型,使用html2canvas截屏时,页面图片过多时响应会较慢;使用webrtc截屏时用户点了分享,该函数为响应完成后触发的事件。回调函数返回一个对象,类型为: {code: number,msg: string, displaySurface: string | null,displayLabel: string | null},code为0时代表截图加载完成,displaySurface返回的的是当前选择的窗口类型,displayLabel返回的是当前选择的标签页标识,浏览器不支持时此值为null。cancelCallback 取消分享回到函数,值为Function类型,使用webrtc模式截屏时,用户点了取消或者浏览器不支持时所触发的事件。回调函数返回一个对象,类型为:{code: number,msg: string, errorInfo: string},code为-1时代表用户未授权或者浏览器不支持webrtc。level 截图容器层级,值为number类型。canvasWidth 画布宽度,值为number类型,必须与高度一起设置,单独设置无效。canvasHeight 画布高度,值为number类型,必须与宽度一起设置,单独设置无效。position 截图容器位置,值为{left?: number, top?: number}类型clickCutFullScreen 单击截全屏启用状态,值为boolean类型, 默认为falsehiddenToolIco 需要隐藏的截图工具栏图标,值为Object类型,默认为{}。传你需要隐藏的图标名称,将值设为true即可,除关闭图标外,其他图标均可隐藏。可隐藏的key如下所示:
square 矩形绘制round 圆形绘制rightTop 箭头绘制brush 涂鸦mosaicPen马赛克工具text 文本工具separateLine 分割线save 下载图片undo 撤销工具confirm 保存图片showScreenData 截图组件加载完毕后,是否显示截图内容至canvas画布内,值为boolean类型,默认为false。customRightClickEvent 自定义容器的右键点击事件,值为Object类型,接受2个参数:
state 是否拦截右键点击,值为boolean类型,默认为false。handleFn 拦截后的事件处理函数,该属性为可选项,如果不传,默认行为是销毁组件。imgSrc 截图内容,如果你已经通过其他方式获取到了屏幕内容(例如electron环境),那么可以将获取到的内容传入,此时插件将使用你传进来的图片,值为string类型(可以为图片url地址或者base64),默认为null。loadCrossImg 是否加载跨域图片,值为boolean类型,默认为false。proxyUrl 代理服务器地址,值为string类型,默认为""screenShotDom 需要进行截图的容器,值为HTMLElement类型,默认使用的是body。cropBoxInfo 初始裁剪框,值为{ x: number; y: number; w: number; h: number }类型,默认不加载。wrcReplyTime webrtc模式捕捉屏幕时的响应时间,值为number类型,默认为500ms。wrcImgPosition webrtc模式下是否需要对图像进行裁剪,值为{ x: number; y: number; w: number; h: number }类型,默认为不裁剪。noScroll 截图容器是否可滚动,值为boolean类型,默认为true。maskColor 蒙层颜色,值为{ r: number; g: number; b: number; a: number }类型,默认为:{ r: 0; g: 0; b: 0; a: 0.6 }toolPosition 工具栏展示位置,值为string类型,默认为居中展示,提供三个选项:
left 左对齐于裁剪框center 居中对齐于裁剪框right 右对齐于裁剪框writeBase64 是否将截图内容写入剪切板,值为boolean类型,默认为truewrcWindowMode 是否启用窗口截图模式,值为boolean类型,默认为false,即当前标签页截图。如果标签页截图的内容有滚动条或者底部有空缺,可以考虑启用此模式。hiddenScrollBar 是否隐藏滚动条,用webrtc模式截图时chrome 112版本的浏览器在部分系统下会挤压出现滚动条,如果出现你可以尝试通过此参数来进行修复。值为Object类型,有4个属性:
state: boolean; 启用状态, 默认为falsefillState?: boolean; 填充状态,默认为falsecolor?: string; 填充层颜色,滚动条隐藏后可能会出现空缺,需要进行填充,默认填充色为黑色。fillWidth?: number; 填充层宽度,默认为截图容器的宽度fillHeight?: number; 填充层高度,默认为空缺区域的高度使用当前标签页进行截图相对而言用户体验是最好的,但是因为
chrome 112版本的bug会造成页面内容挤压导致截取到的内容不完整,因此只能采用其他方案来解决此问题了。wrcWindowMode和hiddenScrollBar都可以解决这个问题。
wrcWindowMode方案会更完美些,但是用户授权时会出现其他的应用程序选项,用户体验会差一些hiddenScrollBar方案还是采用标签页截图,但是会造成内容挤压,底部出现空白。两种方案的优点与缺点讲完了,最好的办法还是希望
chrome能在之后的版本更新中修复此问题。
上述类型中的
?:为ts中的可选类型,意思为:这个key是可选的,如果需要就传,不需要就不传。
imgSrc是url时,如果图片资源跨域了,必须让图片服务器允许跨域才能正常加载。同样的loadCrossImg设置为true时,图片资源跨域了也需要让图片服务器允许跨域。
插件容器监听了三个快捷键,如下所示:
Esc,按下键盘上的esc键时,等同于点了工具栏的关闭图标。Enter,按下键盘上的enter键时,等同于点了截图工具栏的确认图标。Ctrl/Command + z,按下这两个组合键时,等同于点了截图工具栏的撤销图标。插件暴露了一些内部变量出来,便于调用者根据自己的需求进行修改。
该函数用于获取截图容器的DOM,返回值为HTMLCanvasElement类型。
示例代码:
import ScreenShot from "js-web-screen-shot";
const screenShotHandler = new ScreenShot();
const canvasDom = screenShotHandler.getCanvasController();
注意:如果截图容器尚未加载完毕,获取到的内容可能为null。
该函数用于销毁截图容器,无返回值。
示例代码:
import ScreenShot from "js-web-screen-shot";
const screenShotHandler = new ScreenShot();
screenShotHandler.destroyComponents()
如果你需要修改截图工具栏的图标,可以通过覆盖元素css类名的方式实现,插件内所有图标的css类名如下所示:
以square为例,要修改它的图标,只需要将下述代码添加进你项目代码的样式中即可。
.square {
background-image: url("你的图标路径") !important;
&:hover {
background-image: url("你的图标路径") !important;
}
&:active {
background-image: url("你的图标路径") !important;
}
}
至此,插件的所有使用方法就介绍完了,该插件的Vue3版本,请移步:vue-web-screen-shot
FAQs
web端自定义截屏插件(原生JS版)
The npm package js-web-screen-shot-vv receives a total of 8 weekly downloads. As such, js-web-screen-shot-vv popularity was classified as not popular.
We found that js-web-screen-shot-vv demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
GitHub Actions checkout now blocks risky pull_request_target checkouts by default to help prevent pwn request supply chain attacks.

Product
Socket now supports Custom Roles and Repository Access Permissions so organizations can control who can access specific repositories and actions.

Product
Socket MCP now lets AI assistants review org alerts, investigate threats using the Socket threat feed, and inspect package files in addition to dependency scoring.