This commit is contained in:
zh
2025-09-18 20:48:30 +08:00
parent a0499b9b35
commit e7c4294d71
100 changed files with 45475 additions and 122 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

12014
src/renderer/public/Vue/vue.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,169 @@
.w-e-text-container {
position: relative;
height: 100%;
}
.w-e-text-container .w-e-progress {
position: absolute;
background-color: #1e88e5;
top: 0;
left: 0;
height: 1px;
}
.w-e-text-container .placeholder {
color: #d4d4d4;
position: absolute;
font-size: 11pt;
line-height: 22px;
left: 10px;
top: 10px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
z-index: -1;
}
.w-e-text {
padding: 0 10px;
overflow-y: auto;
}
.w-e-text p,
.w-e-text h1,
.w-e-text h2,
.w-e-text h3,
.w-e-text h4,
.w-e-text h5,
.w-e-text table,
.w-e-text pre {
margin: 10px 0;
line-height: 1.5;
}
.w-e-text ul,
.w-e-text ol {
margin: 10px 0 10px 20px;
}
.w-e-text blockquote {
display: block;
border-left: 8px solid #d0e5f2;
padding: 5px 10px;
margin: 10px 0;
line-height: 1.4;
font-size: 100%;
background-color: #f1f1f1;
}
.w-e-text code {
display: inline-block;
background-color: #f1f1f1;
border-radius: 3px;
padding: 3px 5px;
margin: 0 3px;
}
.w-e-text pre code {
display: block;
}
.w-e-text table {
border-top: 1px solid #ccc;
border-left: 1px solid #ccc;
}
.w-e-text table td,
.w-e-text table th {
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 3px 5px;
min-height: 30px;
height: 30px;
}
.w-e-text table th {
border-bottom: 2px solid #ccc;
text-align: center;
background-color: #f1f1f1;
}
.w-e-text:focus {
outline: none;
}
.w-e-text img {
cursor: pointer;
}
.w-e-text img:hover {
box-shadow: 0 0 5px #333;
}
.w-e-text .w-e-todo {
margin: 0 0 0 20px;
}
.w-e-text .w-e-todo li {
list-style: none;
font-size: 1em;
}
.w-e-text .w-e-todo li span:nth-child(1) {
position: relative;
left: -18px;
}
.w-e-text .w-e-todo li span:nth-child(1) input {
position: absolute;
margin-right: 3px;
}
.w-e-text .w-e-todo li span:nth-child(1) input[type="checkbox"] {
top: 50%;
margin-top: -6px;
}
.w-e-tooltip {
position: absolute;
display: flex;
color: #f1f1f1;
background-color: rgba(0, 0, 0, 0.75);
box-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.15);
border-radius: 4px;
padding: 4px 5px 6px;
justify-content: center;
align-items: center;
}
.w-e-tooltip-up::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border: 5px solid rgba(0, 0, 0, 0);
border-top-color: rgba(0, 0, 0, 0.73);
}
.w-e-tooltip-down::after {
content: "";
position: absolute;
bottom: 100%;
left: 50%;
margin-left: -5px;
border: 5px solid rgba(0, 0, 0, 0);
border-bottom-color: rgba(0, 0, 0, 0.73);
}
.w-e-tooltip-item-wrapper {
cursor: pointer;
font-size: 14px;
margin: 0 5px;
}
.w-e-tooltip-item-wrapper:hover {
color: #ccc;
text-decoration: underline;
}

View File

@ -0,0 +1,453 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./Vue/index.css">
<link rel="stylesheet" href="./Vue/w-e-text.css">
<script src="./Vue/vue.js"></script>
<script src="./Vue/index.js"></script>
<link href="./viewerJs/dist/viewer.css" rel="stylesheet">
<script src="./viewerJs/dist/viewer.js"></script>
<style>
body,
#info,
div {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#info {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
/* height: 100vh; background-color: rgba(255, 255, 255, 0.014); */
/*color: red;*/
}
.tabs-header {
display: flex;
background: #ccc;
user-select: none;
overflow: hidden;
overflow-x: scroll;
/* height: 41px; */
}
.tabs-header::-webkit-scrollbar {
height: 10px;
}
.tabs-header::-webkit-scrollbar-thumb {
background: #f0f0f0;
border-radius: 3px;
}
.tabs-header::-webkit-scrollbar-track {
background: #ccc;
border-radius: 3px;
}
.tabs-header>.item {
border-radius: 6px;
/* padding: 5px 15px; */
padding: 5px 0 5px 0;
margin: 5px 3px;
min-width: 80px;
text-align: center;
cursor: pointer;
}
.active {
background: #fff;
}
table {
border-collapse: collapse;
/* 合并边框 */
width: 100%;
/* 表格宽度 */
}
td {
text-align: center;
}
</style>
<style type="text/css">
#iframe1>[src] {
width: 100%;
height: 100%;
object-fit: contain;
}
</style>
</head>
<body>
<div id="info">
<!-- zhgeli -->
<div class="tabs-header">
<template v-for="(item,index) in tabsData">
<div :class="['item',index!=tabsData.length-1?'borderRight':'',index==activeIndex?'active':'',]"
@click="clickItem(item,index)">
{{ item.name }}
</div>
</template>
</div>
<!-- 全景图片 -->
<template v-if="activeItem.type === '全景图'">
<div style="flex: 9" id="vrBox"></div>
</template>
<template v-else-if="activeItem.name === '富文本'">
<div style="flex: 9" class="w-e-text" v-html="info.text"></div>
</template>
<template v-else-if="activeItem.type === '物资'">
<div v-if="activeItem.type === '物资'" style="flex: 9" class="w-e-text">
<table id="myTable" border="1">
<thead>
<tr>
<th>序号</th>
<th>名称</th>
<th>数量</th>
</tr>
</thead>
</table>
</div>
</template>
<template v-else>
<template v-if="isPicture">
<div style="flex: auto;">
<img v-if="isSvg" style="width: 100%;height: 100%" :src="activeItem.url" alt="">
<iframe v-else style="width: 100%;height: 100%" src="./showPicture.html" frameborder="0"
id="iframe1"></iframe>
</div>
</template>
<template v-else>
<div style="flex: auto;">
<iframe style="width: 100%;height: 100%" :src="activeItem.url" frameborder="0" id="iframe2">
</iframe>
</div>
</template>
</template>
</template>
</div>
</body>
<script type="text/javascript">
const fs = require('fs')
//调用子页面方法
function getIframe(data, str) {
var iframe = document.createElement("iframe");
iframe.src = "./vrHtml/index.html";
iframe.style.width = "100%"
iframe.style.height = "100%"
iframe.setAttribute('frameborder', 0)
iframe.onload = () => {
iframe.contentWindow.setIframe(data, str);
}
document.getElementById('vrBox').appendChild(iframe);
}
//获取img元素并且插入属性
function getImg(data) {
console.log('进入方法', data);
let iframe1 = document.getElementById('iframe1')
console.log(iframe1);
if (!iframe1) {
return
}
console.log('url', data);
iframe1.contentWindow.postMessage(data, '*')
console.log('urlurlurlurlurl', data);
// let frame = window.frames['iframeDialog']
iframe1.onload = () => {
iframe1.contentWindow.postMessage(data, '*')
}
}
//调用子组件关闭按钮
function closeImg() {
let iframe1 = document.getElementById('iframe1')
if (!iframe1) {
return
}
iframe1.contentWindow.close()
}
function closeVr() {
let parentElement = document.getElementById('vrBox')
if (!parentElement) {
return
}
removeAllChildren(parentElement);
}
function removeAllChildren(parentNode) {
while (parentNode.firstChild) {
parentNode.removeChild(parentNode.firstChild);
}
}
</script>
<script>
const ipcRenderer = require('electron').ipcRenderer
new Vue({
el: '#info',
data: function () {
return {
showRichText: '',
activeIndex: 0,
activeItem: {},
tabsData: [],
info: {
type: "",
text: "",
hrefs: "",
vrPath: '',
},
isPicture: false,
tbody: '',
}
},
computed: {
},
watch: {
activeItem: {
handler: function (val, oldVal) {
this.appendData(val)
console.log('document.getElementByIdmyObject', document.getElementById('myObject'));
},
deep: true
}
},
methods: {
// 填入数据
appendData(item) {
if (item.name === '物资') {
this.$nextTick(() => {
const table = document.querySelector('#myTable');
if (table) {
table.appendChild(this.tbody)
}
})
}
},
clickItem(item, i) {
if (this.tabsData.length < 1) {
console.log('只有一个选项,不允许切换');
return;
}
let setName = () => {
this.showRichText = item.name
this.activeIndex = i
this.activeItem = item
closeImg()
console.log('this.activeItem', this.activeItem);
this.renderImgView()
this.$nextTick(() => {
if (this.activeItem.name.indexOf('ISC-') > -1) {
if (!this.player) {
this.player = new window.JSPlugin({
szId: 'player',
szBasePath: "./sdk",
iMaxSplit: 1,
iCurrentSplit: 1,
openDebug: true,
oStyle: {
borderSelect: IS_MOVE_DEVICE ? '#000' : '#FFCC00',
}
})
}
//播放某一特定监控
let playURL = this.activeItem.previewUrl, index = this.player.currentWindowIndex, mode = 0//0=普通模式; 1=高级模式
this.player.JS_Play(playURL, { playURL, mode }, index).then(
() => { console.log('realplay success') },
e => { console.error(e) }
)
console.log("this.player", this.player);
}
})
closeVr()
// setIframe2()
}
if (['富文本', '全景图', '链接'].includes(this.activeItem.type)) {
setName()
this.$nextTick(() => {
getImg(this.activeItem.url)
})
return
}
setName()
},
renderImgView() {
console.log(this.activeItem.url);
let name
if (this.activeItem.url) {
name = this.activeItem.url.slice(this.activeItem.url.length - 3, this.activeItem.url.length)
}
console.log('node.detail.namenode.detail.namenode.detail.name', name);
this.isPicture = ['jpg', 'png', 'JPG', 'PNG', 'JPEG', 'jpeg', 'gif', 'webp', 'GIF', 'bmp'].includes(name)
console.log('this.isPicture', this.isPicture);
this.isSvg = (name === 'svg');
setTimeout(() => {
//我希望图片和全景都有时,他们各自渲染各自的
if (this.activeItem.type === '全景图') {
getIframe(this.activeItem.url, '')
} else {
getImg(this.activeItem.url)
}
// if (!Boolean(this.info.panorama.length)) {
// console.log('图片渲染', 1232132);
// getImg(this.activeItem.url)
// } else {
// getIframe(this.activeItem.url, '')
// }
}, 0)
},
},
mounted() {
window.ssssssssssssss = this.tabsData
let fs = require('fs')
console.log('fsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfsfs', fs);
ipcRenderer.on('data', (event, obj) => {
this.info = obj.info
console.log('ddddddddddddddddddddddddddd', this.info);
document.title = obj.source_name
let arr = this.info.hrefs
arr.forEach(item => {
console.log(fs.existsSync(item.url));
if (fs.existsSync(item.url)) {
let url = ""
if (item.url.startsWith("http"))
url = item.url
else {
//说明是本地的json在磁盘中存在的
if (item.url.includes(":")) {
url = obj.host + "/fileInfo/previewLocal?fileAbsolutePath=" + encodeURIComponent(item.url)
} else {
if (obj.host) {
let o = new URL(object.url, obj.host)
url = o.href
} else
url = item.url
}
}
item.url = url
} else {
if (!item.url.startsWith('http')) {
// item.url = this.info.env + "/" + item.url
item.url = obj.host + item.url
}
}
})
this.tabsData = arr
console.log('this.tabsData', this.tabsData);
let hasRichText = Boolean(this.info.text)
let hasVrPath = Boolean(this.info.vrPath)
let hasVr = Boolean(this.info.vr.length)
let hasGoods = Boolean(this.info.goods.length)
let hasISC = this.info.ISC && Boolean(this.info.ISC.length > 0)
if (hasRichText) {
this.tabsData.unshift({ name: "富文本", type: '富文本', href: this.info.text })
this.activeItem = this.tabsData[this.activeIndex]
}
// 当hasRichText为false将第一个选项设置为链接
if (!hasRichText && !hasVrPath && !hasVr && !hasGoods && !hasISC) {
this.activeItem = this.tabsData[this.activeIndex]
this.activeItem.type = '链接'
this.clickItem(this.activeItem, this.activeIndex)
}
if (this.info.type == "link" && this.tabsData.length > 0) {
this.activeIndex = hasRichText ? 0 : 0
this.activeItem = this.tabsData[this.activeIndex]
this.showRichText = ''
this.activeItem.type = '链接'
this.clickItem(this.activeItem, this.activeIndex)
}
// let jsonPath = obj.info.source_path.replace('.jpg', '.json')
// console.log(hasRichText, hasVrPath, fs.existsSync(jsonPath), this.tabsData);
let str = ""
// fetch(jsonPath)
// if (fs.existsSync(jsonPath)) {
// str = String(fs.readFileSync(jsonPath))
// }
/*else {
return
}*/
if (hasVrPath) {
this.tabsData.unshift({ name: "全景图", type: '全景图', href: this.info.vrPath })
this.$nextTick(() => {
getIframe(this.info.vrPath, str)
})
this.activeItem = this.tabsData[this.activeIndex]
}
if (hasISC) {
this.info.ISC.forEach(item => {
this.tabsData.push({ name: "ISC-" + item.name, cameraIndexCode: item.cameraIndexCode, status: item.status })
})
this.activeItem = this.tabsData[this.activeIndex]
}
if (hasGoods) {
this.tabsData.unshift({ name: "物资", type: '物资' })
// tbody.appendChild(row);
this.tbody = document.createElement('tbody')
this.info.goods.reverse().forEach((item, index) => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${index + 1}</td>
<td>${item.name}</td>
<td>${item.cnt}</td>
`;
this.tbody.appendChild(row);
});
this.activeItem = this.tabsData[this.activeIndex]
}
if (hasVr) {
this.info.vr.forEach(item => {
if (fs.existsSync(item.url)) {
let url = ""
if (item.url.startsWith("http"))
url = item.url
else {
//说明是本地的json在磁盘中存在的
if (item.url.includes(":")) {
url = obj.host + "/fileInfo/previewLocal?fileAbsolutePath=" + encodeURIComponent(item.url)
} else {
if (obj.host) {
let o = new URL(object.url, obj.host)
url = o.href
} else
url = item.url
}
}
item.url = url
} else {
if (!item.url.startsWith('http')) {
// item.url = this.info.env + "/" + item.url
item.url = obj.host + item.url
}
}
this.tabsData.unshift({ name: "全景图", type: '全景图', url: item.url })
})
this.activeItem = this.tabsData[this.activeIndex]
this.renderImgView()
}
})
},
})
</script>
<script>
</script>
</html>

View File

@ -0,0 +1,94 @@
<!DOCTYPE html>
<meta charset="UTF-8">
<html lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="./Vue/index.css">
<link rel="stylesheet" href="./Vue/w-e-text.css">
<script src="./Vue/vue.js"></script>
<script src="./Vue/index.js"></script>
<link href="./viewerJs/dist/viewer.css" rel="stylesheet">
<script src="./viewerJs/dist/viewer.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
html,
body {
width: 100%;
height: 100%;
}
img {
width: 100%;
height: 100%;
object-fit: contain;
}
</style>
</head>
<body>
<div id="pictureHtml" style="width: 100%;height: 100%;">
<img :src="url" id="imgShow" :alt="url" title="图片预览">
</div>
</body>
<script>
let viewer = null
function close() {
console.log('图片关闭被调用了', viewer);
viewer.destroy()
}
new Vue({
el: '#pictureHtml',
data() {
return {
url: '',
}
},
methods: {
setImgTools() {
console.log('重新渲染', 123);
let img = document.getElementById('imgShow')
if (!img) {
return
}
img.onload = () => {
viewer = new Viewer(img, {
toolbar: {
zoomIn: 4,
zoomOut: 4,
oneToOne: false,
reset: false,
prev: false,
play: {
show: 4,
size: 'large',
},
next: false,
rotateLeft: false,
rotateRight: false,
flipHorizontal: 4,
flipVertical: 4,
},
zoomRatio: 0.5
})
}
}
},
mounted() {
window.addEventListener('message', (data) => {
this.url = data.data
console.error('图片地址', this.url);
})
this.$nextTick(() => {
this.setImgTools()
})
}
})
</script>
</html>

Binary file not shown.

View File

@ -0,0 +1,539 @@
/*!
* PhotoSphereViewer 5.7.3
* @copyright 2014-2015 Jérémy Heleine
* @copyright 2024 Damien "Mistic" Sorel
* @licence MIT (https://opensource.org/licenses/MIT)
*/
/* src/styles/index.scss */
.psv-container {
--psv-core-loaded: true;
width: 100%;
height: 100%;
margin: 0;
padding: 0;
position: relative;
background: radial-gradient(#fff 0%, #fdfdfd 16%, #fbfbfb 33%, #f8f8f8 49%, #efefef 66%, #dfdfdf 82%, #bfbfbf 100%);
overflow: hidden;
}
.psv-container * {
box-sizing: content-box;
}
.psv-canvas-container {
position: absolute;
top: 0;
left: 0;
z-index: 0;
transition: opacity linear 100ms;
}
.psv-canvas {
display: block;
}
.psv-loader-container {
display: flex;
align-items: center;
justify-content: center;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 80;
}
.psv-loader {
--psv-loader-border: 3px;
--psv-loader-tickness: 10px;
position: relative;
display: flex;
justify-content: center;
align-items: center;
color: rgba(255, 255, 255, 0.7);
width: 150px;
height: 150px;
}
.psv-loader-canvas {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
color: rgba(61, 61, 61, 0.5);
z-index: -1;
}
.psv-loader-text {
font: 600 16px sans-serif;
}
.psv-navbar {
display: flex;
position: absolute;
z-index: 90;
bottom: -40px;
left: 0;
width: 100%;
height: 40px;
background: rgba(61, 61, 61, 0.5);
transition: bottom ease-in-out 0.1s;
font: 16px sans-serif;
cursor: default;
}
.psv-navbar--open {
bottom: 0;
}
.psv-navbar,
.psv-navbar * {
box-sizing: content-box;
}
.psv-button {
flex: 0 0 auto;
padding: 10px;
position: relative;
cursor: pointer;
height: 20px;
width: 20px;
background: transparent;
color: rgba(255, 255, 255, 0.7);
}
.psv-button--active {
background: rgba(255, 255, 255, 0.2);
}
.psv-button--disabled {
pointer-events: none;
opacity: 0.5;
}
.psv-button-svg {
width: 100%;
transform: scale(1);
transition: transform 200ms ease;
vertical-align: initial;
}
.psv-button:not(.psv-button--disabled):focus-visible {
outline: 2px solid #007cff;
outline-offset: -2px;
}
.psv-container:not(.psv--is-touch) .psv-button--hover-scale:not(.psv-button--disabled):hover .psv-button-svg {
transform: scale(1.2);
}
.psv-move-button + .psv-move-button {
margin-left: -10px;
}
.psv-custom-button {
width: auto;
min-width: 20px;
}
.psv-custom-button--no-padding {
padding: 0;
height: 100%;
}
.psv-caption {
flex: 1 1 100%;
color: rgba(255, 255, 255, 0.7);
overflow: hidden;
text-align: center;
cursor: unset;
padding: unset;
height: unset;
width: unset;
}
.psv-caption-content {
display: inline-block;
padding: 10px;
white-space: nowrap;
}
.psv-zoom-range.psv-button {
width: 80px;
height: 1px;
margin: 10px 0;
padding: 9.5px 0;
max-width: 600px;
}
.psv-zoom-range-line {
position: relative;
width: 80px;
height: 1px;
background: rgba(255, 255, 255, 0.7);
transition: all 0.3s ease;
}
.psv-zoom-range-handle {
position: absolute;
border-radius: 50%;
top: -3px;
width: 7px;
height: 7px;
background: rgba(255, 255, 255, 0.7);
transform: scale(1);
transition: transform 0.3s ease;
}
.psv-zoom-range:not(.psv-button--disabled):hover .psv-zoom-range-line {
box-shadow: 0 0 2px rgba(255, 255, 255, 0.7);
}
.psv-zoom-range:not(.psv-button--disabled):hover .psv-zoom-range-handle {
transform: scale(1.3);
}
.psv-notification {
position: absolute;
z-index: 100;
bottom: -40px;
display: flex;
justify-content: center;
box-sizing: border-box;
width: 100%;
padding: 0 2em;
opacity: 0;
transition-property: opacity, bottom;
transition-timing-function: ease-in-out;
transition-duration: 200ms;
}
.psv-notification-content {
max-width: 50em;
background: rgba(61, 61, 61, 0.8);
border-radius: 4px;
padding: 0.5em 1em;
font: 14px sans-serif;
color: rgb(255, 255, 255);
}
.psv-notification--visible {
opacity: 100;
bottom: 80px;
}
.psv-overlay {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: absolute;
z-index: 110;
inset: 0;
background: radial-gradient(#fff 0%, #fdfdfd 16%, #fbfbfb 33%, #f8f8f8 49%, #efefef 66%, #dfdfdf 82%, #bfbfbf 100%);
opacity: 0.8;
cursor: default;
}
.psv-overlay-image {
width: 100%;
text-align: center;
}
.psv-overlay-image svg {
width: 50%;
}
@media (orientation: landscape) {
.psv-overlay-image svg {
width: 33%;
}
}
.psv-overlay-title {
color: black;
margin-top: 1em;
font: 30px sans-serif;
text-align: center;
}
.psv-overlay-text {
color: rgba(0, 0, 0, 0.8);
font: 20px sans-serif;
opacity: 0.8;
text-align: center;
}
.psv-panel {
position: absolute;
z-index: 90;
right: 0;
height: 100%;
width: 400px;
max-width: calc(100% - 9px);
background: rgba(10, 10, 10, 0.7);
transform: translate3d(100%, 0, 0);
opacity: 0;
transition-property: opacity, transform;
transition-timing-function: ease-in-out;
transition-duration: 100ms;
cursor: default;
margin-left: 9px;
}
.psv--has-navbar .psv-panel {
height: calc(100% - 40px);
}
.psv-panel-close-button {
display: none;
position: absolute;
top: -1px;
right: 0;
width: 19.2px;
height: 19.2px;
padding: 6.4px;
background: transparent;
color: #fff;
transition: background 300ms ease-in-out;
cursor: pointer;
}
.psv-panel-close-button svg {
transition: transform 300ms ease-in-out;
}
.psv-panel-close-button:hover {
background: rgba(0, 0, 0, 0.9);
}
.psv-panel-close-button:hover svg {
transform: scale(-1);
}
.psv-panel-resizer {
display: none;
position: absolute;
top: 0;
left: -9px;
width: 9px;
height: 100%;
background-color: rgba(0, 0, 0, 0.9);
cursor: col-resize;
}
.psv-panel-resizer::before {
content: "";
position: absolute;
top: 50%;
left: 1px;
margin-top: -14.5px;
width: 1px;
height: 1px;
box-shadow:
1px 0 #fff,
3px 0px #fff,
5px 0px #fff,
1px 2px #fff,
3px 2px #fff,
5px 2px #fff,
1px 4px #fff,
3px 4px #fff,
5px 4px #fff,
1px 6px #fff,
3px 6px #fff,
5px 6px #fff,
1px 8px #fff,
3px 8px #fff,
5px 8px #fff,
1px 10px #fff,
3px 10px #fff,
5px 10px #fff,
1px 12px #fff,
3px 12px #fff,
5px 12px #fff,
1px 14px #fff,
3px 14px #fff,
5px 14px #fff,
1px 16px #fff,
3px 16px #fff,
5px 16px #fff,
1px 18px #fff,
3px 18px #fff,
5px 18px #fff,
1px 20px #fff,
3px 20px #fff,
5px 20px #fff,
1px 22px #fff,
3px 22px #fff,
5px 22px #fff,
1px 24px #fff,
3px 24px #fff,
5px 24px #fff,
1px 26px #fff,
3px 26px #fff,
5px 26px #fff,
1px 28px #fff,
3px 28px #fff,
5px 28px #fff;
background: transparent;
}
.psv-panel-content {
width: 100%;
height: 100%;
box-sizing: border-box;
color: rgb(220, 220, 220);
font: 16px sans-serif;
overflow: auto;
}
.psv-panel-content:not(.psv-panel-content--no-margin) {
padding: 1em;
}
.psv-panel-content--no-interaction {
user-select: none;
pointer-events: none;
}
.psv-panel--open {
transform: translate3d(0, 0, 0);
opacity: 1;
transition-duration: 0.2s;
}
.psv-panel--open .psv-panel-close-button,
.psv-panel--open .psv-panel-resizer {
display: block;
}
@media screen and (max-width: 400px) {
.psv-panel {
width: 100% !important;
max-width: none;
}
.psv-panel-resizer {
display: none !important;
}
}
.psv-panel-menu {
height: 100%;
display: flex;
flex-direction: column;
}
.psv-panel-menu-title {
flex: none;
display: flex;
align-items: center;
font: 24px sans-serif;
margin: 24px 12px;
}
.psv-panel-menu-title svg {
width: 24px;
height: 24px;
margin-right: 12px;
}
.psv-panel-menu-list {
flex: 1;
list-style: none;
margin: 0;
padding: 0;
overflow-x: hidden;
}
.psv-panel-menu-item {
min-height: 1.5em;
padding: 0.5em 1em;
cursor: pointer;
display: flex;
align-items: center;
justify-content: flex-start;
transition: background 0.1s ease-in-out;
}
.psv-panel-menu-item--active {
outline: 1px solid currentcolor;
outline-offset: -1px;
}
.psv-panel-menu-item-icon {
flex: none;
height: 1.5em;
width: 1.5em;
margin-right: 0.5em;
}
.psv-panel-menu-item-icon img {
max-width: 100%;
max-height: 100%;
}
.psv-panel-menu-item-icon svg {
width: 100%;
height: 100%;
}
.psv-panel-menu-item:focus-visible {
outline: 2px solid #007cff;
outline-offset: -2px;
}
.psv-panel-menu--stripped .psv-panel-menu-item:hover {
background: rgba(255, 255, 255, 0.2);
}
.psv-panel-menu--stripped .psv-panel-menu-item:nth-child(odd),
.psv-panel-menu--stripped .psv-panel-menu-item:nth-child(odd)::before {
background: rgba(255, 255, 255, 0.1);
}
.psv-panel-menu--stripped .psv-panel-menu-item:nth-child(even),
.psv-panel-menu--stripped .psv-panel-menu-item:nth-child(even)::before {
background: transparent;
}
.psv-container:not(.psv--is-touch) .psv-panel-menu-item:hover {
background: rgba(255, 255, 255, 0.2);
}
.psv-tooltip {
position: absolute;
z-index: 50;
box-sizing: border-box;
max-width: 200px;
background: rgba(61, 61, 61, 0.8);
border-radius: 4px;
opacity: 0;
transition-property: opacity, transform;
transition-timing-function: ease-in-out;
transition-duration: 100ms;
cursor: default;
}
.psv-tooltip-content {
color: rgb(255, 255, 255);
font: 14px sans-serif;
text-shadow: 0 1px #000;
padding: 0.5em 1em;
}
.psv-tooltip-arrow {
position: absolute;
height: 0;
width: 0;
border: 7px solid transparent;
}
.psv-tooltip--top-left,
.psv-tooltip--top-center,
.psv-tooltip--top-right {
transform: translate3d(0, 5px, 0);
}
.psv-tooltip--top-left .psv-tooltip-arrow,
.psv-tooltip--top-center .psv-tooltip-arrow,
.psv-tooltip--top-right .psv-tooltip-arrow {
border-top-color: rgba(61, 61, 61, 0.8);
}
.psv-tooltip--bottom-left,
.psv-tooltip--bottom-center,
.psv-tooltip--bottom-right {
transform: translate3d(0, -5px, 0);
}
.psv-tooltip--bottom-left .psv-tooltip-arrow,
.psv-tooltip--bottom-center .psv-tooltip-arrow,
.psv-tooltip--bottom-right .psv-tooltip-arrow {
border-bottom-color: rgba(61, 61, 61, 0.8);
}
.psv-tooltip--left-top,
.psv-tooltip--center-left,
.psv-tooltip--left-bottom {
transform: translate3d(5px, 0, 0);
}
.psv-tooltip--left-top .psv-tooltip-arrow,
.psv-tooltip--center-left .psv-tooltip-arrow,
.psv-tooltip--left-bottom .psv-tooltip-arrow {
border-left-color: rgba(61, 61, 61, 0.8);
}
.psv-tooltip--right-top,
.psv-tooltip--center-right,
.psv-tooltip--right-bottom {
transform: translate3d(-5px, 0, 0);
}
.psv-tooltip--right-top .psv-tooltip-arrow,
.psv-tooltip--center-right .psv-tooltip-arrow,
.psv-tooltip--right-bottom .psv-tooltip-arrow {
border-right-color: rgba(61, 61, 61, 0.8);
}
.psv-tooltip--left-top,
.psv-tooltip--top-left {
box-shadow: -3px -3px 0 rgba(90, 90, 90, 0.7);
}
.psv-tooltip--top-center {
box-shadow: 0 -3px 0 rgba(90, 90, 90, 0.7);
}
.psv-tooltip--right-top,
.psv-tooltip--top-right {
box-shadow: 3px -3px 0 rgba(90, 90, 90, 0.7);
}
.psv-tooltip--left-bottom,
.psv-tooltip--bottom-left {
box-shadow: -3px 3px 0 rgba(90, 90, 90, 0.7);
}
.psv-tooltip--bottom-center {
box-shadow: 0 3px 0 rgba(90, 90, 90, 0.7);
}
.psv-tooltip--right-bottom,
.psv-tooltip--bottom-right {
box-shadow: 3px 3px 0 rgba(90, 90, 90, 0.7);
}
.psv-tooltip--center-left {
box-shadow: -3px 0 0 rgba(90, 90, 90, 0.7);
}
.psv-tooltip--center-right {
box-shadow: 3px 0 0 rgba(90, 90, 90, 0.7);
}
.psv-tooltip--visible {
transform: translate3d(0, 0, 0);
opacity: 1;
}
/*# sourceMappingURL=index.css.map */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,48 @@
/*!
* PhotoSphereViewer.MarkersPlugin 5.7.3
* @copyright 2024 Damien "Mistic" Sorel
* @licence MIT (https://opensource.org/licenses/MIT)
*/
/* src/style.scss */
.psv-container {
--psv-markers-plugin-loaded: true;
}
.psv-markers {
user-select: none;
position: absolute;
z-index: 10;
width: 100%;
height: 100%;
}
.psv-markers-svg-container {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
}
.psv-marker {
display: none;
}
.psv-marker--normal {
position: absolute;
top: 0;
left: 0;
z-index: 30;
overflow: visible;
background-size: contain;
background-repeat: no-repeat;
}
.psv-marker--transparent {
display: block;
opacity: 0;
}
.psv-marker--visible {
display: block;
}
.psv-marker--has-tooltip,
.psv-marker--has-content {
cursor: pointer;
}
/*# sourceMappingURL=index.css.map */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,115 @@
<!DOCTYPE html>
<html lang="en">
<!-- 传整个数组节点 -->
<head>
<!-- for optimal display on high DPI devices -->
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="@photo-sphere-viewer/core/index.css" />
<link rel="stylesheet" href="@photo-sphere-viewer/markers-plugin/index.css" />
<script src="./three.min.js"></script>
<script type="module">
</script>
<script type="text/javascript">
function setIframe(data, str) {
load(data, str)
}
</script>
<!-- <script type="module">
import * as THREE from './three.min.js';
window.THREE = THREE;
console.log(THREE)
</script> -->
<script src="@photo-sphere-viewer/core/index.js"></script>
<script src="@photo-sphere-viewer/markers-plugin/index.js"></script>
<style>
* {
margin: 0;
}
</style>
</head>
<!-- the viewer container must have a defined size -->
<div id="viewer" style="width: 100vw; height: 100vh;"></div>
<script>
function load(path, str) {
let url = new URL(path)
let options = {}
if (str.length) {
let obj = JSON.parse(str)
options.markers = initMarker(obj.neighbors)
}
const viewer = new PhotoSphereViewer.Viewer({
container: document.querySelector('#viewer'),
// panorama: "http://localhost:8890/yjearth4.0/api/v1/vr/97ef82188bc7e2d074502c5730e2b3ec.jpg",
panorama: path,
plugins: [
[PhotoSphereViewer.MarkersPlugin, options],
],
});
const markersPlugin = viewer.getPlugin(PhotoSphereViewer.MarkersPlugin);
markersPlugin.addEventListener('select-marker', ({ marker }) => {
let str = marker.config.myPath
window.marker = marker
let imgUrl = `${url.origin}/yjearth4.0/api/v1/vr/${str}.jpg`
let json = `${url.origin}/yjearth4.0/api/v1/vr/${str}.json`
let markers = undefined
fetch(json).then(res => {
if (res.ok) {
res.json().then(json => {
markers = initMarker(json.neighbors)
add(imgUrl, markers)
})
} else {
add(imgUrl)
}
})
});
function add(imgUrl, markers) {
viewer.setPanorama(imgUrl, {})
viewer.animate({
zoom: 100,
speed: "-2rpm",
}).then(() => {
markersPlugin.clearMarkers()
if (markers) {
markersPlugin.setMarkers(markers)
}
})
}
}
function initMarker(arr) {
let markers = []
for (let i = 0; i < arr.length; i++) {
const element = arr[i];
console.log(Math.atan2(Math.sin(element.position.lng), Math.cos(element.position.lat)))
let obji = {
id: 'image' + i,
image: './定位.png',
tooltip: element.name,
position: { yaw: element.degree + 'deg', pitch: '1deg' },
size: { width: 32, height: 32 },
myPath: element.node_id,
data: {
generated: true,
},
}
markers.push(obji)
}
return markers
}
</script>
<body>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB