| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- import { __awaiter } from "tslib";
- import { PromiseQueue } from "./PromiseQueue";
- import { ROTATE_DIRECTION, ZOOM_ACTION, } from "./types";
- import { buildKrpanoAction, buildKrpanoTagSetterActions } from "./utils";
- export class KrpanoActionProxy {
- constructor(krpanoRenderer, name = "ReactKrpanoActionProxy") {
- this.eventHandlers = [];
- this.syncTagsLoaded = false;
- this.syncTagStack = [];
- this.krpanoRenderer = krpanoRenderer;
- this.name = name;
- // krpano 1.19 版本不支持动态插入 include,只能在文本中插入后重新加载
- this.dynamicTagWaitQueue = new PromiseQueue();
- }
- /**
- * 等待 include 标签加载完成
- */
- waitIncludeLoaded(push) {
- return this.syncTagsLoaded
- ? Promise.resolve()
- : // 先进后出
- this.dynamicTagWaitQueue[push ? "push" : "unshift"]();
- }
- /**
- * 执行 Javascript 函数
- * @param action 动作
- * @param nexttick 是否在下一个渲染帧后执行
- */
- call(action, nexttick = false) {
- var _a;
- const actionStr = nexttick ? `nexttick(${action})` : action;
- (_a = this.krpanoRenderer) === null || _a === void 0 ? void 0 : _a.call(actionStr);
- }
- set(name, ...params) {
- this.call(buildKrpanoAction("set", name, ...params));
- }
- /**
- * 动态添加标签
- * @param tag 标签
- * @param name 名称
- * @param attrs 属性
- */
- setTag(tag, name, attrs) {
- return __awaiter(this, void 0, void 0, function* () {
- let nexttick = false;
- if (tag === "hotspot" || tag === "events") {
- nexttick = true;
- }
- yield this.waitIncludeLoaded();
- this.call(buildKrpanoTagSetterActions(name ? `${tag}[${name}]` : tag, attrs), nexttick);
- });
- }
- get(name) {
- var _a;
- return (_a = this.krpanoRenderer) === null || _a === void 0 ? void 0 : _a.get(name);
- }
- /**
- * 删除场景
- * @param name 场景名称
- */
- removeScene(name) {
- if (this.get("scene") &&
- typeof this.get("scene").removeItem === "function") {
- this.get("scene").removeItem(name);
- }
- else {
- // TODO: report Error
- }
- }
- /**
- * 加载场景
- * @param name 场景 name
- */
- loadScene(name) {
- this.call(buildKrpanoAction("loadscene", name, "null", "MERGE", "BLEND(0.5)"));
- }
- /**
- * 旋转视图
- * @param direction 方位
- * @param degrees 旋转度数,默认为 10
- */
- rotateView(direction, degrees = 10) {
- let str = "";
- const view = this.get("view");
- switch (direction) {
- case ROTATE_DIRECTION.LEFT:
- str = `view.hlookat, ${(view.hlookat || 0) - degrees}`;
- break;
- case ROTATE_DIRECTION.RIGHT:
- str = `view.hlookat, ${(view.hlookat || 0) + degrees}`;
- break;
- case ROTATE_DIRECTION.UP:
- str = `view.vlookat, ${(view.vlookat || 0) - degrees}`;
- break;
- case ROTATE_DIRECTION.DOWN:
- str = `view.vlookat, ${(view.vlookat || 0) + degrees}`;
- break;
- }
- this.call(buildKrpanoAction("tween", str, 0.5));
- }
- /**
- * 缩放视图
- * @param action 动作
- * @param num 缩放大小
- */
- zoomView(action, num = 10) {
- const view = this.get("view");
- const targetFov = action === ZOOM_ACTION.IN ? -num : num;
- this.call(buildKrpanoAction("tween", "view.fov", (view.fov || 0) + targetFov, 1));
- }
- on(eventName, selector, handler) {
- this.eventHandlers.push({
- eventName: eventName.toLowerCase(),
- selector,
- handler,
- });
- return this;
- }
- off(eventName, selector, handler) {
- this.eventHandlers = this.eventHandlers.filter((e) => !(e.eventName === eventName.toLowerCase() &&
- e.selector === selector &&
- e.handler === handler));
- }
- fire(eventName, selector) {
- this.eventHandlers
- .filter((e) => e.eventName === eventName.toLowerCase() && e.selector === selector)
- .map(({ handler }) => handler(this));
- }
- bindEvents(selector, mapEventsToHandler) {
- Object.keys(mapEventsToHandler).map((eventName) => {
- const func = mapEventsToHandler[eventName];
- if (func) {
- this.on(eventName, selector, func);
- }
- });
- }
- unbindEvents(selector, mapEventsToHandler) {
- Object.keys(mapEventsToHandler).map((eventName) => {
- const func = mapEventsToHandler[eventName];
- if (func) {
- this.off(eventName, selector, func);
- }
- });
- }
- addHotspot(name, attrs) {
- return __awaiter(this, void 0, void 0, function* () {
- yield this.waitIncludeLoaded();
- this.call(buildKrpanoAction("addhotspot", name), true);
- this.setTag("hotspot", name, attrs);
- });
- }
- removeHotspot(name) {
- this.call(buildKrpanoAction("removehotspot", name), true);
- }
- pushSyncTag(tagName, attribute) {
- this.syncTagStack.unshift({
- tagName,
- attribute,
- });
- }
- createSyncTags() {
- return __awaiter(this, void 0, void 0, function* () {
- const xmlDoc = yield this.getXMLContent();
- const krpanoElement = xmlDoc.querySelector("krpano");
- while (this.syncTagStack.length) {
- const tag = this.syncTagStack.pop();
- const element = xmlDoc.createElement(tag.tagName);
- for (const key in tag.attribute) {
- element.setAttribute(key, tag.attribute[key]);
- }
- krpanoElement === null || krpanoElement === void 0 ? void 0 : krpanoElement.insertBefore(element, null);
- }
- return xmlDoc;
- });
- }
- getXMLContent() {
- return __awaiter(this, void 0, void 0, function* () {
- let contentText = "";
- const xml = this === null || this === void 0 ? void 0 : this.get("xml");
- const parser = new DOMParser();
- if (xml.content) {
- contentText = xml.content;
- }
- else if (xml.url) {
- contentText = yield fetch(xml.url).then((res) => res.text());
- }
- return parser.parseFromString(contentText, "text/xml");
- });
- }
- }
|