Krpano website
This article is based on KRpano version 1.20.9
takeaway
What is the krpano
Krpano is a basis for customizing panoramic projects, and many online visual panoramic platforms are developed based on Krpano. It itself is not open source, commercial need to pay to buy, otherwise there will be a watermark, the purchase method readers can learn on the official website.
In this paper, the target
This article will do a complete panorama project from scratch. It is expected that the reader will understand the basic usage of Krpano after following the steps, without going into the syntax of Krpano in depth.
Online preview: Panorama Demo source code can be viewed and downloaded directly from the console
How do I use Krpano
Krpano file introduction
After downloading krpano from the official website, you can see the following files in the package:
The docu folder is krpano’s document, templates provides a set of templates, and Viewer is the place to put the examples. Double-click Krpano Testing server.exe to open it, and you’ll see a popup window that provides the address of the local service. Click inside to open it and you’ll see the same structure as above. Click on examples.html to see all the examples, which readers can browse for their own research.
Our focus is on the bottom.bat file, which is used to generate the panorama required by KRpano. It can be seen that there are 6 files in total below, among which the first one is to generate the planar graph and the last one is to generate the graph required by VR. We will ignore these two files for the moment and focus on the four files in the middle. MAKE PANO and MAKE VTOUR are two different types. They represent the generation of a single scene and a group of scenes respectively. NORMAL and MULTIRES in parentheses represent the type of generated panorama, and NORMAL represents the generation of 6-sided panorama. MULTIRES means to generate a more detailed panorama, and the reader can see the difference by manipulating it himself.
How to generate a panorama
First, I found two panoramic images from the Internet
Select them and drag toMAKE VTOUR (NORMAL) droplet.bat
On, a folder called vtour will be generated under the current folder. The folder directory structure is as follows
runtour_testingserver.exe
You can start the service, and you can see that the browser automatically opens the page with the basic functions: zoom, jump, full screen.So let’s start by looking at what it does, first of all, righttour.html
You can see in the file that it refers to a name calledtour.js
In fact, it iskrpano.js
And then I initialized it underneath
// Focus on the second and third lines
embedpano({
swf:"tour.swf".xml:"tour.xml".// Here is the configuration file, which is also the source of all krpano function configuration
target:"pano".// This "pano" represents the container ID set to krpano. You can see that there is a div with the id pano in the HTML
html5:"auto".mobilescale:1.0.passQueryParameters:true
});
Copy the code
As mentioned above, krpano’s most important configuration file is tour.xml, so let’s take a quick look at it first and see something like the following structure.
<krpano version="1.20.7" title="Virtual Tour">
<include url="skin/vtourskin.xml" />
<skin_settings maps="false"
.
/>.<action name="startup" autorun="onstart">if(startscene === null OR ! scene[get(startscene)], copy(startscene,scene[0].name); ) ; loadscene(get(startscene), null, MERGE); if(startactions ! == null, startactions() );</action>
<scene name="scene_view1" title="view1" onstart="" thumburl="panos/view1.tiles/thumb.jpg" lat="" lng="" heading="">.</scene>.</krpano>
Copy the code
First, the outermost layer is wrapped by the KRpano tag, and the scene in the middle represents the scene, which you can see refers to the panorama file generated in the directory.
The section wrapped in the Action tag indicates that the first scenario is automatically loaded at startup.
<krpano version="1.20.7" title="Virtual Tour">
<action name="startup" autorun="onstart">if(startscene === null OR ! scene[get(startscene)], copy(startscene,scene[0].name); ) ; loadscene(get(startscene), null, MERGE); if(startactions ! == null, startactions() );</action>
<scene name="scene_view1" title="view1" onstart="" thumburl="panos/view1.tiles/thumb.jpg" lat="" lng="" heading="">
<view hlookat="0.0" vlookat="0.0" fovtype="MFOV" fov="120" maxpixelzoom="2.0" fovmin="70" fovmax="140" limitview="auto" />
<preview url="panos/view1.tiles/preview.jpg" />
<image>
<cube url="panos/view1.tiles/pano_%s.jpg" />
</image>
</scene>
<scene name="scene_view2" title="view2" onstart="" thumburl="panos/view2.tiles/thumb.jpg" lat="" lng="" heading="">
<view hlookat="0.0" vlookat="0.0" fovtype="MFOV" fov="120" maxpixelzoom="2.0" fovmin="70" fovmax="140" limitview="auto" />
<preview url="panos/view2.tiles/preview.jpg" />
<image>
<cube url="panos/view2.tiles/pano_%s.jpg" />
</image>
</scene>
</krpano>
Copy the code
With only one panorama left on the page, let’s start defining the functionality we want. So let’s list what we’re going to do
- Select the appropriate location in the scene, customize the hot spot with animation
- Click a hotspot to jump to a scene
- Click on the hotspot to interact with JS
- Hot spot shift animation
- There are instructions on the hot spots
- Implement asteroid opener and gyroscope
Add hot
The first feature we’ll implement is to add a hotspot to the scene, first adding a hotspot tag to the first scene
<hotspot
name="area1"
url="skin/vtourskin_hotspot.png" />
Copy the code
You can see an arrow graphic appearing in the middle of the screen, but we want to be able to customize its position by adding ath and ATV properties, where ATH represents horizontal coordinates and ath represents vertical coordinates
<hotspot
name="area1" ath="0.736" atv="35.471"
url="skin/vtourskin_hotspot.png" />
Copy the code
Again, slowly adjusting the number is clearly not enough, wouldn’t it be better to move the hotspot directly to the desired location? Of course it works. First add the following action under the krpano tag:
<action name="draghotspot">spheretoscreen(ath, atv, hotspotcenterx, hotspotcentery, calc(mouse.stagex LT stagewidth/2 ? 'l' : 'r')); sub(drag_adjustx, mouse.stagex, hotspotcenterx); sub(drag_adjusty, mouse.stagey, hotspotcentery); asyncloop(pressed, sub(dx, mouse.stagex, drag_adjustx); sub(dy, mouse.stagey, drag_adjusty); screentosphere(dx, dy, ath, atv); print_hotspot_pos(); ) ;</action>
<action name="print_hotspot_pos"><! [CDATA[ copy(print_ath, ath); copy(print_atv, atv); roundval(print_ath, 3); roundval(print_atv, 3); calc(plugin[hotspot_pos_info].html, '<hotspot name="' + name + '"[br] ...[br] ath="' + print_ath + '"[br] atv="' + print_atv + '"[br] ...[br] />'); ]]></action>
Copy the code
Then add this paragraph below the scene tag:
<plugin name="hotspot_pos_info"
type="text"
html="drag the hotspots..."
css="font-family:Courier; font-size: 25px;"
padding="8"
align="lefttop" x="10" y="10"
width="600"
height="200"
enabled="true"
/>
Copy the code
Also add relevant methods to the hotspot tag:
<hotspot name="area1" ath="-360" ATV ="35.471" URL ="skin/ vtourSkin_hotspot. PNG "onDown ="draghotspot()" />Copy the code
At this time, you can find a white box in the upper left corner of the scene. When you drag a hotspot, it will show the hotspot coordinate, so we can easily define the hotspot to the desired position. The first oneaction draghotspot
For hot drag, second oneaction print_hotspot_pos
Used to configure the upper left corner of the box, through the sceneplugin
Tag to create a plug-in and toprint_hotspot_pos
Pass parameters for output.
The frame of animation
Next we will animate the hot spot. First we need a sequence frame image, which will be used in krpano’s official exampleFirst place this image in the skin folder of the current project, and then point the hot image reference address to this image:
<hotspot
name="area1" ath="360" atv="35.471"
url="skin/arrow.png"
ondown="draghotspot()"
/>
Copy the code
In this case, the page directly displays the image, how to make it dynamic, here again use action, add the following code to the page:
<action name="do_crop_animation" scope="local" args="framewidth, frameheight, framerate"> <! -- define local variables --> calc(local.xframes, (caller.imagewidth /framewidth) BOR 0); calc(local.frames, xframes * ((caller.imageheight / frameheight) BOR 0)); def(local.frame, integer, 0); <! -- set the first frame --> calc(caller.crop, '0|0|' + framewidth + '|' + frameheight); <! Setinterval (calc('crop_anim_' + caller.name), calc(1.0 / framerate), if(caller.loaded, inc(frame); if( frame GE frames, if( caller.onlastframe ! == null, callwith(caller, onlastframe()) ); set(frame,0); ) ; mod(xpos, frame, xframes); div(ypos, frame, xframes); Math.floor(ypos); mul(xpos, framewidth); mul(ypos, frameheight); calc(caller.crop, xpos + '|' + ypos + '|' + framewidth + '|' + frameheight); The <! -- stop the interval when the hotspot gets removed --> clearinterval(calc('crop_anim_' + caller.name)); ) ;) ; </action>Copy the code
The hotspot changes are as follows:
<hotspot
name="area1" ath="360" atv="35.471"
onloaded="do_crop_animation(200, 100, 24);"
url="skin/arrow.png"
ondown="draghotspot()"
/>
Copy the code
You will see a rotating arrow on the page.
Scene jump
The above operation is only carried out in a single scene, the actual development is generally multiple scenes, scenes can also jump freely, so we will implement the function of clicking the hot spot to jump. First, continue adding new actions:
<action name="skin_loadscene" scope="local" args="newscenenameorindex, blendmode">if(webvr.isenabled AND scene.count GT 1, set(hotspot[skin_webvr_prev_scene].visible, false); set(hotspot[skin_webvr_next_scene].visible, false); ) ; calc(layer[skin_thumbborder].parent, 'skin_thumb_' + scene[get(newscenenameorindex)].index);<! -- layer[skin_thumbs].scrolltocenter(get(scene[get(newscenenameorindex)].thumbx), get(scene[get(newscenenameorindex)].thumby)); -->
loadscene(get(scene[get(newscenenameorindex)].name), null, get(skin_settings.loadscene_flags), get(blendmode));
</action>
<action name="skin_gotoscene" scope="local" args="newscene">if(scene[get(newscene)], copy(cursceneindex, scene[get(xml.scene)].index); copy(newsceneindex, scene[get(newscene)].index); Skin_loadscene (get(newsceneIndex), 'ZOOMBLEND(1.0, 1.0, easeInOutSine)')); ;</action>
Copy the code
Action names give you an intuitive sense of what they mean. The first is loading the scene, and the second is switching the scene. We add click events to the hotspot:
<hotspot name=" hotspot "ath=" -hotspot" atV =" -hotspot "onloaded="do_crop_animation(64, 64, 60); url="skin/arrow.png" ondown="draghotspot()" onclick="skin_gotoscene('scene_view2')" />Copy the code
Click on the hot spot to see the scene fade in and out.
Add text to the hotspot
Sometimes the hotspot needs to be accompanied by some text. If the text is made on the hotspot, it needs many pictures when there are many hotspots, which is obviously more troublesome. It is better to separate the text directly.
<action name="add_all_the_time_tooltip"> txtadd(tooltipname, 'tooltip_', get(name)); addhotspot(get(tooltipname)); set(hotspot[get(tooltipname)].url,'%SWFPATH%/plugins/textfield.swf'); set(hotspot[get(tooltipname)].align,top); set(hotspot[get(tooltipname)].edge,bottom); If (device. Mobile, set (hotspot) [r]. Get (tooltipname) scale, 0.5);) ; set(hotspot[get(tooltipname)].atv,get(hotspot[get(name)].atv)); set(hotspot[get(tooltipname)].ath,get(hotspot[get(name)].ath)); set(hotspot[get(tooltipname)].autowidth,true); set(hotspot[get(tooltipname)].autoheight,true); set(hotspot[get(tooltipname)].vcenter,true); set(hotspot[get(tooltipname)].background,true); set(hotspot[get(tooltipname)].bgroundedge,10); set(hotspot[get(tooltipname)].backgroundcolor,0xccc); set(hotspot[get(tooltipname)].roundedge,5); set(hotspot[get(tooltipname)].backgroundalpha,1); set(hotspot[get(tooltipname)].padding,5); set(hotspot[get(tooltipname)].border,false); set(hotspot[get(tooltipname)].glow,0); set(hotspot[get(tooltipname)].zorder,99999); set(hotspot[get(tooltipname)].glowcolor,0xFFFFFF); if(device.mobile, set(hotspot[get(tooltipname)].css,'text-align:center; color:#FFFFFF; font-size:28px; text-shadow: 1px 1px 1px #000; '); , set(hotspot[get(tooltipname)].css,'text-align:center; color:#FFFFFF; font-size:28px; text-shadow: 1px 1px 1px #000; '); ; set(hotspot[get(tooltipname)].textshadow,0); Set (hotspot [get (tooltipname)] textshadowrange, 6.0); set(hotspot[get(tooltipname)].textshadowangle,90); if(text == '' OR text === null, copy(hotspot[get(tooltipname)].html,scene[get(linkscene)].title), copy(hotspot[get(tooltipname)].html,text) ); set(hotspot[get(tooltipname)].enabled,false); if(hotspot[get(name)].typeid == '1', if(device.mobile, set(hotspot[get(tooltipname)].oy,100); , set(hotspot[get(tooltipname)].oy,100); ) ; , if(device.mobile, set(hotspot[get(tooltipname)].oy,100); , set(hotspot[get(tooltipname)].oy,100); ) ;) ; </action>Copy the code
Then add properties and events to the hotspot:
<hotspot name="area1" ath="-360" atV ="35.471" onloaded="do_crop_animation(64, 64, 60); Add_all_the_time_tooltip "url="skin/arrow.png" onDown ="draghotspot()" text=" Hotspot description" onclick="skin_gotoscene('scene_view2')" />Copy the code
You can see that the page displays a box with white text on a blue background and rounded corners. The parameters can be changed in the Action.
Angle limit
It is not difficult to find that the current panorama can be dragged up and down to see the top and bottom. Generally speaking, when viewing the scene, we want the user to be in a relatively flat range, but also do not want the user to zoom in too large a range, so we need to configure the scene to limit this range. As you can see, our current view configuration is as follows:
<view hlookat="0.0" vlookat="0.0" fovType ="MFOV" fov="120" maxpixelZoom ="2.0" fovmin="70" fovmax="140" limitView ="auto" />Copy the code
Hlootat and vlookat indicate the horizontal and vertical angles of the initial display, ranging from -180 to 180 and from -90 to 90 respectively. Fov indicates the Angle range, ranging from 0 to 179. We want to limit the scope of browsing up and down, we need to set vlookatmin and vlookatMax, modify the following code:
<view
hlookat="0.0"
vlookat="0.0"
vlookatmin="70"
vlookatmax="80"
fovtype="MFOV"
fov="120"
maxpixelzoom="2.0"
fovmin="70"
fovmax="140"
limitview="auto" />
Copy the code
Set limitView to fullrange; set Fullrange to Fullrange; set Fullrange to Fullrange; set Fullrange to Fullrange;
Krpano and page interaction
All of this is done in AN XML file, so what if you want to click on a hot spot, make the page pop up, or do more complicated DOM manipulation? Krpano also provides a method for XML and JS interaction: jscall
Let’s start by adding a random method to tour.html:
function showTips () {
alert('This is a popover')}Copy the code
Then add another hotspot to the scene. Note that the hotspot name attribute cannot be repeated in the same scene
<hotspot
name="area2" ath="320" atv="35.471"
url="skin/vtourskin_hotspot.png"
onclick="jscall(showTips())"
/>
Copy the code
Click on the hot spot, a popup window pops up on the page, and the function is complete.
Asteroid opening animation
There are two actions in this code, one is event. The first action is the main body of the asteroid animation. The second action is used to control the display of hot spots, so as not to display hot spots when entering the scene. Event indicates that the asteroid animation is executed after the folder is loaded.
<action name="skin_setup_littleplanetintro" scope="local">
<! -- skin_hideskin(instant); -->set_hotspot_visible(false); set(global.lpinfo, scene=get(xml.scene), hlookat=get(view.hlookat), vlookat=get(view.vlookat), fov=get(view.fov), fovmax=get(view.fovmax), limitview=get(view.limitview)); set(view, fovmax=170, limitview=lookto, vlookatmin=90, vlookatmax=90); lookat(calc(global.lpinfo.hlookat - 180), 90, 150, 1, 0, 0); Set (events[lp_events]. Onloadcomplete, delayedCall (0.5, if(lpinfo.scene === xml.scene, set(control.userControl, off); set(view, limitview=get(lpinfo.limitview), vlookatmin=null, view.vlookatmax=null); tween(view.hlookat|view.vlookat|view.fov|view.distortion, Calc (' + lpinfo hlookat + '|' + lpinfo. Vlookat + '|' + lpinfo. The fov + '|' + 0.0), 3.0, easeOutQuad); Delayedcall (3.0, set (control) usercontrol, all);<! -- skin_update_bouncinglimits_control(); -->
tween(view.fovmax, get(lpinfo.fovmax));
<! -- skin_deeplinking_update_url(); -->
delete(global.lpinfo);
set_hotspot_visible(true);
<! -- skin_showskin(); -->if(skin_settings.thumbs AND skin_settings.thumbs_opened, skin_showthumbs() ); ) ; , delete(global.lpinfo); ) ;) ;) ;</action>
<events name="lp_events_" keep="true"
onxmlcomplete="set(events[lp_events_].onxmlcomplete,null); if(device.webgl OR device.flash, skin_setup_littleplanetintro(); ) ; "
/>
<action name="set_hotspot_visible">for(set(i,0),i LT hotspot.count,inc(i), if(%1 == false, if(hotspot[get(i)].visible == true, set(hotspot[get(i)].mark,true); set(hotspot[get(i)].visible,%1); ) ; , if(hotspot[get(i)].mark == true OR hotspot[get(i)].mark2 == true, set(hotspot[get(i)].visible,%1); ) ;) ;) ;</action>
Copy the code
gyroscope
To do mobile terminal projects, gyroscope function is sometimes needed. Krpano gyroscope is very convenient to use. Add the following in the code:
<plugin name="skin_gyro" keep="true" url="./plugins/gyro2.js" softstart="1.0" enabled="true" />
<! The following action controls the gyro on and off.
<action name="switch_gryo">
switch(plugin[skin_gyro].enabled);
</action>In this way, gyroscope can be used on android phones, but in ios13 and above, users need to obtain user authorization, so you need to judge, generally speaking, gyroscope function is off by default, users click to make the corresponding judgment, another point to note that the website using gyroscope authorization must have HTTPS certificate. Sample code is provided here, and the full code can be seen on Github. ```js var ua = navigator.userAgent if (!! ua.match(/\(i[^;] +; ( U;) ? ()? CPU.+Mac OS X/i)) { if ( typeof window.DeviceMotionEvent ! == "undefined" && typeof window.DeviceMotionEvent.requestPermission === "function" ) { // (optional) Do something before API request prompt. window.DeviceMotionEvent.requestPermission() .then(function (response) { // (optional) Do something after API prompt dismissed. if (response == "granted") { ... // start gyroscope} else {... }}). Catch (function (e) {... }); } else { var str = ua.toLowerCase().match(/cpu iphone os (.*?) Like MAC OS /) var v = STR [1].split('_')[0] / 1 if (v < 13) {else {//... } } } else { ... }Copy the code
Displacement of the animation
Sometimes we want the hotspot to have some simple displacement animation without using sequence frames, adding an action:
<action name="float_animation">def(val, number, 0); Def (Max, number, 0.1); def(flag, boolean, true); Setinterval (calc('val' + caller.name), 0.05, inc(val, 0.01); if (flag, set(ath, calc(ath + val)); set(atv, calc(atv + val)); , set(ath, calc(ath - val)); set(atv, calc(atv - val)); ) ; if (val GE max, set(flag, calc(! get(flag))); set(val, 0)); ) ;</action>
Copy the code
Also add this action to the hot spot
<hotspot
name="area2" ath="320" atv="35.471"
onloaded="float_animation"
url="skin/vtourskin_hotspot.png"
onclick="jscall(showTips())"
/>
Copy the code
You can see that the hotspot has a slight floating effect, so how this code is implemented, step by step to explain.
Def setInterval calc set inc if (krpano) def setInterval calc set inc if (krpano) def setInterval calc set Inc if (KRpano)
Def (variable, type, value*) defines variable variable: the variable name. Type: variable type, including Boolean, number, INTEGER /int, uint, string, object, and array
Setinterval (ID, delay, actions) Creates a timer. Id: unique ID required by each interval. Delay: number of seconds between actions: executes a function
Calc (variable, expression) Since there are no free operations like in JS, most calculations are performed using calc
Set (variable, value) Assigns a value to a variable
Inc (variable, byValue *, Max *, min*) Increases or decreases a value. The upper and lower limits can be defined. Byvalue: increases or decreases a value
If (condition, then-actions, else-actions*) if(condition, then-actions, else-actions*) if(condition, then-actions, else-actions*) if(condition, then-actions, else-actions*) (Other conditions and executing functions) Execute function c)
If might be a little hard to understand, for example, in js code like this:
if (number == 1) {
fnA();
fnB();
} else if (number == 2) {
fnC();
} else {
fnD();
}
Copy the code
In Krpano it looks like this:
if (number == 1, fnA(); fnB(), number == 2, fnC(), fnD() );Copy the code
We define three variables and increment them by 0.01 every 0.05 frames, using flag to increase or decrease the ath and ATV values (both values are automatically acquired).
If written in js, it would look like this:
var time = 0;
var max = 0.1;
var flag = true;
setInterval(function () {
time += 0.01;
if (flag) {
ath = ath + time;
atv = atv + time;
} else {
ath = ath - time;
atv = atv - time;
}
if(time >= max) { flag = ! flag; time =0; }},1000)
Copy the code
conclusion
This is the introductory guide to Krpano, if there are mistakes or unreasonable places, welcome to correct.
Resources: krpano.com/docu www.krpano360.com