在上篇文章《使用 Fastboard 快速接入白板互动系统》中我们已经成功接入了 Fastboard 并拥有了一套和 Agora Flat 开源教室一样的白板互动系统。
如上图此时你已经可以运用左侧的画笔工具在白板上随意涂鸦,同时也支持使用手写板来写写画画。当一页白板写不下所有内容时,可以轻松点击右下方的新增一页按钮。
同时在工具栏最下方有一个插件中心,里面我们内置了一些实用的第三方工具,例如代码编辑器、Geogebra 数学教学工具、计时器等。
到此为止,你已经通过接入 Fastboard 拥有了一个功能相对完善的白板互动系统。如果你没有特殊的需求,在类似你画我猜、简单白板协作的场景中,这样的白板已经完全够用。
本篇文章依然以 Web 端为例,介绍如何使用 Fastboard 内置插件来满足复杂业务场景中常见的需求,比如教育场景中的文档演示功能,包括图片、音视频、PPT、PDF、在线资源(YouTube、Google Doc)如何插入白板,师生同步观看文档的同时,双方可以在文档上进行标注涂鸦。
备注:在满足文档演示需求时,个人认为互动白板解决方案要比屏幕分享更有整体优势,除了标注方便外,还有清晰度、对带宽、设备性能要求低的优越性。读者感兴趣的话可以留言说明,后面我们单独出一期对比分析文章。
细心的读者可能会问,Fastboard 上不是已经有一些内置插件了嘛,像 GeoGebra,今天要写的插件和已经内置进去的插件有什么不同?为什么不一起内置进去呢?这样用起来不是更方便?
首先是一个肯定的回答,今天要写的文档演示相关插件和已有的内置插件都是 Fastboard 内置支持的插件,用来丰富白板的使用场景、提高使用效率。
不同的点在于今天介绍的插件依赖于云存储(OSS)或者白板后端转码的结果,需要用户简单写一些业务代码才能正常演示和使用。所以 Fastboard 作为一个库支持了这些功能,但是没有在 UI 层面去展示,用户必须理解一些相关概念,同时写一部分业务代码才可以正常使用。
不过不用担心,本篇文章会帮助你理解这些概念并实现相关功能。
简单完善用户界面
在上篇文章《使用 Fastboard 快速接入白板互动系统》基础之上,在 index.html 中简单实现几个上传文档的按钮。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>fastboard</title>
<link rel="stylesheet" href="./index.css" />
</head>
<body>
<div id="app"></div>
<div id="upload">
<button id="add-img">上传图片</button>
<button id="add-audio">上传音频</button>
<button id="add-vedio">上传视频</button>
<button id="add-ppt">上传PPT</button>
<button id="add-youtube">YouTube</button>
<button id="add-googledoc">Google DOC</button>
<button id="clear-apps">清空所有 App</button>
</div>
<script type="module" src="/main.js"></script>
</body>
</html>
新建 index.css 文件,简单写一下按钮的样式。
#app {
width: 100vw;
height: 100vh;
border: 1px solid;
}
#upload {
padding: 8px;
position: fixed;
top: 0;
right: 0;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
z-index: 9;
}
#upload > button {
cursor: pointer;
}
接下来我们来实现上传功能。
实现上传功能
在上篇文章《使用 Fastboard 快速接入白板互动系统》基础之上,在 main.js 中实现上传功能。
上传图片
var btn = document.getElementById("add-img");
btn.onclick = function addImg() {
app.insertImage(
"https://meta.appinn.net/uploads/default/original/3X/b/d/bda0c2d51c9f493ef20207d16050044a37e27195.jpeg"
);
};
其中Url是该图片文件的 CDN 地址,需保证该图片权限为公开可访问,否则白板无权限访问。
上传音视频
var btn = document.getElementById("add-audio");
btn.onclick = function addAudio() {
app.insertMedia(
"test.mp3",
"https://flat-storage.oss-accelerate.aliyuncs.com/cloud-storage/2022-03/27/7a46c06a-4e86-4aef-966f-8ac9d7e84e96/7a46c06a-4e86-4aef-966f-8ac9d7e84e96.mp4"
);
};
var btn = document.getElementById("add-vedio");
btn.onclick = function addVedio() {
app.insertMedia(
"test.mp4",
"https://flat-storage.oss-accelerate.aliyuncs.com/cloud-storage/2022-03/27/7a46c06a-4e86-4aef-966f-8ac9d7e84e96/7a46c06a-4e86-4aef-966f-8ac9d7e84e96.mp4"
);
};
其中Url是该媒体文件的 CDN 地址,需保证该媒体资源权限为公开可访问,否则白板无权限访问。
展示音视频
上传 PPT、PDF、Word 文档
const appId = await app.insertDocs("文件名.pptx", conversioResponse);
其中 conversionResponse 是转码结果,这一步必不可少,经过转码才可以将 PPT、PDF、Word 等本地格式的资源转为可以在线查看的资源。可以点击链接查看转码相关文档。
代码示例:
var btn = document.getElementById("add-ppt");
btn.onclick = function addPPT() {
app.insertDocs("开始使用Flat.pptx", {
uuid: "feae41208e0b11ecb954e907f43a0c2c",
type: "dynamic",
status: "Finished",
progress: {
totalPageSize: 29,
convertedPageSize: 29,
convertedPercentage: 100,
convertedFileList: [
{
width: 1280,
height: 720,
conversionFileUrl:
"pptx://convertcdn.netless.link/dynamicConvert/feae41208e0b11ecb954e907f43a0c2c/1.slide",
preview:
"https://convertcdn.netless.link/dynamicConvert/feae41208e0b11ecb954e907f43a0c2c/preview/1.png",
},
{
width: 1280,
height: 720,
conversionFileUrl:
"pptx://convertcdn.netless.link/dynamicConvert/feae41208e0b11ecb954e907f43a0c2c/2.slide",
preview:
"https://convertcdn.netless.link/dynamicConvert/feae41208e0b11ecb954e907f43a0c2c/preview/2.png",
},
{
width: 1280,
height: 720,
conversionFileUrl:
"pptx://convertcdn.netless.link/dynamicConvert/feae41208e0b11ecb954e907f43a0c2c/3.slide",
preview:
"https://convertcdn.netless.link/dynamicConvert/feae41208e0b11ecb954e907f43a0c2c/preview/3.png",
},
],
currentStep: "Packaging",
},
});
};
展示 YouTube 在线资源
var btn = document.getElementById("add-youtube");
btn.onclick = function addYouTube() {
const appId = app.manager.addApp({
kind: "Plyr",
options: { title: "YouTube" },
attributes: {
src: "https://www.youtube.com/embed/bTqVqk7FSmY",
provider: "youtube",
},
});
};
其中Url是 YouTube 视频的链接。
展示 Google Doc 协同文档
var btn = document.getElementById("add-googledoc");
btn.onclick = function addGoogleDOC() {
const appId = app.manager.addApp({
kind: "EmbeddedPage",
options: { title: "Google Docs" },
attributes: {
src: "https://docs.google.com/document/d/1bd4SRb5BmTUjPGrFxU2V7KI2g_mQ-HQUBxKTxsEn5e4/edit?usp=sharing",
},
});
};
其中 Url 是 Google Doc 文档的链接,上传到白板后不仅可以同步展示,你还可以与你的学生协同编辑。
注意:EmbeddedPage 使用
<iframe>
来显示外部资源,由于浏览器限制,最好不要嵌套使用 iframe(即 iframe 内还有 iframe,通常来说浏览器会对第二层 iframe 增加十分多的限制或者根本无法使用)
总结
现在我们通过接入 Fastboard 实现了一个白板互动系统,不仅可以满足简单的在线板书、在线协作需求,而且可以满足复杂场景下使用不同效率插件的需求,比如代码编辑器、在线文档展示、在线文档写协作等。
最后你可能会问,以上都是在介绍如何使用 Fastboard 内置插件来满足场景需求,那遇到你们官方不会去实现的场景插件,是否支持用户去自定义实现插件?实现难度如何?
答案是肯定的,我们支持用户自定义互动插件,下一篇文章会专门来介绍,敬请期待。
如果你在动手实现的过程中遇到问题欢迎留言互动,我们很乐意能够帮助到你。
PS:上文提到的 Fastboard 和 Agora Flat 开源教室均为开源项目,感兴趣的朋友可以前往 GitHub 查看源码。
Agora Flat 开源教室:https://flat.whiteboard.agora.io
Web 端 Fastboard:GitHub - netless-io/fastboard: An open sourced whiteboard starter based on white-web-sdk. 快速开始白板应用。
Android 端 Fastboard:GitHub - netless-io/fastboard-android
iOS 端 Fastboard:GitHub - netless-io/fastboard-iOS: Quickly create a whiteboard interface for iOS