ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Krpano XML配置全解析:校园全景漫游场景切换与热点地图交互

Krpano XML配置全解析:校园全景漫游场景切换与热点地图交互 简介这份文档面向希望入门全景漫游开发的前端与虚拟展示方向学习者围绕 krpano 这一全景漫游引擎梳理从引擎能力到校园全景项目落地的完整实现思路。内容以标签体系为线索逐一说明 include、preview、image、view、display、control、autorotate、plugin、hotspot、events、action、scene、contextmenu、progress、network、memory、security、textstyle、lensflare 等标签的用途与配置方式并延伸到 Krpano Viewer 的能力边界。压缩包仅含 1 个 doc 文件约 41KB轻量便于离线查阅。文档后段给出校园全景漫游的具体实现路径包括借助 swfkrpano.js 把查看器嵌入 HTML 页面、通过根节点 onstart 事件设置初始场景、用 scene 与 action 构建多场景并实现视角与音频控制、以 image 载入球面全景图、用 hotspot 完成场景互联、利用 plugin 自行实现导航地图与地图热点附带 Crop 裁切图标等实用细节。目前已有 144 人学习适合需要理解 krpano 配置结构与项目组织方式的读者参考。1. 全景校园漫游卡在“场景切不动”问题多半在 XML 而不在素材校园全景漫游这类项目最容易被误判的地方在于很多人以为难点是拍摄和拼图真正拖工期的却是 Krpano 的 XML 配置链路。同一套全景图热点点了不跳、地图不换、按钮按了没反应九成不是图片问题而是scene的 name、action的 name、插件的 parent 绑定或者相对路径写错了。Krpano 是一个完全靠 XML 标签加轻量脚本驱动的 viewer标签之间彼此引用一处名字写偏整条交互链就断在那一环。这份资源适合做校园、景区、展厅漫游的前端和三维方向同学也适合已经会用全景相机、却被 XML 卡住的人。下面按“标签体系 → HTML 嵌入 → 场景与热点 → 地图与按钮”的顺序把能直接抄的配置和参数讲清楚。2. Krpano 标签体系与球面全景图的加载链路2.1 根节点下的标签分层先分清谁管什么Krpano 的所有配置都挂在根节点krpano下面标签看着多其实按职责分四类就清楚了。加载类管资源进来显示类管渲染质量交互类管鼠标键盘和事件结构类管场景与插件。分不清这一点就会出现把alpha写到image上、把url写到display上的低级错误而 Krpano 对未知属性通常静默忽略你只会看到“怎么没效果”。标签职责典型属性常见坑include引入其他 xml 片段url相对路径以主 xml 所在目录为基准preview大图加载前显示小图url、typetype 必须与主图一致image载入全景图本体type、multiressphere 与 cube 的 type 值不能混用view记录当前视角hlookat、vlookat、fov写死在 xml 里会覆盖用户的进入视角display渲染质量与性能quality、movetquality移动端开最高档会掉帧control鼠标键盘控制mouse、keyboard与autorotate同时开容易打架plugin/layer载入 flash、图片、按钮url、align、parentlayer 是 plugin 的别名别重复定义同名hotspot场景内热点ath、atv、onclick坐标是球面角度不是像素action定义脚本动作namename 全局唯一重名会互相覆盖events事件响应onstart、onloadcomplete写在根节点还是 scene 内作用域不同scene定义场景name、onstartname 必须全局唯一memory/network内存与下载控制maxmem、downloadqueues切图量大时不调会爆内存新手最容易忽略的是action和scene的 name 都属于全局命名空间。你有两个场景都定义叫startscene的动作后加载的会顶掉前一个表现就是“第一个场景正常、第二个场景视角乱飞”。2.2 image 与 sphere球面全景图的加载方式校园漫游一般用单张球面图配置很省事但type一旦写错画面会直接糊成一条!-- 单分辨率球面全景图最省事的写法 -- image typeSPHERE sphere urlpano/scene1.jpg / /image !-- 多分辨率切片适合大图或移动端 -- image typeSPHERE multires512,1024,2048 level tiledimagewidth2048 tiledimageheight1024 sphere urlpano/scene1_%0v_%0h.jpg / /level /imagetype只认SPHERE、CYLINDER、CUBE三种球面图填SPHERE。multires里的数字是各级切片宽度viewer 会按当前视口和带宽自动选级%0v、%0h是行列占位符切片工具生成的文件名必须和它对得上。常见做法是先用单分辨率跑通交互再换切片不然你分不清是切图没对上还是别的标签写错了。2.3 preview、progress、network 决定第一眼的观感大图进浏览器之前有几秒空白用户会以为页面挂了。补一个preview再配progress体验立刻不一样!-- 低分辨率小图几百 KB先撑住画面 -- preview typeSPHERE urlpano/scene1_preview.jpg / !-- 加载进度条显示下载进度等待时不转圈 -- progress showloadsize showwaitnone / !-- 下载与解码并发带宽差时把并发压到 2 -- network downloadqueues2 decodequeues1 /showload取值none、size、percent、barsize显示的是字节数观感比百分比稳。network的队列数不是越大越好并发拉太高会把首帧优先级冲掉反而更慢。我一般在局域网演示环境开 4外网发布压到 2。2.4 crop 属性把多个图标合并成一张精灵图Krpano 的crop用来从一张大图里裁一块出来用语法是cropx|y|width|height四个值分别是起点横纵坐标和裁切宽高!-- 从 icons.png 的 (0,150) 处裁出 150x150 的播放图标 -- plugin namesnd urlicons.png alignleftbottom crop0|150|150|150 /这么做的好处是一次请求拿到所有按钮素材切场景时不会因为补图闪烁。注意分隔符是竖线|写成逗号 Krpano 不会报错只是整块不裁你会看到一张巨大的精灵图糊在屏幕角上。所有小图标按 150 的倍数排布坐标心算就够不用开工具量。3. 用 swfkrpano.js 把 Viewer 嵌进 HTML 并驱动初始场景3.1 引入脚本与容器准备Krpano 提供swfkrpano.js负责创建和挂载 viewer页面侧只需要一个固定尺寸的容器。容器没有高度是最常见的白屏原因!-- 容器必须有明确高度父级 100% 时逐级往上都要给高度 -- div idkrpanoDIV stylewidth:100%;height:100%;/div script srcswfkrpano.js/script script typetext/javascript // 参数依次为主程序路径、对象名、宽度、高度 var swf createSWF(krpano.swf, krpanoSWFObject, 100%, 100%); // 指定主配置文件viewer 启动后按这个路径去读 xml swf.addVariable(xml, krpano.xml); // 把 viewer 挂到上面那个容器里 swf.embed(krpanoDIV); /scriptcreateSWF的四个参数是位置参数不要调换addVariable必须在embed之前调用否则变量注入不进去。embed的入参是容器的id字符串不是元素对象。3.2 一个容易踩的坑addVariable 调用两次原始写法里出现了两次addVariable(xml, ...)第一次写scenes-with-imagemap.xml后面又写krpano.xml。这不是配置两份而是后者覆盖前者最终只加载最后那一个。如果两行之间还夹着embed那第一次的值生效第二次根本没机会执行// 错误示范后一行覆盖前一行第一份配置永远不会被读到 swf.addVariable(xml, scenes-with-imagemap.xml); swf.addVariable(xml, krpano.xml); // 正确做法主配置只有一个其他配置用 xml 里的 include 引进来 swf.addVariable(xml, krpano.xml); swf.embed(krpanoDIV);需要多份配置时在krpano.xml里用include urlbuttons-png-include.xml /拆而不是在 JS 里反复覆盖同一个变量。3.3 根节点 onstart进入页面先落哪个场景初始场景不是在 JS 里定的是在根节点的onstart事件里定的krpano version1.0.8 onstartloadscene(scene1, null, MERGE); playsound(s1, sound/music.mp3, 0, 0);onstart在 viewer 初始化完成后触发后面跟一串分号分隔的脚本。loadscene的第一个参数是场景名必须和某个scene name...完全一致大小写敏感第二个参数传null表示不覆盖当前视角传角度值会强制转到指定方向第三个参数MERGE表示新场景与当前状态合并如果想彻底重置视角就用BLEND(1)之类的过渡方式。playsound来自音频插件参数依次是插件实例名、文件路径、循环标志、音量路径写错不会报错只是安静。3.4 嵌入后无反应的排查顺序按这个顺序查基本五分钟内能定位浏览器控制台是否报createSWF is not defined是则swfkrpano.js路径错。容器div的实际高度是否为 0用开发者工具量一下。krpano.xml是否 404看 Network 面板里那条请求的状态码。xml 解析是否失败version属性缺失或者标签没闭合都会导致整个文件被丢弃。场景名是否拼错loadscene找不到目标会停在黑屏。4. scene 构建、热点互连与地图插件的挂载4.1 scene 标签与它内部的组织顺序每个场景是一段独立配置name全局唯一onstart在场景载入时触发scene namescene1 onstartaction(startscene); image typeSPHERE sphere urlpano/scene1.jpg / /image /scene action namestartscene set(heading, 90); !-- 进入视角的水平朝向 -- showtext([b]教学楼前广场[/b], infostyle); !-- 弹出文字提示 -- action(activatespot, scene3, 190); !-- 激活指定场景的地图热点 -- playsound(s1, sound/sound.mp3, 0, 0); !-- 场景切换音效 -- /actionset给变量赋值heading是内置视角变量showtext第一个参数是内容[b]是粗体标记第二个参数是textstyle里定义的样式名action调用另一个命名动作这是 Krpano 里复用逻辑的主要手段等价于 C# 里的方法调用。activatespot是我自己封装的、用来刷新地图热点高亮状态的动作它内部会遍历地图上的插件并切换图标。4.2 hotspot把相邻场景串成一条动线热点是场景内可点击的标记坐标用球面角度hotspot nameto_scene2 ath35.2 atv-8.4 urlhotspot_arrow.png onclickloadscene(scene2, null, MERGE); /ath是水平角度0 到 360atv是垂直角度-90 到 90跟全景图上的像素位置没关系靠肉眼对位效率很低。常见做法是先用一个显眼的临时图标从视角里读出hlookat和vlookat的当前值再填进ath、atv。onclick里可以直接写脚本也可以调命名动作热点多的时候后者更好维护。4.3 地图插件定位、透明度与缩放导航地图本质就是一个parent为空、贴在屏幕上的插件plugin namemap urlscenes/map.jpg keeptrue alignrighttop x-480 y0 alpha0.8 handcursorfalse scalechildrentrue width480 height360 /keeptrue让插件在切场景时不被销毁否则每换一个场景地图都要重新加载再闪一次。alignrighttop把锚点定在右上角x-480是相对锚点向左偏移 480 像素因为地图宽 480等于把它收到屏幕外。alpha控制透明度handcursorfalse让鼠标移上去不变成手型表示这层不直接响应点击。scalechildrentrue是关键它让挂在地图下的子插件跟随地图的坐标系统否则热点位置全乱。4.4 地图热点靠 parent 绑定在地图坐标系里场景在地图上的位置用插件表示通过parent挂到地图下面plugin namespot_scene1 urldot.png keeptrue parentmap alignleft edgecenter x162 y495 zorder2 onhovershowtext(教学楼, infostyle); onclickloadscene(scene1, null, MERGE, BLEND(1)); /parentmap的值必须和地图插件的name逐字符一致写错就变成屏幕坐标热点会跑到画面角落。alignleft配edgecenter表示以自身中心对齐父容器的左基准点x、y就是图上的像素坐标。zorder越大越靠上当前场景那个高亮图标给它更大的值就不会被别的点盖住。onhover显示文字onclick跳场景BLEND(1)是一秒淡入的过渡。5. 自定义按钮的状态切换与交互验证技巧5.1 声音按钮一次点击切换图标和静音状态Krpano 预设按钮之外的两个按钮声音和地图都是靠crop加状态变量实现的单键双态plugin namesnd urlicons.png alignleftbottom x10 y5 alpha0.6 scale1.0 keeptrue onovertween(alpha, 1); onouttween(alpha, 0.6); crop0|150|150|150 onclickswitch(soundinterface.mute); switch(crop, 0|150|150|150, 0|300|150|150); /tween(alpha, 1)是 0.5 秒内把透明度过渡到 1鼠标移开再降回来。switch(x)单参数时是取反所以第一次点击把soundinterface.mute翻成真声音停再点翻回假声音播放。第二个switch三个参数是「判断表达式、真值、假值」图标在这一步同步换成关闭态。两次switch写在同一个onclick里用分号隔开顺序不能反否则图标和声音状态会脱节。5.2 地图按钮用状态变量驱动 tween 位移地图的收起展开也是同一套路只是把对crop的切换换成了对x的补间plugin nameshowmap keeptrue urldaohang.png visibletrue alignrightbottom y5 onclickAset(state, A); tween(plugin[map].x, 0); onclickBset(state, B); tween(plugin[map].x, -480); onclickif(state A, onclickB(), onclickA()); /按钮本身只跑onclick里面用if判断当前state再去调 A 或 B。tween(plugin[map].x, 0)让地图从屏幕外滑进来收起来就补回-480。plugin[map]里的map就是地图插件的 name这里又一次印证了命名一致有多重要。5.3 上线前跑一遍自检打包之前我把这几个点固定过一遍能挡掉大部分线上白屏和交互失灵1. 所有 scene name、action name、plugin name 是否全局唯一 2. 每个 hotspot 的 ath/atv 是否落在可视角度范围内 3. 每个 parent 引用的插件名是否真实存在 4. include url 与图片 url 的相对路径是否以主 xml 目录为基准 5. 移动端是否关掉了 movetquality 高档渲染 6. network 的并发数是否按外网环境压到 2 到 3第 4 条可以用一行命令直接验把所有引用的文件路径抽出来跑一次存在性检查# 从主配置里抽出所有 url 属性值逐个判断文件是否存在 grep -oE url[^] krpano.xml | cut -d -f2 | while read f; do [ -f $f ] || echo 缺失: $f donegrep -oE只输出匹配片段cut -d -f2取引号内的路径循环里-f判断文件是否存在缺哪个直接打出来。这一步能在本地就把 include 和贴图的路径错误清干净省下不少在浏览器里反复刷新找 404 的时间。本文还有配套的精品资源点击获取
返回列表