時(shí)間:2023-07-19 23:36:02 | 來源:網(wǎng)站運(yùn)營
時(shí)間:2023-07-19 23:36:02 來源:網(wǎng)站運(yùn)營
思源筆記折騰記錄-整一個(gè)全景圖瀏覽器-簡單的全景圖渲染:let fs = require('fs')let path = require('path')export let vite掛件目錄 = window.siyuan.config.system.workspaceDir +'/data/viteWidgets'export function 讀取掛件列表(){ let 掛件列表 =[] let 路徑列表= require('fs').readdirSync(vite掛件目錄) 路徑列表.forEach( 路徑名=>{ //如果目錄下有vite.config.js if(fs.existsSync(path.join(vite掛件目錄,路徑名,'vite.config.js'))){ 掛件列表.push({ name:路徑名, path:path.join(vite掛件目錄,路徑名) }) } } ) return 掛件列表}
import noobApi from '../noobApi/index.js'import { 讀取掛件列表 } from './util/file.js'import { 獲取可用端口號 } from './util/port.js'if (window.require) { const path = require('path') const vite = require('vite') let vite服務(wù)注冊表 = {} 讀取掛件列表().forEach( 掛件屬性 => { 創(chuàng)建vite服務(wù)(掛件屬性.path) } ) function 創(chuàng)建vite服務(wù)(文件夾路徑) { return new Promise(async (resolve, reject) => { let vite配置文件路徑 = path.join(文件夾路徑, 'vite.config.js') if (!vite服務(wù)注冊表.文件夾路徑) { let server = await vite.createServer({ configFile: vite配置文件路徑, root: 文件夾路徑, }) !vite服務(wù)注冊表[文件夾路徑]?vite服務(wù)注冊表[文件夾路徑]={}:null vite服務(wù)注冊表[文件夾路徑]['server'] = server let port if (server.config.server.port) { port = await 獲取可用端口號(server.config.server.port) } else { port =await 獲取可用端口號(6806) } await server.listen(port,'127.0.0.1').then( s => { console.log(文件夾路徑,'的開發(fā)服務(wù)在:',port,'上啟用') vite服務(wù)注冊表[文件夾路徑]['port'] = port } ) resolve(server) } }) }}
獲取可用端口號的實(shí)現(xiàn)其實(shí)就是嘗試能不能監(jiān)聽這個(gè)端口,如果不能就試個(gè)新的:export async function 獲取可用端口號(端口號){ return new Promise((resolve, reject) => { let http = require('http') let 測試服務(wù) = http.createServer() let 可用端口號 = 端口號||3000 測試服務(wù).on( 'listening',()=>{ console.log(端口號) 測試服務(wù).close(()=>{ resolve(可用端口號) }) } ) 測試服務(wù).on( 'error',async(error)=>{ console.log(error) if(error.code==='EADDRINUSE'){ resolve(await 獲取可用端口號(可用端口號+1)) } else{ reject(error) } } ) 測試服務(wù).listen(端口號) }) }
npm i photo sphere viewer --registry=https://registry.npmmirror.com
import { Viewer } from 'photo-sphere-viewer';//這里是引入了css,vite里面你這么干跟在html里面引入差不多import 'photo-sphere-viewer/dist/photo-sphere-viewer.css'const viewer = new Viewer({ container: document.querySelector('#viewer'), //這個(gè)是我之前上傳到工作空間里的一張全景圖 panorama: 'assets/11111D5_全景圖 1_20221211_061304-20221211182953-7i0dt0q.jpg',});
就像這樣:PhotoSphereViewer.GalleryPlugin
這里我們約定文件名為:全景圖-<項(xiàng)目名>-<空間名>-<id>.jpg的附件文件就是某一個(gè)系列的全景圖。select * from assetswhere name like '全景圖-${項(xiàng)目名}-%'
然后我們來實(shí)驗(yàn)一下:import { Viewer } from 'photo-sphere-viewer';import {GalleryPlugin} from 'photo-sphere-viewer/dist/plugins/gallery.js'import 核心api from 'http://127.0.0.1:6806/snippets/noobApi/util/kernelApi.js'import 'photo-sphere-viewer/dist/photo-sphere-viewer.css'import 'photo-sphere-viewer/dist/plugins/gallery.css'import { 獲取地址參數(shù) } from '../../whiteBoard/src/data';let {project} =獲取地址參數(shù)()console.log(project)let sql =`select * from assets where name like '全景圖-${project}-%'`let 全景圖列表 = await 核心api.sql({stmt:sql})console.log(全景圖列表)全景圖列表.forEach( item=>{ item.panorama=item.path item.thumbnail =item.path let 空間名 = item.name.split('-')[2] item.options ={ caption: 空間名, } })console.log(Viewer,GalleryPlugin)const viewer = new Viewer({ container: document.querySelector('#viewer'), panorama: 全景圖列表[0].path, plugins: [ [GalleryPlugin, { visibleOnLoad: true, }], ],});const gallery = viewer.getPlugin(GalleryPlugin);gallery.setItems(全景圖列表)
?function 創(chuàng)建vite服務(wù)(文件夾路徑) { return new Promise(async (resolve, reject) => { let vite配置文件路徑 = path.join(文件夾路徑, 'vite.config.js') if (!vite服務(wù)注冊表.文件夾路徑) { let vite中間件 = await vite.createServer({ configFile: vite配置文件路徑, root: 文件夾路徑, server: { middlewareMode: "html" } }) const app = express() !vite服務(wù)注冊表[文件夾路徑] ? vite服務(wù)注冊表[文件夾路徑] = {} : null vite服務(wù)注冊表[文件夾路徑]['server'] = app let port = vite中間件.config.server.port || 6807 port = await 獲取可用端口號(port) let server = await app.listen(port, '127.0.0.1', async () => { vite服務(wù)注冊表[文件夾路徑]['port'] = port vite服務(wù)注冊表[文件夾路徑]['server'] = server vite服務(wù)注冊表[文件夾路徑]['app'] = app vite服務(wù)注冊表[文件夾路徑]['vite'] = vite中間件 console.log(文件夾路徑, '的開發(fā)服務(wù)在:', 'http://127.0.0.1:' + port, '上啟用') if (require('fs').existsSync(文件夾路徑 + '/backend/index.js')) { //因?yàn)槟承┑疤鄣脑?,這里只能用require let router = require(文件夾路徑 +'/backend/index.js') //主意router不要妨礙vite的工作,也就是別占了vite的坑 app.use(router) app.use(vite中間件.middlewares) } })/*.then( s => { let {address,port} = server.httpServer.address() console.log(文件夾路徑,'的開發(fā)服務(wù)在:','http://'+address+':'+port,'上啟用') vite服務(wù)注冊表[文件夾路徑]['port'] = port console.log(server) } )*/ resolve(server) } }) }
這樣之后,隨便試一下,就把文件存在data/widgetsData?里面吧。const express = require('express')let router = express.Router()const fs = require('fs')const path = require('path')let 數(shù)據(jù)路徑 = path.join(window.siyuan.config.system.workspaceDir,'data','widgetsData','sphereViewer')if(fs.existsSync(數(shù)據(jù)路徑)){ //為了避免跟思源的接口重合,掛件后端的接口全都加上widget前綴好了 router.use('/widgetData',express.static(數(shù)據(jù)路徑)) router.use('/widgetApi/projects/getAll',(req,res)=>{ res.json(fs.readdirSync(數(shù)據(jù)路徑) })}//上面已經(jīng)做了自動導(dǎo)入,回自動把這個(gè)接口混入vite的開發(fā)服務(wù)器當(dāng)中module.exports=router
這樣之后,往這個(gè)文件夾里面放一點(diǎn)文件:import { 核心api } from "../../../whiteBoard/src/data"export class sql全景圖適配器{ 獲取項(xiàng)目列表(){ } async 獲取全景圖列表(項(xiàng)目名){ let sql =`select * from assets where name like '全景圖-${項(xiàng)目名}-%'` let 全景圖列表 = await 核心api.sql({stmt:sql}) 全景圖列表.forEach( item=>{ item.panorama=item.path item.thumbnail =item.path let 空間名 = item.name.split('-')[2] item.options ={ caption: 空間名, } } ) return 全景圖列表 }}import { Viewer } from 'photo-sphere-viewer';import {GalleryPlugin} from 'photo-sphere-viewer/dist/plugins/gallery.js'import 'photo-sphere-viewer/dist/photo-sphere-viewer.css'import 'photo-sphere-viewer/dist/plugins/gallery.css'import { 獲取地址參數(shù) } from '../../whiteBoard/src/data';import {sql全景圖適配器} from "./adapters/sql.js"let {project} =獲取地址參數(shù)()console.log(project)let 當(dāng)前適配器 = new sql全景圖適配器()let 全景圖列表= await 當(dāng)前適配器.獲取全景圖列表(project) const viewer = new Viewer({ container: document.querySelector('#viewer'), panorama: 全景圖列表[0].path, plugins: [ [GalleryPlugin, { visibleOnLoad: true, }], ],});const gallery = viewer.getPlugin(GalleryPlugin);gallery.setItems(全景圖列表)
這個(gè)時(shí)候訪問127.0.0.1:6809/?project=云park,應(yīng)該可以看到跟之前一樣的結(jié)果。export class sql全景圖適配器{ 獲取項(xiàng)目列表(){ } async 獲取全景圖列表(項(xiàng)目名){ let res = await fetch('widgetApi/projects/getScenesByName',{ method:"POST", body:{ name:項(xiàng)目名 } }) let 全景圖列表 = await res.json() return 全景圖列表 }}
?router.post('widgetApi/projects/getScenesByName',(req,res)=>{ let {name} = req.body let 場景列表 = [] let 項(xiàng)目文件列表 = fs.readdirSync(path.join(數(shù)據(jù)路徑,name)) 項(xiàng)目文件列表.forEach( 路徑名=>{ let 縮略圖路徑 if( fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'thumbnail.jpg'))){ 縮略圖路徑 = path.join('/widgetData',name,路徑名,'thumbnail.jpg').replace(////g,'/') }else if( fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'_f.jpg')) ){ 縮略圖路徑=path.join('/widgetData',name,路徑名,'_f.jpg').replace(////g,'/') }else if( fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'sphere.jpg')) ){ 縮略圖路徑=path.join('/widgetData',name,路徑名,'sphere.jpg').replace(////g,'/') } if(fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'_b.jpg'))){ 場景列表.push( { id:路徑名, panorama:{ left: path.join('/widgetData',name,路徑名,'_r.jpg').replace(////g,'/'), front: path.join('/widgetData',name,路徑名,'_b.jpg').replace(////g,'/'), right: path.join('/widgetData',name,路徑名,'_l.jpg').replace(////g,'/'), back: path.join('/widgetData',name,路徑名,'_f.jpg').replace(////g,'/'), top: path.join('/widgetData',name,路徑名,'_u.jpg').replace(////g,'/'), bottom: path.join('/widgetData',name,路徑名,'_d.jpg').replace(////g,'/'), }, thumbnail:縮略圖路徑, options:{ caption:name, } } ) } else if(fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'sphere.jpg'))){ 場景列表.push( { id:路徑名, panorama:path.join('/widgetData',name,路徑名,'sphere.jpg').replace(////g,'/'), options:{ caption:name, }, thumbnail:縮略圖路徑, } ) } } ) res.json(場景列表) })
看起來應(yīng)該跟上面的這個(gè)差不多對吧,就是識別文件夾里的文件,然后匹配下路徑然后返回。panorama:{ left: path.join('/widgetData',name,路徑名,'_r.jpg').replace(////g,'/'), front: path.join('/widgetData',name,路徑名,'_b.jpg').replace(////g,'/'), right: path.join('/widgetData',name,路徑名,'_l.jpg').replace(////g,'/'), back: path.join('/widgetData',name,路徑名,'_f.jpg').replace(////g,'/'), top: path.join('/widgetData',name,路徑名,'_u.jpg').replace(////g,'/'), bottom: path.join('/widgetData',name,路徑名,'_d.jpg').replace(////g,'/'),},
因?yàn)殇秩酒鹘o出的六面全景圖一般是按照“人在方盒子里面”來適配六個(gè)面的,而PhotoSphereViewer?是按照“人在方盒子外面”來讀取的,所以讀取文件的時(shí)候,除了上下不用反之外,其他前后左右都要反一下~~~import {后端適配器} from './adapters/internal.js'let {project} =獲取地址參數(shù)()console.log(project)let 當(dāng)前適配器 = new 后端適配器()let 全景圖列表= await 當(dāng)前適配器.獲取全景圖列表(project) const viewer = new Viewer({ container: document.querySelector('#viewer'), panorama: 全景圖列表[0].path, plugins: [ [GalleryPlugin, { visibleOnLoad: true, }], ],});const gallery = viewer.getPlugin(GalleryPlugin);gallery.setItems(全景圖列表)
然后它就報(bào)錯(cuò)了:const bodyParser = require('body-parser')router.post('/widgetApi/projects/getScenesByName', (req,res,next)=>{ //強(qiáng)制按json解析,這樣前端就不用設(shè)置content-type了 req.headers['content-type']='application/json' //記得調(diào)用next() next() }, bodyParser.json(), let {name} = req.body let 場景列表 = [] let 項(xiàng)目文件列表 = fs.readdirSync(path.join(數(shù)據(jù)路徑,name)) 項(xiàng)目文件列表.forEach( 路徑名=>{ let 縮略圖路徑 if( fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'thumbnail.jpg'))){ 縮略圖路徑 = path.join('/widgetData',name,路徑名,'thumbnail.jpg').replace(////g,'/') }else if( fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'_f.jpg')) ){ 縮略圖路徑=path.join('/widgetData',name,路徑名,'_f.jpg').replace(////g,'/') }else if( fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'sphere.jpg')) ){ 縮略圖路徑=path.join('/widgetData',name,路徑名,'sphere.jpg').replace(////g,'/') } if(fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'_b.jpg'))){ 場景列表.push( { id:路徑名, panorama:{ left: path.join('/widgetData',name,路徑名,'_r.jpg').replace(////g,'/'), front: path.join('/widgetData',name,路徑名,'_b.jpg').replace(////g,'/'), right: path.join('/widgetData',name,路徑名,'_l.jpg').replace(////g,'/'), back: path.join('/widgetData',name,路徑名,'_f.jpg').replace(////g,'/'), top: path.join('/widgetData',name,路徑名,'_u.jpg').replace(////g,'/'), bottom: path.join('/widgetData',name,路徑名,'_d.jpg').replace(////g,'/'), }, thumbnail:縮略圖路徑, options:{ caption:name, } } ) } else if(fs.existsSync(path.join(數(shù)據(jù)路徑,name,路徑名,'sphere.jpg'))){ 場景列表.push( { id:路徑名, panorama:path.join('/widgetData',name,路徑名,'sphere.jpg').replace(////g,'/'), options:{ caption:name, }, thumbnail:縮略圖路徑, } ) } } ) res.json(場景列表)}
然后再看一下127.0.0.1:6809/?project=云park48let 全景圖選項(xiàng) = { container: document.querySelector('#viewer'), panorama: 全景圖列表[0].panorama, plugins: [ [GalleryPlugin, { visibleOnLoad: true, }], ],}//如果有六面圖文件,就使用六面圖適配器if(全景圖列表[0].panorama.left){ 全景圖選項(xiàng).adapter = CubemapAdapter}let viewer= new Viewer(全景圖選項(xiàng))
這回顯示對了,效果就像這樣:關(guān)鍵詞:瀏覽,簡單,渲染,筆記,折騰,記錄
客戶&案例
營銷資訊
關(guān)于我們
微信公眾號
版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。