Pano开发者中心
  • 开发者中心
  • 下载中心

›白板

新手入门

  • 简介
  • 名词解释
  • 创建第一个应用

规则说明

  • Channel ID命名规则
  • 权限控制
  • 计费说明
  • 频道最大时长说明
  • 每月一万分钟免费说明
  • 布局参数说明
  • 水印

场景方案

    教育行业

    • 1vN互动小班课
    • 互动直播大班课

快速接入

  • 简介
  • 音视频

    • Windows (C++)
    • iOS (Objective-C)
    • Android (Java)
    • Web
    • Electron
    • Flutter
    • React Native
    • Unity

    白板

    • Windows (C++)
    • iOS (Objective-C)
    • Android (Java)
    • Web
    • Electron
    • Flutter
    • React Native

高级功能(RTC)

  • 简介
  • 屏幕共享
  • 分组讨论
  • 状态回调
  • 设备诊断
  • 音量指示
  • 控制声音
  • 声卡操作
  • 混音/伴音
  • 混响
  • 耳返
  • 变声
  • 美颜
  • 音视频数据回调
  • 音视频外部采集
  • 收发多路视频
  • 多窗口渲染
  • 性能检测
  • 截图
  • 反馈

高级功能(RTS)

  • 简介
  • 白板

    • Windows (C++)
    • iOS (Objective-C)
    • Android (Java)
    • Web
    • Flutter

    标注

    • 视频标注
    • 共享标注
    • 外部标注

    消息

    • 消息服务

    远程控制

    • 远程控制

操作实践

  • 切换大小屏

RESTful API

  • 基本格式
  • 生成Token
  • 频道管理
  • 云端录制
  • CDN推流
  • 文档转码
  • 消息服务
  • 服务端消息通知

SDK API

  • SDK接口说明
  • Windows (C++)
  • macOS/iOS (Objective-C)
  • Android (Java)
  • Web SDK (IE专用版)
  • Web SDK

    • 浏览器兼容性
    • RtcEngine
    • GroupManager
    • RtcWhiteboard
    • RtsService
    • RtcMessage
    • Annotation
    • Constants

更新记录

  • 简介
  • Windows
  • macOS
  • iOS
  • Android
  • Electron
  • Flutter
  • React Native
  • Unity
  • Web(全功能SDK)
  • Web(RTS SDK)
  • Web(IE专用音视频SDK)

帮助

  • FAQ
  • 更多帮助

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,销毁本地白板,断开白板服务,踢出该白板内所有用户,停止所有用户计费
Last updated on 3/9/2022
← Android (Java)Flutter →
  • 文档操作
    • 上传文档
    • 加载文档
    • 列举文档
    • 切换文档
    • 删除文档
    • 获取当前页码
    • 获取当前文档页码总数
    • 切换页码
    • 添加页面
    • 添加页面到指定位置
    • 删除页面
  • 课件操作
    • 步骤跳转
    • 课件交互
  • 视角跟随
    • 事件通知
    • 分享视角
    • 跟随视角
  • 对接手写板
    • 事件驱动
    • 设置手写板缩放和位移
    • 手写板绘制模式
  • 其他操作
    • 固定白板宽高
    • 设置语言(国际化)
    • 广播消息
    • 发送消息
    • 截图
    • 获取统计信息
  • 多白板
    • 获取白板
    • 停止白板
  • open/close/leave/stop的区别
浙ICP备20002645号 ©2019-2022 Pano拍乐云