山海鲸可视化

内外网页通信

集成山海鲸页面时,外部网页可以通过发送 postmessage 的形式来进行通信,同时也支持直接通过 postmessage 动态的修改属性值和触发交互。

1.同二开代码通信

最通用也是最灵活的方式就是外部发送 postmessage 给内部的二开代码,再有二开代码来决定下一步需要做什么操作,同时二开代码在收到 message 之后也可以向外部发送信息。
在前面文章集成了 iFrame 之后,我们在外部网页中再添加两个按钮,分别是白天和晚上。
我们看一下实例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<html>
<style>
html {
background-color: cadetblue;
}
.controlbar {
display: flex;
}
.controlbar button {
width: 200px;
height: 100px;
margin-left: 50px;
}
</style>
<body>
<iframe
id="shanhai-frame"
width="1600"
height="900"
src="http://192.168.31.136:5057/uo0cu7q95zuq/"
frameborder="0"
allowfullscreen="true"
></iframe>
<div class="controlbar">
<button onclick="setDaytime(12)">切换白天</button
><button onclick="setDaytime(0)">切换晚上</button>
</div>
</body>

<script>
let iframeLoaded = false;
let shanhaiFrame = document.getElementById("shanhai-frame");
shanhaiFrame.addEventListener("load", function (e) {
iframeLoaded = true;
});
function setDaytime(value) {
if (iframeLoaded) {
const postMessageData = {
action: "customMessage", //动作名称
data: {
daytime: value,
},
};
shanhaiFrame.contentWindow.postMessage(postMessageData, "*");
}
}
</script>
</html>

在山海鲸中,所有的组件的二开都会收到的这个 message,这里因为我们要修改鲸孪生场景上的当前时间,因此我们在鲸孪生场景上挂载以下二开代码:
image.png
二开代码内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export class SampleExtension {
async init() {
//监听postMessage事件
this.element.addEventListener("message", (ev) => {
const { data, origin, source } = ev;
if (data.action == "customMessage") {
const customData = data.data;
const daytime = customData.daytime;
this.element.setOption(["daytime"], daytime);
// 可以通过两种形式回发信息
// source.postMessage("Got it");
// window.parent.postMessage("Got it", "*");
}
});
}
}

我们也可以在收到了 message 之后,通过 source 对象向外部发送 postmessage,也可以直接通过 window.parent 来发送。注意这两种形式的区别在于 source 必须收到 message 之后才能发送,window.parent 可以主动发送,我们修改一下代码,向网页发送一个回传消息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
export class SampleExtension {
async init() {
//监听postMessage事件
this.element.addEventListener("message", (ev) => {
const { data, origin, source } = ev;
if (data.action == "customMessage") {
const customData = data.data;
const daytime = customData.daytime;
this.element.setOption(["daytime"], daytime);
// 可以通过两种形式回发信息
// source.postMessage("Got it");
window.parent.postMessage("Got it", "*");
}
});
}
}

在网页的代码中加上收消息的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<html>
<style>
html {
background-color: cadetblue;
}
.controlbar {
display: flex;
}
.controlbar button {
width: 200px;
height: 100px;
margin-left: 50px;
}
</style>
<body>
<iframe
id="shanhai-frame"
width="1600"
height="900"
src="http://192.168.31.136:5057/uo0cu7q95zuq/"
frameborder="0"
allowfullscreen="true"
></iframe>
<div class="controlbar">
<button onclick="setDaytime(12)">切换白天</button
><button onclick="setDaytime(0)">切换晚上</button>
</div>
</body>

<script>
let iframeLoaded = false;
let shanhaiFrame = document.getElementById("shanhai-frame");
shanhaiFrame.addEventListener("load", function (e) {
iframeLoaded = true;
});
// 收取来自二开代码的信息
window.addEventListener("message", (ev) => {
const { data } = ev;
console.log("收到信息:", data);
});
function setDaytime(value) {
if (iframeLoaded) {
const postMessageData = {
action: "customMessage", //动作名称
data: {
daytime: value,
},
};
shanhaiFrame.contentWindow.postMessage(postMessageData, "*");
}
}
</script>
</html>

2.动态修改组件设置

我们修改一下上一节代码的结构,不使用二开代码,直接修改设置项,具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<html>
<style>
html {
background-color: cadetblue;
}
.controlbar {
display: flex;
}
.controlbar button {
width: 200px;
height: 100px;
margin-left: 50px;
}
</style>
<body>
<iframe
id="shanhai-frame"
width="1600"
height="900"
src="http://192.168.31.136:5057/ap1guovmpedt/"
frameborder="0"
allowfullscreen="true"
></iframe>
<div class="controlbar">
<button onclick="setDaytime(12)">切换白天</button
><button onclick="setDaytime(0)">切换晚上</button>
</div>
</body>

<script>
let iframeLoaded = false;
let shanhaiFrame = document.getElementById("shanhai-frame");
shanhaiFrame.addEventListener("load", function (e) {
iframeLoaded = true;
});
function setDaytime(value) {
if (iframeLoaded) {
const postMessageData = {
action: "setOption", //动作名称
data: {
elementUID: ["c9ozws2ktrjk", "9lj7ryar3jjz", "scene"], //目标元素
optionPath: ["daytime"], //目标属性
optionValue: value, //目标值
},
};
shanhaiFrame.contentWindow.postMessage(postMessageData, "*");
}
}
</script>
</html>

注意这段代码主要就是向按了按钮之后向山海鲸的页面中发送 postmessage,其中 elementUID 是我们需要修改的目标元素的 UID,我们可以通过点击对应的元素,然后再右侧面板中点击更多选项卡,可以看到 elementUID:
image.png
另外 optionPath 则是和其他二开一样,找到对应的属性,鼠标移动上去后,点击三个点,选择菜单中的调用代码示例:
image.png
弹出框中复制 getOption 或者 setOption 的第一个参数即可:
image.png
最终网页效果如下:
image.png
点击了切换晚上后得到以下结果:
image.png

3.动态触发交互

此功能暂未开放。