Web
本文介绍 Web 白板的部分高级功能。
请先查看 Web 白板快速接入指南 了解基本功能后,再查看此文档。
文档操作
Pano 白板支持多份文档,每份文档支持多个页面。
即白板的层级结构为:白板 -> 文档 -> 页面。
调用
RtcWhiteboard
实例的open
方法打开白板时,会自动生成docId
和name
均为'default'
的只有一页的默认文档。
上传文档
通过 RtcWhiteboard
实例的 uploadDoc(onDocTranscodeStatus: function, transcodeType: "doc" | "courseware" | "pdf", needThumb: boolean, lifeType: 1 | 2, meta?: string)
方法上传文档。
- 调用此接口会自动打开文件选择框。
- 文件上传后会自动转码,转码成功后自动创建一份新的白板文档,文档创建成功会触发
docCreated
事件。 - 如果上传的文件有多页,则新创建的白板文档也相应有多页。
- 对于
transcodeType
参数:- 为
"doc"
时支持 Word/Excel/PowerPoint/PDF 文件转码为图片) - 为
"courseware"
时仅支持 PowerPoint 文件转码为动态课件) - (2.4.0 版本新增) 为
"pdf"
时支持 Word/Excel/PowerPoint/PDF 文件转码为 PDF 格式高清文档)。
- 为
needThumb
参数表示是否生成文档缩略图。lifeType
参数表示转码结果保存时间:1 - 长期,2 - 临时。- 早期的 SDK 版本不支持
needThumb
和lifeType
参数。 - 从 2.2.6 版本开始支持可选的
meta
参数,该参数将随文档转码结果原样返回给服务端,用于开发者传递自定义信息。
为了获得更好的体验,请参考 文档转码建议。
rtcWhiteboard.uploadDoc(obj => {
console.info(obj)
}, 'doc', true, 1);
加载文档
通过 RtcWhiteboard
实例的 loadDoc(fileKey: string)
方法加载已转码的文档。
- 对于 Web SDK,调用 上传文档
uploadDoc
接口时,当回调函数的code
为 3 时,表示转码完成,可以获取fileKey
参数。 - 对于服务端,文档转码相关接口及 Webhook 回调的
docId
参数即对应 Web SDK的fileKey
参数。
rtcWhiteboard.loadDoc("1234567890").then(info => console.info(info));
还可以通过 RtcWhiteboard
实例的 addPdfDoc(url, name)
方法使用外部 URL 加载第三方 PDF 文档。
列举文档
通过 RtcWhiteboard
实例的 enumerateDocs()
方法列举文档信息。
rtcWhiteboard.enumerateDocs();
切换文档
通过 RtcWhiteboard
实例的 switchToDoc(docId: string)
方法切换文档。
rtcWhiteboard.switchToDoc('default');
删除文档
通过 RtcWhiteboard
实例的 deleteDoc(docId: string, switchDocId?: string)
方法删除文档。
switchDocId
参数表示删除后跳转到指定文档(如果不传值并且删除当前文档,则跳转至默认文档)
rtcWhiteboard.deleteDoc('1234567890');
默认文档不支持删除。
获取当前页码
通过 RtcWhiteboard
实例的 getCurrentPageNumber
方法获取当前页码(页码从 0 开始)。
rtcWhiteboard.getCurrentPageNumber();
获取当前文档页码总数
通过 RtcWhiteboard
实例的 getTotalNumberOfPages
方法获取当前文档的页码总数。
rtcWhiteboard.getTotalNumberOfPages();
切换页码
通过 RtcWhiteboard
实例的 prevPage
方法切换到当前文档的上一页,nextPage
方法切换到下一页。
rtcWhiteboard.nextPage();
通过 RtcWhiteboard
实例的 gotoPage(pageIndex: number, docId?: string)
方法切换到指定文档的指定页面(页码从 0 开始,如果不传 docId
默认操作当前文档)。
rtcWhiteboard.gotoPage(0, 'default');
添加页面
通过 RtcWhiteboard
实例的 addPage(autoSwitch: boolean)
方法添加一个新页面到当前文档最后。
- 添加页面是异步的,添加成功后会触发
whiteboardContentUpdate
事件,随后可以通过getTotalNumberOfPages
方法获取当前文档页码总数,通过getCurrentPageNumber
方法获取当前页码。 autoSwitch
参数表示是否自动切换到新页面。- 不支持对动态课件添加页面。
rtcWhiteboard.addPage(true);
添加页面到指定位置
通过 RtcWhiteboard
实例的 insertPage(pageIndex: number, autoSwitch: boolean, docId?: string)
方法添加一个新页面到指定文档的指定位置。
pageIndex
参数表示页码位置(页码从 0 开始),如果传入的参数超出文档页码总数,会返回"INVALID_INDEX"
。autoSwitch
参数表示是否自动切换到新页面。docId
参数如果不传,默认操作当前文档。- 不支持对动态课件添加页面。
rtcWhiteboard.insertPage(6, true);
删除页面
通过 RtcWhiteboard
实例的 removePage(index: number, docId?: string)
方法删除指定页面。
docId
参数如果不传,默认操作当前文档。- 不支持对动态课件删除页面。
rtcWhiteboard.removePage(1);
课件操作
本小节(课件操作)介绍的内容,仅适用于动态课件(
'courseware'
),不适用于普通文档('doc'
)。
步骤跳转
通过 RtcWhiteboard
实例的 coursewarePrev
方法跳转到课件的上一步,coursewareNext
方法跳转到下一步。
rtcWhiteboard.coursewareNext();
课件交互
通过 RtcWhiteboard
实例的 disableCoursewareInteraction
方法禁止用户通过键盘上下左右键控制课件交互,enableCoursewareInteraction
方法开启键盘方向键交互。
rtcWhiteboard.disableCoursewareInteraction();
通过 RtcWhiteboard
实例的 setToolType
方法设置工具类型为 ShapeType.Click
可以操作白板底部的课件。
rtcWhiteboard.setToolType(RtcWhiteboard.ShapeType.Click); // 可以操作白板底部的课件
视角跟随
视角跟随指的是和其他用户同步缩放或移动。
事件通知
请注意监听视角跟随相关的事件通知:
userVisionShareStart
:其他用户开始分享视角userVisionShareStop
:其他用户停止分享视角visionLockStop
: 自己分享视角时被他人抢占
分享视角
通过 RtcWhiteboard
实例的 startVisionShare
方法分享视角,stopVisionShare
方法停止分享。
开始和停止时,其他用户会收到通知。
同一时刻只能有一位用户分享视角,后分享的用户会导致正在分享的用户自动停止分享(后发抢占模式)。
rtcWhiteboard.startVisionShare();
跟随视角
通过 RtcWhiteboard
实例的 startFollowVision
方法跟随他人视角,stopFollowVision
方法停止跟随。
rtcWhiteboard.startFollowVision();
对接手写板
事件驱动
RtcWhiteboard
实例通过浏览器的自定义事件接收手写板的绘制指令,绘制指令结构如下:
type PanoPenEvent = {
// hang:手写笔悬停;start:书写开始;write:书写事件;end:书写结束
eventType: 'hang' | 'start' | 'write' | 'end'
x: number // 轨迹点 x 坐标
y: number // 轨迹点 y 坐标
width: number // 手写板宽度
height: number // 手写板高度
}
开发者需要根据您使用的手写板sdk里提供的事件类型,在接收到绘制事件时,转换为对应的 PanoPenEvent
的 eventType
,然后dispatch
到浏览器中,其中 start
类型不是必须的,可以直接发送 write
指令开始书写。
除了选择激光笔(ShapeType.LaserPointer)类型,其他绘制模式下手写板绘制指令均会绘制自由路径(ShapeType.Pen)
示例代码:
// 在某手写笔的sdk中接收到绘制事件时,判断该事件为书写的事件
// 假设书写事件的点位为 (100, 600),手写板的长宽为 1280 * 600
window.dispatchEvent(
new CustomEvent('panoPenEvent', {
detail: {
eventType: 'write',
x: 100,
y: 600,
width: 1280,
height: 600
}
})
);
设置手写板缩放和位移
以宽或以高为准缩放到白板画布
默认情况下,手写板的轨迹点位是以手写板的宽度作为缩放标准对应到画布上的,可以通过白板实例的 tabletMatchMode
属性指定以宽或高为准缩放
// tabletMatchMode: 'fitWidth' | 'fitHeight' = 'fitWidth'
console.log(rtcWhiteboard.tabletMatchMode); // 默认为 'fitWidth'
rtcWhiteboard.tabletMatchMode = 'fitHeight';
console.log(rtcWhiteboard.tabletMatchMode); // 输出 'fitHeight'
手写板缩放比例
通过白板实例的 tabletScale
属性设置手写板绘制到画布上的缩放比例,默认缩放比例为 1,即手写板是 1:1 对应到画布上的。
放大仅放大对应的点位,手写笔的轨迹宽度不受影响,轨迹宽度只受白板实例的 lineWidth
属性影响。
例如,当以tabletMatchMode
为 fitWidth
模式书写,在 tabletScale
为 1 时,在手写笔的水平 50% 位置画一个点,对应在白板上的位置也是水平50%的位置,当 tabletScale
为 2 时,在水平 50% 位置画一个点,在白板上对应的坐标值被放大了 2 倍,该点位在画布上对应为水平 100% 处。
移动端显示手写板的内容,如果默认比例下觉得写得字显示到白板上比较小,可以尝试把
tabletScale
设置大一点
console.log(rtcWhiteboard.tabletScale); // 默认为 1
rtcWhiteboard.tabletScale = 2;
console.log(rtcWhiteboard.tabletScale); // 输出 2,手写板在画布上被放大2倍
手写板位移
通过白板实例的 tabletTranslate
属性设置手写板相对于画布原点的位移比例,默认位移为 [0, 0],即手写板的左上角位置和画布的左上角(坐标[0, 0])位置一致。
位移的计算不受缩放影响。
console.log(rtcWhiteboard.tabletTranslate); // 默认为 [0, 0]
rtcWhiteboard.tabletTranslate = [100, 100];
console.log(rtcWhiteboard.tabletTranslate); // 输出 [100, 100]
手写板绘制模式
默认情况下手写板和白板画布是静态结合在一起的,默认情况下白板的画布是无限的,用户可以往任意方向无限托拽画布,但是手写板绘制的内容只会被限定在某个范围内显示,
可以通过设置白板实例的tabletWriteMode
属性设置让手写的内容不受拖拽影响,永远都以目前可视区域的左上角为原点计算对应的点位。
例如:假设白板的宽高为 500x500,手写板的宽高为 1000x2000,默认情况下,手写板内书写产生的轨迹点位只会被计算对应到白板的(0, 0) - (500, 1000) 的矩形范围内。
// tabletWriteMode: 'static' | 'sticky' = 'static'
console.log(rtcWhiteboard.tabletWriteMode); // 默认为 'static'
rtcWhiteboard.tabletWriteMode = 'sticky';
console.log(rtcWhiteboard.tabletWriteMode); // 输出 'sticky'
其他操作
固定白板宽高
Pano 白板默认是无界的,但是有的场景下开发者可能需要固定白板宽高。
通过 RtcWhiteboard
实例的 initVision(width: number, height: number, limited?: boolean)
方法设置白板宽高。
将 limited
参数指定为 true
来固定宽高。
- 各端设置的宽高数值需要保持一致。
- 打开白板时
open
接口传入的视图的宽高比需要和此处传入的宽高比保持一致。
rtcWhiteboard(640, 360, true);
设置语言(国际化)
通过 RtcWhiteboard
实例的 setLocale
方法设置语言。会影响音视频播放控件的界面语言等。
// rtcWhiteboard.setLocale('zh_CN'); // 设置为简体中文
rtcWhiteboard.setLocale('en'); // 设置为英语
广播消息
通过 RtcWhiteboard
实例的 broadcastMessage(message: any)
方法广播消息(发给白板频道内所有用户)。
rtcWhiteboard.broadcastMessage('这是一条广播消息');
收到消息会触发
messageReceived
事件通知。
发送消息
通过 RtcWhiteboard
实例的 sendMessage(to: string, message: any)
方法向特定用户发送消息。
rtcWhiteboard.sendMessage('10000', '这是一条定向消息');
收到消息会触发
messageReceived
事件通知。
截图
通过 RtcWhiteboard
实例的 snapshot(autoDownload: boolean, mode: 'all' | 'view')
方法截图。
autoDownload
参数表示是否自动下载mode
参数表示截图模式('all'
:截取整个页面,'view'
:截取当前可视区域)
rtcWhiteboard.snapshot(true, 'all');
获取统计信息
通过 RtcWhiteboard
实例的 getStatistics
方法获取用户创建的图形数据统计信息。
rtcWhiteboard.getStatistics();
多白板
获取白板
Pano 白板支持多白板的特色功能。
例如,对于多人教学场景,老师和学生之间可以使用一块公共白板,用于老师授课。
每位学生也可以有一块自己的白板,用于提交各自的学习内容。
老师可以切换查看公共白板和每位特定学生的白板,每位学生也可以切换查看公共白板和自己的白板。
如需使用 Web 多白板,请通过 RtsService
实例的 joinChannel
方法加入频道,再通过其 getWhiteboard
方法切换白板实例,随后即可调用 RtcWhiteboard
实例的 open
方法打开该白板。
// 获取默认白板(默认白板的 wbId 为 "default"),随后即可打开和操作该白板
const rtcWhiteboard_0 = RtsService.getInstance().getWhiteboard("default");
// 获取 "Student1" 白板,随后即可打开和操作该白板
const rtcWhiteboard_1 = RtsService.getInstance().getWhiteboard("Student1");
前缀为 "pano-" 的白板ID为保留值,开发者请不要使用。
停止白板
通过 RtcWhiteboard
实例的 stop
方法停止白板(注意:默认白板不能停止),此方法会指示服务器销毁当前白板并踢出所有加入该白板的用户,请谨慎使用。
rtcWhiteboard.stop();
open/close/leave/stop的区别
open
: 开启白板并且设置显示窗口,并且开始计费- 对于默认白板,如果任意用户调用
open
接口,则加入该白板频道的所有用户都会自动连接默认白板并开始计费。 - 对于自定义白板(多白板),各用户调用
open
接口时仅本人开始计费。
- 对于默认白板,如果任意用户调用
close
: 关闭白板UI,不会销毁本地白板,不会断开白板服务,不会停止本人计费 (可以重新open
)leave
: 关闭白板UI,销毁本地白板,断开白板服务,停止本人计费 (可以重新open
)stop
: 关闭白板UI,销毁本地白板,断开白板服务,踢出该白板内所有用户,停止所有用户计费