Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
alibabacloud-tdsr-js-sdk
Advanced tools
三维重建(TDSR)SDK 主要为三维重建(TDSR)提供了平台生成的三维模型的:模型播放能力、 与模型进行互动的能力、以及标签标注能力。整个 SDK 分为 PanoramaScenePlayer 和 PanoramaSceneEdtior 两部分:
该 SDK 与框架无关,您可在 React 框架中使用,也可嵌入到 Angular\Vue 等任何框架中 使用。本文档将以嵌入 React 的方式演示如何利用该 SDK 加载三维模型以及如何与三维模 型进行交互。
PanoramaScenePlayer 相关,详见第 5 章
初始化 PlayerService 对象, 该对象封装了前后端通信的能力,提供与后端接口交互 API,详见章节 4。
const service = new PanoramaScenePlayerService();
// service.registerFetch(utils.mock) // NOTICE: 本地mock测试,线上不要使用
service.registerHook({
// 详见章节4
async request(method, url, data, header) {
const prefix = '//localhost/aoding/demo';
return [`${prefix}${url}`, data, header];
},
async response(result, context) {
return {
code: result.code,
message: result.message,
data: result.data,
};
},
});
初始化播放器对象
const player = new PanoramaScenePlayer(document, {
service: service, // PlayerService对象
mode: '1', // mode: 1 | 2, 参数详见5.1
});
模型加载
await player.load(token); // TODO: 请求获取模型数据接口,并加载模型
设置监听事件,详见 5.3 节
player.registerSceneHook({
onOrbitRotate: (quaternion) => {
console.log('Current Quaternion', quaternion);
},
onChangePanorama: (panoId) => {
console.log('Current Panorama', panoId);
},
});
基于 React 的完整代码如下:
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import {
PanoramaScenePlayer,
PanoramaScenePlayerService,
utils,
DefaultSceneData,
} from 'alibabacloud-tdsr-js-sdk';
import axios from 'axios';
/**
* 加载模型
* @param {string} token
* @param {HTMLDivElement} target
*/
function usePlayer(token, target) {
const [myPlayer, setMyPlayer] = React.useState(null);
const init = async () => {
const service = new PanoramaScenePlayerService();
service.registerHook({
// 详见章节4
async request(method, url, data, header) {
const prefix = '//localhost/aoding/demo';
return [`${prefix}${url}`, data, header];
},
async response(result, context) {
return {
code: result.code,
message: result.message,
data: result.data,
};
},
});
const player = new PanoramaScenePlayer(target.current, {
service: service,
mode: '1', // 如果想预览未发布的Tag, mode设置为2,mode参数详见5.1
});
await player.load(token); // 请求接口&加载模型
// 设置监听事件,详见5.3节
player.registerSceneHook({
onOrbitRotate: (quaternion) => {
console.log('Current Quaternion', quaternion);
},
onChangePanorama: (panoId) => {
console.log('Current Panorama', panoId);
},
});
return player;
};
React.useEffect(() => {
init().then((p) => setMyPlayer(p));
}, [token]);
return myPlayer;
}
function Player(props) {
// token 即 listMainScenes 接口中获取的 previewToken
const token = '58b51071d0a446318607443bd2135d74';
const target = React.useRef();
const player = usePlayer(token, target);
const style = {
width: '100%',
height: 450,
position: 'relative',
};
return <div ref={target} style={style} />;
}
ReactDOM.render(<Player />, mountNode);
PanoramaSceneEditor 相关,详见第 6 章
初始化 PanoramaSceneEditorService 对象, 该对象封装了前后端通信的能力,提供与 后端接口交互 API,详见下一章节。
const service = new PanoramaSceneEditorService();
service.registerFetch(utils.mock); // NOTICE: 本地mock测试,线上不要使用
初始化播放器对象
const editor = new PanoramaSceneEditor(document, {
service,
autoSave: false,
});
模型加载
await editor.load(token);
设置监听事件,详见 5.3 节
editor.registerTagHook({
onSelected: (tag) => {
console.log('tag', tag);
},
});
基于 React 的完整代码如下:
import React, { useCallback, useState, useEffect } from 'react';
import {
PanoramaSceneEditor,
PanoramaSceneEditorService,
} from 'alibabacloud-tdsr-js-sdk';
/**
* 加载模型
* @param {string} token
* @param {HTMLDivElement} target
*/
function useEditor(token, target) {
const [editor, setEditor] = useState(null);
const init = async () => {
const service = new PanoramaSceneEditorService();
// service.registerFetch(utils.mock) // NOTICE: 本地mock测试,线上不要使用
service.registerHook({
async request(method, url, data, header) {
const prefix = '//localhost/aoding/demo'; // 域名需更换为业务方自己服务器域名
return [`${prefix}${url}`, data, header];
},
async response(result, context) {
return {
code: result.code,
message: result.message,
data: result.data,
};
},
});
const editor = new PanoramaSceneEditor(target.current, {
service,
autoSave: false, // 是否开启标签自动保存
});
await editor.load(token); // 请求接口&加载模型
editor.registerTagHook({
// 标签创建必要
onCreating: () => {
// tag参数,详见6.4.1
const tag = {
type: 'TEXT',
config: {
backgroundColor: '#000',
content: '444',
title: '1231',
},
};
return tag;
},
// 标签创建完成
onCreated: (tag) => {
console.log(tag);
// editor.updateTag(tag.id, tag)
},
});
return editor;
};
useEffect(() => {
init().then((editor) => {
setEditor(editor);
});
}, [token]);
return editor;
}
function Editor(props) {
// token 即 listMainScenes 接口中获取的 previewToken
const token = 'f9d19ae0541f4131bb787d8a4521d46d';
const target = React.useRef();
const editor = useEditor(token, target);
// 添加标签
const addTag = useCallback(() => {
if (!editor) return;
// tips: 添加标签,需配合onCreating事件使用
editor.setState(2); // tips: 改为2 即 EDIT态,可鼠标右键创建标签
// editor.createTagInView({ x: 1, y: 1 }) // 在指定位置添加标签
}, [editor]);
// 切换至3D模型,DollHouse: 3D模型,Panorama: 全景模式
const go3D = useCallback(() => {
if (!editor) return;
editor.changeView('DollHouse');
}, [editor]);
// 保存标签
const save = useCallback(() => {
if (!editor) return;
// save后的标签,可在mode为Preview时展示
editor.save();
}, [editor]);
// 发布标签
const publish = useCallback(() => {
if (!editor) return;
// save后的标签,可在mode为Online时展示
editor.publish();
}, [editor]);
return (
<div>
<div
ref={target}
style={{
width: '100%',
height: 450,
position: 'relative',
}}
/>
<button onClick={() => addTag()}>ADD Tag</button>
<button onClick={() => go3D()}>go 3D</button>
<button onClick={() => save()}>save</button>
<button onClick={() => publish()}>publish</button>
</div>
);
}
export default Editor;
SDK 需要依赖后端接口进行模型的加载以及标签的增删改查,考虑到安全性,需要业务
方对依赖接口进行转发,其架构如下图。三维重建服务端把依赖的后端接口通过 Open
API 的方式开放给业务方,业务方可以通过 Open API SDK 方式与这些接口进行交互,并通
过 WEB API 方式转发给 WEB 端的播放器。播放器通过转发后的 API 实现三维重建服务端
通信, 又能保证其安全性,以及各平台兼容性
。
PanoramaScenePlayerService、PanoramaSceneEditorService
对象封装了通信能力,开发者可以通过
const service = new PanoramaSceneEditorService();
和
const service = new PanoramaSceneEditorService();
的方式创建该对象。
Mock:为了方便开发者进行本地调试 ,PanoramaScenePlayerService、PanoramaSceneEditorService 提供了 Mock 数据的能 力,开发者在开发前期可以通过如下的方式加载 Mock 数据进行本地开发
service.registerFetch: (replacedFetch: fetch) => viod;
替换底层 fetch 库,
用于 mock 数据
service.registerFetch(utils.mock); // NOTICE: 本地mock测试,线上不要使用
协议适配: 考虑到不同业务方前后端通信协议会有较大差异 ,PanoramaScenePlayerService、PanoramaSceneEditorService 开发了协议转换的能力 ,用户可以通过 registerHook 接口进行协议转换。比如以下 Code 给 URL 增加前缀, 同时对返回结果进行适配
service.registerHook: ({request, response}) => viod;
参数说明:
request 请求拦截器
method: GET | POST 请求方式
url: string 临云镜后端 SDK 接口地址,接口在前端 SDK 内部调用,详见下
文服务端接口对应交互API
data: object 请求参数
header: object 请求头
response 响应拦截器
code: number 状态码 code:0 为成功,否则抛出异常
message: string 错误信息
data: object 临云镜后端 SDK 返回的 data 数据,具体参数详见临云镜服务端 SDK 接口文档
示例
service.registerHook({
// 请求拦截器
async request(method, url, data, header) {
const prefix = '//localhost/biz'
return [`${prefix}${url}`, data, header];
},
// 响应拦截器
async response(result, context) {
return {
code: result.errorCode,
message: result.errorMessage,
data: result.data
}
});
API: 以下 API 均为 SDK 内部已封装集成,无需手动调用(域名需业务方自己通过 registerHook 配置),API 内会自动调用服务端接口。接口参数可参考临云镜服务端 SDK 接口文档。
- PanoramaScenePlayerService
> player.load()时,SDK内部调用
- service.getPanoramaConfigData: `(token: string) => response;` 获得全局配置信息,调用接口:`/getWindowConfig`
- service.getSceneData: `(token: string) => response;` 获取场景渲染数据,调用接口:`/getSceneData`
- service.getTags: `(subSceneUuid: number, previewToken: string, type: number) => response;` 获取所有热点标注数据,调用接口:`/getHotspotTag`
- PanoramaSceneEditorService
> tips: 继承 PanoramaScenePlayerService 所有 API,无需手动调用,save()&publish()时自动调用
- service.saveTags: `(subSceneUuid: number, tags: ICombinedTag[]) => response;` 保存标签。tips: ICombinedTag为标签数据,调用接口:`/saveHotspotTag`
- service.publish: `(subSceneUuid: number) => response;` 发布标签,调用接口:`/publishHotspot`
PanoramaScenePlayer 对象提供了基本模型加载,模型交互(如场景漫游,飞入标签,多视 图切换,事件监听等能力)
constructor(target: HTMLDivElement, protected config: IPanoramaScenePlayerConfig)
加载模型,previewToken 为模型的唯一标示,可以通过 OPEN API 提供的接口获得,详 见后端 SDK
async player.load(previewToken: string)
卸载模型
async player.unload()
registerSceneHook(hooks); // hooks: {} 一个事件对象
() => void;
加载完成事件(type: EnumPanoramaSceneView) => void;
切换全景/3D 模式
事件(panoId: string) => void;
切换子场景事件(quanertion: TypeQuaternion) => void;
场景旋转, 目前暂
不支持三维空间旋转player.getTagList()
获得所有标签player.getTagListByPanoramaId(panoId)
获得当前子场景下标签player.getPanoramaList()
获得所有子场景player.changeView(view)
切换视图,支持 DollHouse(3D 模式)\Panorama(全景模
式),player.flyToPanoramaById(panoId)
跳转到指定子场景player.hideTag()
隐藏标签player.showTag()
显示标签player.flyToTag(tagId)
跳转到指定标签位置player.getTagClientPosition(tagId)
获得 Tag 的屏幕坐标player.getCurrentPanorama()
获得当前子场景,若在 Dollhouse(3D)模式下,返
回为 undefinedplayer.isTagInViewScene(tagId)
判断标签是否当前视口可见player.getRotateQuaternion()
获得当前场景旋转四元组player.setRotateQuaternion(quaternion)
设置当前场景的旋转四元组PanoramaSceneEditor 继承了 PanoramaScenePlayer 对象,该对象除了提供模型加载,模 型交互,还提供了标签编辑的能力,可以跟进 API 进行标签创建、标签删除、标签修改等 操作。
constructor(target: HTMLDivElement, protected config: IPanoramaSceneEditorConfig)
加载模型,previewToken 为模型的唯一标示,可以通过 OPEN API 提供的接口获得,详 见后端 SDK
async editor.load(previewToken: string)
卸载模型
async editor.unload()
registerTagHook(hooks); // hooks: {} 一个事件对象
(tag: ICombinedTag) => void;
点击标签事件(tag: ICombinedTag) => boolean;
标签选中事件(tag: ICombinedTag) => boolean;
标签取消选中事件() => ICombinedTag;
创建标签事件(tag: ICombinedTag) => void;
标签创建完成事件(tag: ICombinedTagWithScenePosition[]) => void;
标
签位置更新事件(tag: ICombinedTag) => void;
标签拖拽事件(tag: ICombinedTag) => void;
标签拖拽事件(tag: ICombinedTag) => void;
标签拖拽事件PanoramaSceneEditor 继承了 PanoramaScenePlayer 所有 API 除此之外 ,PanoramaSceneEditor 还提供了跟标签编辑有关的 API
创建标签目前只能在全景模型下创建,标签创建必须通过 onCreating 事件。
自定义创建 tips(参考 3.2 示例): 1.通过 onCreating 创建默认标签。2.通过 onCreated 拿到标签 Id。3. 通过
editor.updateTag(tagId, tag)
方法自定义标签内容
通过注册 onCreating 事件回填标签内容
tag 参数说明:
type: tag 类型支持 IMAGE | TEXT | VIDEO
tips: VIDEO 类型的暂时无法播放!如果有播放需求,需业务方前端额外添加弹 出层,视频在弹出框中播放
config: tag 配置
formSelectImgType: 'default'(默认) | 'point'(小标) | 'mural'(壁纸); 图片 类型,仅 IMAGE 支持
title: string 标题
content: string 内容
backgroundColor: string 背景色
images: string[] 图片 CDN 地址
video: string 视频 CDN 地址
tag 示例:
图片:
{
type: 'IMAGE',
config: {
backgroundColor: '#000', // 背景色
images: [ // 图片cdn地址
'http://s.alicdn.com/@lyj/pano_src/100070-82766/hotspot/image/4bbc-06439_LD.png',
],
title: '22222',
formSelectImgType: 'mural',
},
}
文本:
{
type: 'TEXT',
config: {
backgroundColor: '#000',
title: '22222',
content: '11111'
},
}
视频:
{
type: 'VIEDO',
config: {
backgroundColor: '#000',
title: '22222',
content: '11111',
video: '' // 视频cdn地址
},
}
onCreating 示例:
editor.registerTagHook({
onCreating: () => {
const tag = {
type: 'IMAGE',
config: {
backgroundColor: '#000',
images: [
'http://s.alicdn.com/@lyj/pano_src/100070-82766/hotspot/image/4bbc-06439_LD.png',
],
title: '60152892558',
formSelectImgType: 'mural',
},
};
return tag;
},
});
通过 createTagInView(position?: { x: number, y: number })
接口创建标签,默
认在视口中心创建
editor.createTagInView();
另外也支持通过鼠标点击方式在指定位置创建标签,开启鼠标点击交互能力
/*
播放器状态, state: 1 | 2 默认为: 1
1: ROMA, 默认允许进行场景漫游,场景旋转等操作
2: EDIT, 编辑态,允许用户右键创建标签
*/
editor.setState(1)
editor.setState(2)
const state = editor.getState() // 获得当前播放器状态
6.4.2 更新标签
editor.updateTag(tagId, tag);
6.4.3 选中标签
editor.selectTag(tagId);
6.4.4 删除标签
editor.deleteTag(tagId);
6.4.5 保存标签
当开启了 autoSave 模式,模型创建、模型取消选中、模型更新、模型拖拽都会触发保
存,否则就需要调用 save()
手动触发保存。
保存后的标签可以在 PanoramaScenePlayer 的 Preiview 模式查看,但是不能 Online 模式查看
editor.save();
6.4.6 发布标签
发布后的标签既可以在 PanoramaScenePlayer 的 Preiview 模式查看,又可以在 Online 模式查看
editor.publish();
FAQs
We found that alibabacloud-tdsr-js-sdk demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers 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 removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.