雅荷心语博客
雅荷心语
心之所向便是光
  • 首页
  • 前端之旅
  • 后端之路
  • 软件工具
  • 心灵鸡汤
  • 心路历程
  • 视频资料
  • 关于我们
    • 关于我
    • 关于我
  • 微信平台
    • 业务合作
  • 首页
  • 前端之旅
  • 后端之路
  • 软件工具
  • 心灵鸡汤
  • 心路历程
  • 视频资料
  • 关于我们
    • 关于我
    • 关于我
  • 微信平台
    • 业务合作
  • 关注本站
    • 微信
    • 微博
    • 腾讯微博
    • Twitter
    • Facebook
    • RSS订阅
Hi, 请登录     我要注册     找回密码
分享到:

前端之旅 第11页

去分类设置中添加分类描述吧

记录几个常用的HTML空格占位符

2017-10-26admin阅读(2657)评论(0)

  == 普通的英文半角空格

  ==   ==   == no-break space (普通的英文半角空格但不换行)

  == 中文全角空格 (一个中文宽度)

  ==   == en空格 (半个中文宽度)

  ==   == em空格 (一个中文宽度)

  == 四分之一em空格 (四分之一中文宽度)

相比平时的空格( ),nbsp拥有不间断(non-breaking)特性。

即连续的nbsp会在同一行内显示。即使有100个连续的nbsp,浏览器也不会把它们拆成两行。

http://www.qdkf.net/41.html

简单理解vue的slot内容分发

2017-10-25admin阅读(2204)评论(0)

官方文档这样说

为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个过程被称为内容分发 (即 Angular 用户熟知的“transclusion”)。Vue.js 实现了一个内容分发 API,参照了当前 Web Components 规范草案,使用特殊的 <slot> 元素作为原始内容的插槽。

那我们在实际中到底怎么使用:

我们新建两个组件

父组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<template>
    <div class="hello">
        <div>
            <h1>我是父组件的标题</h1>
            <component>
              
            </component>
        </div>
    </div>
</template>
 
<script>
    import component from './Test.vue'
    export default {
        name: 'hello',
        data () {
            return {}
        },
        components:{
            component
        },
        created:function () {}
    }
</script>

子组件里

1
2
3
4
5
6
<template>
    <div>
        <h2>我是子组件的标题</h2>
        <slot>只有在没有要分发的内容时才会显示。</slot>
    </div>
</template>

 

这样执行以下代码,

效果是这样

QQ截图20171025101932

 

很明显可以看出来: 写在父组件 component 里面的内容被动态的显示在了子组件里面

如果我把 component  里面的内容删除,则会变成这样

QQ截图20171025102543

显示出来了我们定义的默认值,这样大家应该能想到使用场景了!

我们能直接动态传内容到子组件里面,如果不传,就使用子组件里面默认的值!

比如我们的弹窗,就可以直接使用这样来自定义内容了

vue 官方推荐Nuxt.js 服务端渲染尝试!

2017-10-18admin阅读(2623)评论(0)

安装

Nuxt.js 十分简单易用。一个简单的项目只需将 nuxt 添加为依赖组件即可。

项目安装

1
$ vue init nuxt-community/starter-template <project-name>

安装完成后, 进入项目!

安装依赖: npm install

启动项目!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export default {
  head: {
    title: '哈哈哈~',
    meta: [
      { hid: 'description', name: 'description', content: 'About page description' }
    ]
  },
  serverCacheKey () {
    // Will change every 10 secondes
    return Math.floor(Date.now() / 10000)
  },
  asyncData ({ req, params }) {
    // We can return a Promise instead of calling the callback
    return axios.get('https://jsonplaceholder.typicode.com/posts')
    .then((res) => {
      return { posts: res.data.slice(0, 5) }
    })
  },
  components: {
    Logo
  }
}

直接设置head 即可设置SEO相关信息!

krpano xml 文件参数详解

2017-10-11admin阅读(7197)评论(0)

xml配置文件的参数详解,收藏来自网络

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
<krpano>
 
    <!-- krpano 1.19.pr8 - Virtual Tour Skin -->
    <!-- maps="false"  是否使用必应地图或谷歌地图
    maps_type="bing"  选择使用谷歌地图或必应地图
    maps_bing_api_key=""   必应地图所需的API密钥,需申请
    maps_google_api_key=""   谷歌地图所需的API密钥,需申请
    maps_zoombuttons="false"   是否在地图上显示缩放按钮
    gyro="true"   是否使用陀螺仪
    webvr="true"    是否启用VR
    webvr_gyro_keeplookingdirection="false" 进入陀螺仪或VR时是否保持观看方向
    webvr_prev_next_hotspots="true"  在VR下是否启用导航到前后场景的链接热点
    littleplanetintro="false"    是否使用小行星开场
    title="true"  是否左下角显示title
    thumbs="true"  是否使用缩略图,如不使用,则没有缩略图一栏
    thumbs_width="120" thumbs_height="80" thumbs_padding="10" thumbs_crop="0|40|240|160"  缩略图宽度、高度、间距以及缩略图裁切范围
    thumbs_opened="false"   是否在启动时弹出缩略图一栏
    thumbs_text="false"  是否在缩略图上显示名字
    thumbs_dragging="true"   是否允许鼠标拖拽缩略图区域
    thumbs_onhoverscrolling="false"  是否允许鼠标悬停缩略图自动滚动
    thumbs_scrollbuttons="false"   是否显示缩略图滚动按钮
    thumbs_scrollindicator="false"   是否显示缩略图滚动条
    thumbs_loop="false"  滚动按钮是否使用缩略图循环
    tooltips_buttons="false" 鼠标在按钮悬停时是否弹出文字提示
    tooltips_thumbs="false"  鼠标在缩略图悬停时是否弹出文字提示
    tooltips_hotspots="false"   鼠标在热点上悬停时是否弹出文字提示
    tooltips_mapspots="false"   鼠标在地图热点悬停时是否弹出文字提示
    deeplinking="false"       是否使用深度链接获取功能,可使得当前页面路径获取场景及视角信息
    loadscene_flags="MERGE"  缩略图切换场景时的变量
    loadscene_blend="OPENBLEND(0.5, 0.0, 0.75, 0.05, linear)"  缩略图切换场景时的融合
    loadscene_blend_prev="SLIDEBLEND(0.5, 180, 0.75, linear)"  缩略图切换到上一个场景时的融合
    loadscene_blend_next="SLIDEBLEND(0.5, 0, 0.75, linear)"  缩略图切换到下一个场景时的融合
    loadingtext="载入中..." 在全景图载入中时显示的文字
    layout_width="100%"  导航条容器相对屏幕宽度的百分比
    layout_maxwidth="814"  导航条容器的最大宽度像素
    controlbar_width="-24" 导航条背景的宽度像素
    controlbar_height="40"  导航条背景的高度像素
    controlbar_offset.normal="20"  导航条背景与屏幕底部的距离
    controlbar_offset_closed="-40"  导航条隐藏状态时与屏幕底部的距离
    controlbar_overlap.no-fractionalscaling="10"  在不支持分级缩放页面和设置像素比的设备的导航条重叠的像素
    controlbar_overlap.fractionalscaling="0" 支持分级缩放页面和设置像素比的设备的导航条重叠的像素
    design_skin_images="vtourskin.png" 皮肤所用的源图片
    design_bgcolor="0x000000" 皮肤的背景颜色
    design_bgalpha="0.5" 皮肤的透明度
    design_bgborder="0 0xFFFFFF 1.0" 皮肤的边框
    design_bgroundedge="1" 皮肤边框圆角设置
    design_bgshadow="0 0 9 0xFFFFFF 0.5" 皮肤的背景阴影
    design_thumbborder_bgborder="4 0xFFFFFF 1.0" 皮肤的缩略图边框
    design_thumbborder_padding="2" 皮肤缩略图边框间距
    design_thumbborder_bgroundedge="5" 皮肤缩略图边框的圆角
    design_text_css="color:#FFFFFF; font-family:Arial; font-weight:bold;"皮肤文字样式
    design_text_shadow="1" 皮肤的文字阴影 -->
    <skin_settings maps="false"
                   maps_type="google"
                   maps_bing_api_key=""
                   maps_google_api_key=""
                   maps_zoombuttons="false"
                   gyro="true"
                   webvr="true"
                   webvr_gyro_keeplookingdirection="false"
                   webvr_prev_next_hotspots="true"
                   littleplanetintro="false"
                   title="true"
                   thumbs="true"
                   thumbs_width="120" thumbs_height="80" thumbs_padding="10" thumbs_crop="0|40|240|160"
                   thumbs_opened="false"
                   thumbs_text="false"
                   thumbs_dragging="true"
                   thumbs_onhoverscrolling="false"
                   thumbs_scrollbuttons="false"
                   thumbs_scrollindicator="false"
                   thumbs_loop="false"
                   tooltips_buttons="false"
                   tooltips_thumbs="true"
                   tooltips_hotspots="false"
                   tooltips_mapspots="false"
                   deeplinking="false"
                   loadscene_flags="MERGE"
                   loadscene_blend="OPENBLEND(0.5, 0.0, 0.75, 0.05, linear)"
                   loadscene_blend_prev="SLIDEBLEND(0.5, 180, 0.75, linear)"
                   loadscene_blend_next="SLIDEBLEND(0.5,   0, 0.75, linear)"
                   loadingtext="loading..."
                   layout_width="100%"
                   layout_maxwidth="814"
                   controlbar_width="-24"
                   controlbar_height="40"
                   controlbar_offset="20"
                   controlbar_offset_closed="-40"
                   controlbar_overlap.no-fractionalscaling="10"
                   controlbar_overlap.fractionalscaling="0"
                   design_skin_images="vtourskin.png"
                   design_bgcolor="0x2D3E50"
                   design_bgalpha="0.8"
                   design_bgborder="0"
                   design_bgroundedge="1"
                   design_bgshadow="0 4 10 0x000000 0.3"
                   design_thumbborder_bgborder="3 0xFFFFFF 1.0"
                   design_thumbborder_padding="2"
                   design_thumbborder_bgroundedge="0"
                   design_text_css="color:#FFFFFF; font-family:Arial;"
                   design_text_shadow="1"
                   />
 
 
    <!-- save the url path of this xml file (the url value will be adjusted during xml parsing) -->
    <vtourskinxmlpath url="./" />
 
 
    <!-- mouse / touch / keyboard(button) control settings - http://krpano.com/docu/xml/#control -->
    <!-- 鼠标触屏键盘控制的设定 -->
    <control mouse="drag"
             touch="drag"
             zoomtocursor="false"
             zoomoutcursor="false"
             draginertia="0.1"
             dragfriction="0.9"
             movetoaccelerate="1.0"
             movetospeed="10.0"
             movetofriction="0.8"
             keybaccelerate="0.09"
             keybfriction="0.94"
             keybfovchange="0.25"
             mousefovchange="1.0"
             fovspeed="3.0"
             fovfriction="0.9"
             bouncinglimits="true"
             />
 
    <!-- mouse cursors - http://krpano.com/docu/xml/#cursors -->
    <!-- 鼠标光标设定可自定义光标的样式 -->
    <cursors standard="default"
             dragging="move"
             moving="move"
             />
 
 
    <!-- ensure stagescale 2x for mobile devices (regardless if mobilescale is 0.5 or 1.0) -->
 
    <krpano stagescale="calc:stagescale * 2" if="stagescale LT 1.0" devices="mobile" />
 
 
    <!-- include VR support - http://krpano.com/plugins/webvr/ -->
    <!-- WebVR插件 -->
    <include url="%SWFPATH%/plugins/webvr.xml" devices="html5" />
 
    <!-- overwrite some settings from the webvr.xml for the skin integration -->
    <!-- 覆盖WebVR默认设定 -->
    <!-- onavailable去除插件自定义的进入VR按钮(因为皮肤中已包含)webvr_enterbutton
    skin_arrange_buttons初始化皮肤按钮  webvr_onavailable()初始化设定,显示Enter VR 按钮-->
    <!-- onentervr skin_showloading去除加载文字 webvr_setup 设置场景切换热点并跟随
    webvr_onentervr 将所有没有添加vr="true"的layer隐藏,并显示VR的Layer skin_reloadscene_webvr
    显示屏幕旋转提示图片-->
    <plugin name="WebVR" keep="true" devices="html5"
            pluginurl="%SWFPATH%/plugins/webvr.js"
            url=""
            multireslock.desktop="true"
            multireslock.mobile.or.tablet="false"
            mobilevr_support="true"
            mobilevr_fake_support="true"
            onavailable="removelayer(webvr_enterbutton); skin_arrange_buttons(); webvr_onavailable();"
            onentervr="skin_showloading(false); webvr_onentervr(); webvr_setup(); skin_reloadscene_webvr();"
            onexitvr="webvr_onexitvr(); webvr_setup(); skin_reloadscene_webvr();"
            />
 
    <!-- webvr button style (adjust to match skin style) -->
    <!-- 修改WebVR界面的style使其符合当前场景的样式 主要设置背景颜色和文字 -->
    <style name="webvr_button_style"
           border="false"
           roundedge="calc:1.0"
           backgroundcolor="get:skin_settings.design_bgcolor" backgroundalpha="get:skin_settings.design_bgalpha"
           shadow="0.01" shadowrange="10.0" shadowangle="90.0" shadowcolor="0x30261B" shadowalpha="0.50"
           css="calc:skin_settings.design_text_css + ' color:#FFFFFF;font-size:' + 20*webvr_setup_scale*webvr_button_scale + 'px;'"/>
 
    <!-- show a 'rotate the device' info when the mobile device is in portrait orientation in VR mode -->
    <!-- 显示屏幕旋转提示图片 devices="mobile" 只在手机模式下-->
    <layer name="webvr_rotate_to_landscape_request" keep="true" vr="true" devices="mobile"
           url="rotate_device.png" scale="0.5"
           align="top" edge="center" y="28%"
           autoalpha="true" alpha="0.0"
           enabled="false"
           />
    <!-- WebVR相关事件触发 webvr_set_startup_view 设置镜头位置 onloadcomplete根据场景数目觉得是否显示VR场景切换热点-->
    <events name="webvr_events" keep="true" devices="html5"
            onxmlcomplete="webvr_set_startup_view()"
            onresize.mobile="webvr_act_as_gyro_in_portrait_mode();"
            onloadcomplete="delayedcall(0.5, if(webvr.isenabled AND scene.count GT 1 AND skin_settings.webvr_prev_next_hotspots, set(hotspot[webvr_prev_scene].visible,true); set(hotspot[webvr_next_scene].visible,true); ); );"
            onviewchange=""
            />
    <!-- 根据VR是否打开设置镜头位置 -->
    <action name="webvr_set_startup_view">
        if((webvr.isenabled OR plugin[skin_gyro].enabled) AND skin_settings.webvr_gyro_keeplookingdirection == false,
            skin_lookat( get(xml.view.hlookat) );
          );
    </action>
 
    <!-- 进入VR时设定 -->
    <action name="webvr_setup">
        if(webvr.isenabled,
            <!-- 读取自定义设定 -->
            copy(loadscene_flags_backup, skin_settings.loadscene_flags);
            <!-- 设置为 MERGE|KEEPVIEW|KEEPMOVING|NOPREVIEW-->
            set(skin_settings.loadscene_flags, MERGE|KEEPVIEW|KEEPMOVING|NOPREVIEW);
            <!-- 打开WebVR时是否竖屏启动陀螺仪 -->
            webvr_act_as_gyro_in_portrait_mode(true);
            <!-- 读取设置是否显示VR模式下的上下按钮 并且设置跟随-->
            if(scene.count GT 1 AND skin_settings.webvr_prev_next_hotspots,
                set(hotspot[webvr_prev_scene].visible, true);
                set(hotspot[webvr_next_scene].visible, true);
                set(events[webvr_events].onviewchange, webvr_menu_following());
              );
          ,
            if(loadscene_flags_backup !== null, copy(skin_settings.loadscene_flags, loadscene_flags_backup));
            tween(layer[webvr_rotate_to_landscape_request].alpha, 0.0, 0.0);
            set(hotspot[webvr_prev_scene].visible, false);
            set(hotspot[webvr_next_scene].visible, false);
            set(events[webvr_events].onviewchange, null);
          );
    </action>
    <!-- 打开WebVR时是否竖屏启动陀螺仪 -->
    <action name="webvr_act_as_gyro_in_portrait_mode">
        if(device.mobile AND webvr.isenabled,
            div(aspect, stagewidth, stageheight);
            if(aspect != lastaspect OR '%1' == 'true',
                copy(lastaspect, aspect);
                if(stagewidth GT stageheight,
                    <!-- landscape orientation - use stereo rendering and a direct/fast gyro sensor mode -->
                    set(display.stereo, true);
                    set(webvr.mobilevr_sensor_mode, 3);
                    webvr.update();
                    tween(layer[webvr_rotate_to_landscape_request].alpha, 0.0, 0.0);
                  ,
                    <!-- portrait orientation - use normal rendering and a smoother/slower gyro sensor mode -->
                    set(display.stereo, false);
                    set(webvr.mobilevr_sensor_mode, 1);
                    webvr.update();
                    tween(layer[webvr_rotate_to_landscape_request].alpha, 1.0);
                    delayedcall(3.0, tween(layer[webvr_rotate_to_landscape_request].alpha, 0.0, 1.0); );
                  );
              );
          ,
            set(lastaspect, 0);
          );
    </action>
 
    <!-- VR scene switching hotspots -->
    <!-- VR场景切换热点 distorted="true" 热点跟随场景扭曲-->
    <style name="webvr_menu_style" depth="800" scale="0.5" distorted="true" ath="0" atv="45" alpha="0.5" />
    <hotspot name="webvr_prev_scene" keep="true" style="skin_base|webvr_menu_style" crop="0|64|64|64"  ox="-64" onover="tween(scale,0.6);" onout="tween(scale,0.5);" vr_timeout="750" onclick="skin_nextscene_loop(-1);" visible="false" devices="html5.and.webgl" />
    <hotspot name="webvr_next_scene" keep="true" style="skin_base|webvr_menu_style" crop="64|64|64|64" ox="+64" onover="tween(scale,0.6);" onout="tween(scale,0.5);" vr_timeout="750" onclick="skin_nextscene_loop(+1);" visible="false" devices="html5.and.webgl" />
 
    <!-- floating/following VR hotspots -->
    <!-- 设置VR模式下跟随镜头的场景切换热点 -->
    <action name="webvr_menu_following" type="Javascript" devices="html5"><![CDATA[        var hs1 = krpano.get("hotspot[webvr_prev_scene]");
        var hs2 = krpano.get("hotspot[webvr_next_scene]");
        //头追没有移动到热点处的时候
        if(!hs1.hovering && !hs2.hovering)
        {
            var f = 0.01;   // following speed factor
            var h = krpano.view.hlookat;//获取当前场景的垂直度数(垂直180°)
            var v = krpano.view.vlookat;//获取当前场景的水平度数(水平360°)
            var hsh = hs1.ath;
            var hsv = hs1.atv;
            //将度数转化为距离设置到热点上
            h   = (h  -(h|0))   + (((h|0)  +360180)%360) - 180.0;
            v   = (v  -(v|0))   + (((v|0)  +360180)%360) - 180.0;
            hsh = (hsh-(hsh|0)) + (((hsh|0)+360180)%360) - 180.0;
            var dh = h - hsh;
            dh += (dh > 180) ? -360 : (dh < -180) ? 360 : 0
            hsh += dh*f;
            var a = Math.abs(v - hsv) / 90.0;
            a = 1.0 * Math.max(1.0 - 2.0*Math.sqrt(a), 0);
            v = v + 55.0 - v*1.5;
            hsv = hsv*(1.0 - f) + v*f;
            hs1.ath = hs2.ath = hsh;
            hs1.atv = hs2.atv = hsv;
            hs1.alpha = hs2.alpha = a;
        }
    ]]></action>
    <!-- VR support -->
 
 
 
    <!-- skin styles -->
 
    <!-- skin_base - the base skin image -->
    <!-- 基础样式,设置皮肤的图标文件路径 -->
    <style name="skin_base" url="calc:vtourskinxmlpath.url + skin_settings.design_skin_images" />
 
 
    <!-- skin_glow - button glowing (if additional ondown,onup,onout,over events are needed, this style provides ondown2,onup2,onover2,onout2 events) -->
    <!-- 样式属性,如果有额外的事件监听使用 ondown2,onup2,onover2,onout2 skin_buttonglow 设置按钮的点击hover效果-->
    <style name="skin_glow"
           ondown="copy(skin_lockglow,name); skin_buttonglow(get(name)); if(ondown2, ondown2() );"
           onover="if(skin_lockglow === null, copy(skin_lockglow,name); skin_buttonglow(get(name),0.3) ); if(onover2, onover2() );"
           onout="if(skin_lockglow === name AND !pressed, skin_buttonglow(null);delete(skin_lockglow); ); if(onout2, onout2() );"
           onup="if(onup2, onup2()); delayedcall(0, if(hovering AND enabled, skin_buttonglow(get(name),0.3); , skin_buttonglow(null);delete(skin_lockglow); ); );"
           />
 
    <!-- skin_thumbtext_style - style/textfield for the (optional, skin_settings.thumbs_text) thumbnails texts -->
    <!-- 场景缩略图的文字样式 通过skin_settings.thumbs_text设定是否显示缩略图的文字-->
    <style name="skin_thumbtext_style" url="%SWFPATH%/plugins/textfield.swf" align="bottom" width="100%" autoheight="true" y="5" enabled="false" background="false" border="false" css="calc:skin_settings.design_text_css + ' text-align:center; font-size:10px;'" textshadow="get:skin_settings.design_text_shadow" />
 
    <!-- skin_hotspotstyle - style for the hotspots -->
    <!-- 当前皮肤热点的按钮样式 如果skin_settings.tooltips_hotspots为true 则将scene的title属性值设置为热点的tips-->
    <style name="skin_hotspotstyle" url="vtourskin_hotspot.png" scale="0.5" edge="top" distorted="true"
           tooltip=""
           linkedscene=""
           linkedscene_lookat=""
           onclick="skin_hotspotstyle_click();"
           onover="tween(scale,0.55);"
           onout="tween(scale,0.5);"
           onloaded="if(linkedscene AND skin_settings.tooltips_hotspots, copy(tooltip,scene[get(linkedscene)].title); loadstyle(skin_tooltips); );"
           />
    <!-- 热点点击 读取热点的linkedscene属性设置为跳转的scene如果存在linkedscene_lookat属性则按照","切分字符分别赋值给h,v,fov
    点击时隐藏tips 调用skin_loadscene打开场景skin_lookat旋转到指定位置-->
    <action name="skin_hotspotstyle_click">
        if(linkedscene,
            if(linkedscene_lookat,
                txtsplit(linkedscene_lookat, ',', hs_lookat_h, hs_lookat_v, hs_lookat_fov);
              );
            set(enabled, false);
            skin_hidetooltips();
            tween(depth|alpha|oy|rx, 4000|0.0|-50|-60, 0.5, default,
                skin_loadscene(get(linkedscene), get(skin_settings.loadscene_blend));
                if(hs_lookat_h !== null,
                    skin_lookat(get(hs_lookat_h), get(hs_lookat_v), get(hs_lookat_fov));
                    delete(hs_lookat_h, hs_lookat_v, hs_lookat_fov);
                  );
                skin_updatescroll();
              );
          );
    </action>
 
 
    <!-- skin_tooltip - style for the thumb, hotspot and mapspot tooltips -->
    <!-- tips样式,当前为鼠标移动到layer读取tooltip值设置到mouse.stagex  mouse.stagey(为鼠标的topleft位置) 这个位置-->
    <style name="skin_tooltips"
           onover.mouse="copy(layer[skin_tooltip].html, tooltip);
                         set(layer[skin_tooltip].visible, true);
                         tween(layer[skin_tooltip].alpha, 1.0, 0.1);
                         asyncloop(hovering, copy(layer[skin_tooltip].x,mouse.stagex); copy(layer[skin_tooltip].y,mouse.stagey); );"
           onout.mouse="tween(layer[skin_tooltip].alpha, 0.0, 0.1, default, set(layer[skin_tooltip].visible,false), copy(layer[skin_tooltip].x,mouse.stagex); copy(layer[skin_tooltip].y,mouse.stagey); );"
           />
 
 
    <!-- the tooltip textfield -->
    <!-- 文字提示tips layer使用文字插件展示,这里可以修改tips的式样 -->
    <layer name="skin_tooltip" keep="true"
           url="%SWFPATH%/plugins/textfield.swf"
           parent="STAGE"
           visible="false" alpha="0" enabled="false" zorder="2"
           align="lefttop" edge="bottom" oy="-2" width="200" autoheight="true"
           background="false" backgroundcolor="0xFFFFFF" backgroundalpha="1.0"
           border="false" bordercolor="0x000000" borderalpha="1.0" borderwidth="1.0" roundedge="0"
           shadow="0.0" shadowrange="4.0" shadowangle="45" shadowcolor="0x000000" shadowalpha="1.0"
           textshadow="get:skin_settings.design_text_shadow" textshadowrange="6.0" textshadowangle="90" textshadowcolor="0x000000" textshadowalpha="1.0"
           css="calc:skin_settings.design_text_css + ' text-align:center; font-size:16px;'"
           html=""
           />
 
 
    <!-- skin layout -->
    <!-- 下方控制条 -->
    <layer name="skin_layer" keep="true" type="container" align="top" width="get:skin_settings.layout_width" maxwidth="get:skin_settings.layout_maxwidth" height="100%" maskchildren="true" visible="false" bgcapture="false" zorder="1">
        <!-- 控制条上部分包括视频控制条,缩略图展示,场景名称等 -->
        <layer name="skin_scroll_window" type="container" align="bottom" width="100%" height="100%" x="0" y="calc:skin_settings.controlbar_offset + skin_settings.controlbar_height - skin_settings.controlbar_overlap" maskchildren="true" onloaded="skin_calc_opened_closed();" zorder="1">
            <layer name="skin_scroll_layer" type="container" align="bottom" width="get:skin_settings.controlbar_width" height="100%" x="200" y="200" y_offset="get:skin_settings.controlbar_overlap" accuracy="1" bgalpha="get:skin_settings.design_bgalpha" bgcolor="get:skin_settings.design_bgcolor" bgborder="get:skin_settings.design_bgborder" bgroundedge="get:skin_settings.design_bgroundedge" bgshadow="get:skin_settings.design_bgshadow">
                <!-- 场景名称 -->
                <layer name="skin_title" url="%SWFPATH%/plugins/textfield.swf" align="lefttop" edge="leftbottom" x="4" y="0" zorder="4" enabled="false" background="false" border="false" css="calc:skin_settings.design_text_css + ' text-align:left; font-style:italic; font-size:12px;'" textshadow="get:skin_settings.design_text_shadow" visible="false" onautosized="skin_video_updateseekbarwidth();" />
                <!-- 视频控制条 -->
                <layer name="skin_video_controls" type="container" align="lefttop" edge="leftbottom" width="100%" height="18" visible="false">
                    <layer name="skin_video_seekbar_container" type="container" align="lefttop" width="100%" height="100%" bgcapture="true" ondown="skin_video_ondownseeking();" >
                        <layer name="skin_video_seekbar" type="container" bgcolor="0xFFFFFF" bgalpha="0.25" align="center" width="100%" height="2">
                            <layer name="skin_video_loadbar" type="container" bgcolor="0xFFFFFF" bgalpha="0.5" align="left" width="0" height="2" />
                            <layer name="skin_video_seekpos" type="container" bgcolor="0xFFFFFF" bgalpha="1.0" align="left" edge="center" x="0" bgroundedge="8" width="10" height="10" />
                        </layer>
                    </layer>
                    <layer name="skin_video_time" url="%SWFPATH%/plugins/textfield.swf" align="rightbottom" x="4" enabled="false" background="false" border="false" css="calc:skin_settings.design_text_css + ' text-align:left; font-style:italic; font-size:12px;'" textshadow="get:skin_settings.design_text_shadow" html="0:00 / 0:00" />
                </layer>
                <layer name="skin_scroll_container" type="container" align="lefttop" width="100%" height="100%" x="0" y="0" bgroundedge="get:skin_settings.design_bgroundedge" maskchildren="true">
                    <!-- 缩略图展示 -->
                    <layer name="skin_thumbs_container" type="container" align="lefttop" width="100%" height="100%" visible="false">
                        <layer name="skin_thumbs_scrollleft"  style="skin_base|skin_glow" crop="0|64|64|64"  align="lefttop"  edge="left"  x="5" y="50" scale="0.5" zorder="2" alpha="1.0" ondown2="asyncloop(pressed, layer[skin_thumbs].scrollby(+2,0));" visible="false" />
                        <layer name="skin_thumbs_scrollright" style="skin_base|skin_glow" crop="64|64|64|64" align="righttop" edge="right" x="5" y="50" scale="0.5" zorder="2" alpha="1.0" ondown2="asyncloop(pressed, layer[skin_thumbs].scrollby(-2,0));" visible="false" />
                        <layer name="skin_thumbs_scrollindicator" type="container" bgcolor="0xFFFFFF" bgalpha="0.25" align="lefttop" width="0" y="100" height="2" visible="false" enabled="false" />
                        <!-- 滑动插件 -->
                        <layer name="skin_thumbs" state="closed" url.flash="%SWFPATH%/plugins/scrollarea.swf" url.html5="%SWFPATH%/plugins/scrollarea.js" direction="h" align="top" width="100%" height="100" zorder="1" onloaded="skin_updatescroll();" onscroll="skin_updatethumbscroll();" />
                    </layer>
                    <!-- 地图展示 -->
                    <layer name="skin_map_container" type="container" align="leftop" width="100%" height="100%" bgroundedge="get:skin_settings.design_bgroundedge" maskchildren="true">
                        <layer name="skin_map" state="closed" url="" visible="false" align="lefttop" width="100%" height="50%" x="0" y="0" zorder="1" lat="0" lng="0" zoom="10" bgalpha="0" maptype="satellite" onmapready="skin_addmapspots();">
                            <maptypecontrol visible="true" align="righttop" x="5" y="5" buttonalign="v" scale.mobile="1.5" />
                            <radar visible="false" headingoffset="0" />
                            <spotstyle name="DEFAULT" url="vtourskin_mapspot.png" activeurl="vtourskin_mapspotactive.png" edge="bottom" x="-5" y="-8" scale="0.5" />
                            <layer name="skin_map_zoom_in"  style="skin_base" visible="get:skin_settings.maps_zoombuttons" crop="9|512|46|64"  align="right" x="0" y="-40" zorder="2" ondown="layer[skin_map].zoomin();  skin_buttonglow(get(name));" onup="skin_buttonglow(null);" />
                            <layer name="skin_map_zoom_out" style="skin_base" visible="get:skin_settings.maps_zoombuttons" crop="73|512|46|64" align="right" x="0" y="+40" zorder="2" ondown="layer[skin_map].zoomout(); skin_buttonglow(get(name));" onup="skin_buttonglow(null);" />
                        </layer>
                    </layer>
                </layer>
            </layer>
        </layer>
        <!-- 底部控制条背景图 -->
        <layer name="skin_splitter_bottom" type="container" align="bottom" width="100%" height="calc:skin_settings.controlbar_offset + skin_settings.controlbar_height - skin_settings.controlbar_overlap" y="0" maskchildren="true" onloaded="skin_calc_opened_closed();" zorder="2">
            <layer name="skin_control_bar_bg" type="container" align="bottom" width="get:skin_settings.controlbar_width" height="calc:skin_settings.controlbar_height + skin_settings.controlbar_overlap" x="0" y="get:skin_settings.controlbar_offset" bgcolor="get:skin_settings.design_bgcolor" bgalpha="get:skin_settings.design_bgalpha" bgborder="get:skin_settings.design_bgborder" bgroundedge="get:skin_settings.design_bgroundedge" bgshadow="get:skin_settings.design_bgshadow" />
        </layer>
        <!-- 控制按钮区域 -->
        <layer name="skin_control_bar" type="container" align="bottom" width="get:skin_settings.controlbar_width" height="calc:skin_settings.controlbar_height" x="0" y="get:skin_settings.controlbar_offset" onloaded="skin_calc_opened_closed();" zorder="3">
            <!-- 控制按钮 -->
            <layer name="skin_control_bar_buttons" type="container" align="leftbottom" width="100%" height="get:skin_settings.controlbar_height">
                <!-- 前一个场景按钮 -->
                <layer name="skin_btn_prev"      style="skin_base|skin_glow" crop="0|64|64|64"   align="left"        x="5"    y="0"  scale="0.5" alpha="0.5"  onclick="if(skin_settings.thumbs_loop, skin_nextscene_loop(-1), skin_nextscene(-1) );" />
                <!-- 缩略图按钮,点击后调用skin_showthumbs方法动画展示缩略图-->
                <layer name="skin_btn_thumbs"    style="skin_base|skin_glow" crop="0|128|64|64"  align="left"        x="50"   y="0"  scale="0.5" ondown2="skin_showmap(false); skin_showthumbs();" />
                <!-- 地图按钮,点击后会隐藏缩略图-->
                <layer name="skin_btn_map"       style="skin_base|skin_glow" crop="64|128|64|64" align="left"        x="90"   y="0"  scale="0.5" ondown2="skin_showthumbs(false); skin_showmap();" visible="false" />
                <!-- 导航栏包括上下左右移动放大与缩小,鼠标按下距离+或-1,抬起初始化为默认的0 -->
                <layer name="skin_btn_navi" type="container" align="center" x="0" width="240" height="32">
                    <layer name="skin_btn_left"  style="skin_base|skin_glow" crop="0|192|64|64"  align="center"      x="-100" y="0"  scale="0.5" ondown2="set(hlookat_moveforce,-1);" onup2="set(hlookat_moveforce,0);" />
                    <layer name="skin_btn_right" style="skin_base|skin_glow" crop="64|192|64|64" align="center"      x="-60"  y="0"  scale="0.5" ondown2="set(hlookat_moveforce,+1);" onup2="set(hlookat_moveforce,0);" />
                    <layer name="skin_btn_up"    style="skin_base|skin_glow" crop="0|256|64|64"  align="center"      x="-20"  y="0"  scale="0.5" ondown2="set(vlookat_moveforce,-1);" onup2="set(vlookat_moveforce,0);" />
                    <layer name="skin_btn_down"  style="skin_base|skin_glow" crop="64|256|64|64" align="center"      x="+20"  y="0"  scale="0.5" ondown2="set(vlookat_moveforce,+1);" onup2="set(vlookat_moveforce,0);" />
                    <layer name="skin_btn_in"    style="skin_base|skin_glow" crop="0|320|64|64"  align="center"      x="+60"  y="0"  scale="0.5" ondown2="set(fov_moveforce,-1);"     onup2="set(fov_moveforce,0);" />
                    <layer name="skin_btn_out"   style="skin_base|skin_glow" crop="64|320|64|64" align="center"      x="+100" y="0"  scale="0.5" ondown2="set(fov_moveforce,+1);"     onup2="set(fov_moveforce,0);" />
                </layer>
                <!-- 开启或关闭陀螺仪按钮 -->
                <layer name="skin_btn_gyro"      style="skin_base|skin_glow" crop="0|384|64|64"  align="center"      x="+140" y="0"  scale="0.5" onclick="switch(plugin[skin_gyro].enabled); if(plugin[skin_gyro].enabled, skin_showmap(false));" visible="false" devices="html5" />
                <!-- 进入VR模式按钮 -->
                <layer name="skin_btn_vr"        style="skin_base|skin_glow" crop="0|0|80|64"    align="center"      x="+146" y="0"  scale="0.5" onclick="webvr.enterVR();" visible="false" />
                <!-- 全屏按钮 -->
                <layer name="skin_btn_fs"        style="skin_base|skin_glow" crop="0|576|64|64"  align="right"       x="90"   y="0"  scale="0.5" onclick="switch(fullscreen);" devices="fullscreensupport" />
                <!-- 隐藏控制条按钮 -->
                <layer name="skin_btn_hide"      style="skin_base|skin_glow" crop="0|448|64|64"  align="right"       x="50"   y="0"  scale="0.5" onclick="skin_hideskin()" />
                <!-- 显示控制条按钮 -->
                <layer name="skin_btn_show" type="container" bgcapture="true" align="bottom" width="100%" height="get:skin_settings.controlbar_height" y="calc:skin_settings.controlbar_height - skin_settings.controlbar_offset_closed" onclick="skin_showskin()" onhover="tween(alpha,1.0);" onout="tween(alpha,0.25);" ondown.touch="onhover();" onup.touch="onout();" visible="false" capture="false" alpha="0.0">
                    <layer name="skin_btn_show_icon" style="skin_base" crop="64|448|64|64" scale="0.5" align="bottom" y="2" enabled="false" />
                </layer>
                <!-- 下一个场景按钮 -->
                <layer name="skin_btn_next"      style="skin_base|skin_glow" crop="64|64|64|64"  align="right"       x="5"    y="0"   scale="0.5" alpha="0.5"  onclick="if(skin_settings.thumbs_loop, skin_nextscene_loop(+1), skin_nextscene(+1) );" />
                </layer>
            </layer>
        <!-- 显示加载中文字图层 -->
        <layer name="skin_loadingtext" url="%SWFPATH%/plugins/textfield.swf" align="center" x="5" y="-5" html="get:skin_settings.loadingtext" visible="false" autoheight="true" background="false" border="false" enabled="false" css="calc:skin_settings.design_text_css + ' text-align:center; font-style:italic; font-size:22px;'" textshadow="get:skin_settings.design_text_shadow" />
        <!-- 发光的背景图片,用于按钮点击效果 -->
        <layer name="skin_buttonglow"  style="skin_base" crop="64|384|64|64" align="center" x="0" y="1" scale="1.0" alpha="0.0" visible="false" enabled="false" />
        <!-- 缩略图选择边框效果 -->
        <layer name="skin_thumbborder" type="container" x="get:skin_settings.design_thumbborder_padding" y="get:skin_settings.design_thumbborder_padding" width="calc:skin_settings.thumbs_width - 2*skin_settings.design_thumbborder_padding" height="calc:skin_settings.thumbs_height - 2*skin_settings.design_thumbborder_padding" visible="false" enabled="false" align="lefttop" bgborder="get:skin_settings.design_thumbborder_bgborder" bgroundedge="get:skin_settings.design_thumbborder_bgroundedge" />
    </layer>
 
    <!-- previous/next scene buttons for the hidden skin mode -->
    <!-- 隐藏控制条时显示的用于场景切换的按钮 -->
    <layer name="skin_btn_prev_fs" keep="true" type="container" align="lefttop"  x="-50" width="40" height="100%" bgcapture="true" alpha="0.25" capture="false" zorder="2" onclick="skin_nextscene_loop(-1);" onhover="tween(alpha,1.0);" onout="tween(alpha,0.25);" ondown.touch="onhover();" onup.touch="onout();">
        <layer name="skin_btn_prev_fs_icon" style="skin_base" crop="0|64|64|64"  align="center" scale="0.5" enabled="false" />
    </layer>
    <layer name="skin_btn_next_fs" keep="true" type="container" align="righttop" x="-50" width="40" height="100%" bgcapture="true" alpha="0.25" capture="false" zorder="2" onclick="skin_nextscene_loop(+1);" onhover="tween(alpha,1.0);" onout="tween(alpha,0.25);" ondown.touch="onhover();" onup.touch="onout();">
        <layer name="skin_btn_next_fs_icon" style="skin_base" crop="64|64|64|64" align="center" scale="0.5" enabled="false" />
    </layer>
 
 
    <!-- gyro plugin -->
    <!-- 陀螺仪插件 -->
    <plugin name="skin_gyro" keep="true" url="" html5_url="%SWFPATH%/plugins/gyro2.js" softstart="1.0" enabled="false" onavailable="skin_arrange_buttons();" devices="html5" />
 
 
    <!-- skin events -->
    <!-- 皮肤的事件
    onxmlcomplete XML加载完成后清除当前事件,调用第一个函数skin_startup
    onnewpano 加载新场景时skin_showloading显示加载中文字 skin_update_scene_infos 根据URL重新设定初始位置等信息
    onloadcomplete 加载完成后隐藏加载中文字
    onidle 空闲时执行URL的信息更新
    onresize 屏幕尺寸变化时执行一次skin_onresize,当每次加载新的pano时onresize也会被触发一次
    onenterfullscreen onexitfullscreen 进入退出全屏时更新全屏按钮的图标
    onkeydown 监听键盘事件-->
    <events name="skin_events" keep="true"
            onxmlcomplete="set(events[skin_events].onxmlcomplete,null); skin_startup();"
            onnewpano="skin_showloading(true); skin_update_scene_infos(); skin_deeplinking_update_url();"
            onremovepano="skin_showloading(true);"
            onloadcomplete="skin_showloading(false);"
            onidle="skin_deeplinking_update_url();"
            onresize="skin_onresize();"
            onenterfullscreen.fullscreensupport="set(layer[skin_btn_fs].crop, '64|576|64|64');"
            onexitfullscreen.fullscreensupport="set(layer[skin_btn_fs].crop, '0|576|64|64');"
            onkeydown="skin_keydown_event();"
            />
 
 
    <!-- skin actions -->
    <!-- 当前皮肤的启动函数 -->
    <action name="skin_startup">
 
        <!-- apply skin settings on startup -->
        <!-- 根据设置确定缩略图是否在打开时就显示,并且设定是否可拖拽,鼠标的情况下设置为滚动 -->
        if(skin_settings.thumbs,
            if(skin_settings.thumbs_opened, set(layer[skin_thumbs].state,'opened'); set(layer[skin_thumbs_container].visible,true); );
            copy(layer[skin_thumbs].draggable, skin_settings.thumbs_dragging);
            if(skin_settings.thumbs_onhoverscrolling AND device.mouse,
                set(layer[skin_thumbs].draggable, false);
                set(layer[skin_thumbs].onhover_autoscrolling, true);
              );
          );
        <!-- html5的情况下加载陀螺仪插件 -->
        if(skin_settings.gyro AND !device.desktop AND device.html5,
            copy(plugin[skin_gyro].url, plugin[skin_gyro].html5_url);
          );
        <!-- html5并且支持WebVR的情况下加载WebVR插件 -->
        if(skin_settings.webvr AND device.html5 AND device.webgl,
            copy(plugin[WebVR].url, plugin[WebVR].pluginurl);
          );
        <!-- 是否显示地图插件 -->
        if(skin_settings.maps == true,
            set(layer[skin_btn_map].visible, true);
 
            if(device.flash,
                copy(layer[skin_map].key, skin_settings.maps_bing_api_key);
                set(layer[skin_map].url, '%SWFPATH%/plugins/bingmaps.swf');
              ,
                if(skin_settings.maps_type == 'bing',
                    copy(layer[skin_map].key, skin_settings.maps_bing_api_key);
                    set(layer[skin_map].url, '%SWFPATH%/plugins/bingmaps.js');
                  ,
                    copy(layer[skin_map].key, skin_settings.maps_google_api_key);
                    set(layer[skin_map].url, '%SWFPATH%/plugins/googlemaps.js');
                  );
              );
          );
        <!-- 小行星入场方式,只有支持WebGL和flash的情况下才可以 -->
        if(skin_settings.littleplanetintro AND (device.webgl OR device.flash),
            skin_setup_littleplanetintro();
          );
        <!-- 增加缩略图 -->
        skin_addthumbs();
        <!-- 调用onresize -->
        skin_onresize();
        <!-- skin_updatescroll -->
        skin_updatescroll();
        <!-- 显示下方控制条 -->
        set(layer[skin_layer].visible, true);
    </action>
 
    <!-- 增加缩略图 -->
    <action name="skin_addthumbs">
        if(skin_settings.thumbs == false,
            set(layer[skin_btn_thumbs].visible,false);
          ,
            copy(thumbwidth, skin_settings.thumbs_width);
            copy(thumbheight, skin_settings.thumbs_height);
            copy(thumbpadding, skin_settings.thumbs_padding);
            copy(thumbcrop, skin_settings.thumbs_crop);
 
            add(thumbxoffset, thumbwidth, thumbpadding);
            mul(thumbxcenter, thumbxoffset, 0.5);
            mul(thumbbarwidth, thumbxoffset, scene.count);
            add(thumbbarwidth, thumbpadding);
            add(thumbbarheight, thumbpadding, thumbheight);
            add(thumbbarheight, thumbpadding);
 
            if(skin_settings.thumbs_scrollindicator,
                copy(layer[skin_thumbs_scrollindicator].y, thumbbarheight);
                add(thumbbarheight, layer[skin_thumbs_scrollindicator].height);
            );
 
            copy(layer[skin_thumbs].height, thumbbarheight);
            copy(layer[skin_thumbs].width, thumbbarwidth);
 
            mul(halfheight, thumbbarheight, 0.5);
            copy(layer[skin_thumbs_scrollleft].y, halfheight);
            copy(layer[skin_thumbs_scrollright].y, halfheight);
            <!-- 遍历所有scene并且根据序号设置缩略图名称,并且根据设置添加缩略图文字 -->
            set(thumb_cnt,0);
            for(set(i,0), i LT scene.count, inc(i),
                inc(thumb_cnt);
                txtadd(thumbname,'skin_thumb_',get(i));
                addlayer(get(thumbname));
                copy(layer[get(thumbname)].url, scene[get(i)].thumburl);
                set(layer[get(thumbname)].keep, true);
                set(layer[get(thumbname)].parent, 'skin_thumbs');
                set(layer[get(thumbname)].align, lefttop);
                copy(layer[get(thumbname)].crop, thumbcrop);
                copy(layer[get(thumbname)].width, thumbwidth);
                copy(layer[get(thumbname)].height, thumbheight);
                mul(thumbx, i, thumbxoffset);
                add(thumbx, thumbpadding);
                copy(layer[get(thumbname)].x, thumbx);
                copy(layer[get(thumbname)].y, thumbpadding);
                add(scene[get(i)].thumbx, thumbx, thumbxcenter);
                copy(scene[get(i)].thumby, thumbpadding);
                set(layer[get(thumbname)].linkedscene, get(scene[get(i)].name) );
                set(layer[get(thumbname)].onclick, copy(layer[skin_thumbborder].parent, name); skin_loadscene(get(linkedscene),get(skin_settings.loadscene_blend)); );
                if(skin_settings.tooltips_thumbs,
                    set(layer[get(thumbname)].tooltip, get(scene[get(i)].title) );
                    layer[get(thumbname)].loadstyle(skin_tooltips);
                  );
                if(skin_settings.thumbs_text,
                    txtadd(thumbtext, 'skin_thumbtext_', get(i));
                    addlayer(get(thumbtext));
                    layer[get(thumbtext)].loadstyle(skin_thumbtext_style);
                    set(layer[get(thumbtext)].keep, true);
                    set(layer[get(thumbtext)].parent, get(thumbname));
                    set(layer[get(thumbtext)].html, get(scene[get(i)].title));
                  );
               );
 
            if(thumb_cnt == 1,
                set(layer[skin_thumbs].align, 'lefttop');
              );
          );
    </action>
 
    <!-- 设置地图热点 -->
    <action name="skin_addmapspots">
        for(set(i,0), i LT scene.count, inc(i),
            if(scene[get(i)].lat,
                txtadd(spotname, 'spot', get(i));
                txtadd(spotclickevent, 'skin_hidetooltips(); activatespot(',get(spotname),'); skin_loadscene(', get(scene[get(i)].name), ',get(skin_settings.loadscene_blend)); skin_updatescroll(); delayedcall(0.5,skin_showmap(false));');
                copy(scene[get(i)].mapspotname, spotname);
                addspot(get(spotname), get(scene[get(i)].lat), get(scene[get(i)].lng), get(scene[get(i)].heading), false, get(spotclickevent), null);
                if(skin_settings.tooltips_mapspots,
                    set(layer[skin_map].spot[get(spotname)].tooltip, get(scene[get(i)].title) );
                    txtadd(layer[skin_map].spot[get(spotname)].onover, 'set(hovering,true);',  get(style[skin_tooltips].onover) );
                    txtadd(layer[skin_map].spot[get(spotname)].onout,  'set(hovering,false);', get(style[skin_tooltips].onout)  );
                  );
              );
          );
 
        if(xml.scene != null,
            activatespot( get(scene[get(xml.scene)].mapspotname) );
          ,
            activatespot(spot0);
          );
 
        <!-- zoom and pan the map to see all spots at the same time -->
        zoomToSpotsExtent();
    </action>
 
    <!-- 小行星入场方式 -->
    <action name="skin_setup_littleplanetintro">
        copy(lp_scene, xml.scene);
        copy(lp_hlookat, view.hlookat);
        copy(lp_vlookat, view.vlookat);
        copy(lp_fov, view.fov);
        copy(lp_fovmax, view.fovmax);
        copy(lp_limitview, view.limitview);
        set(view.fovmax, 170);
        set(view.limitview, lookto);
        set(view.vlookatmin, 90);
        set(view.vlookatmax, 90);
        lookat(calc(lp_hlookat - 180), 90, 150, 1, 0, 0);
        set(events[lp_events].onloadcomplete,
            delayedcall(0.5,
                if(lp_scene === xml.scene,
                    set(control.usercontrol, off);
                    copy(view.limitview, lp_limitview);
                    set(view.vlookatmin, null);
                    set(view.vlookatmax, null);
                    tween(view.hlookat|view.vlookat|view.fov|view.distortion, calc('' + lp_hlookat + '|' + lp_vlookat + '|' + lp_fov + '|' + 0.0),
                        3.0, easeOutQuad,
                        set(control.usercontrol, all);
                        tween(view.fovmax, get(lp_fovmax));
                        );
                  );
              );
          );
    </action>
 
    <!-- 跳转到指定的视角,VR模式下要同时更新切换热点的位置 -->
    <action name="skin_lookat">
        if(webvr.isenabled,
            <!-- adjust the VR prev/next hotspots for the view change -->
            calc(hlookat_offset, %1 - view.hlookat);
            add(hotspot[webvr_prev_scene].ath, hlookat_offset);
            add(hotspot[webvr_next_scene].ath, hlookat_offset);
          );
        if(plugin[skin_gyro].enabled,
            <!-- reset the gyro tracking -->
            plugin[skin_gyro].resetsensor(%1);
          );
        <!-- change the view -->
        lookat(%1, %2, %3);
    </action>
 
    <!-- 皮肤重置位置 -->
    <action name="skin_onresize">
        mul(mh, area.pixelheight, -1);
        if(layer[skin_thumbs].state == 'opened', add(mh,layer[skin_thumbs].height); );
        if(layer[skin_map].state    == 'opened', sub(hh,area.pixelheight,skin_settings.controlbar_offset); sub(hh,layer[skin_control_bar].height); sub(hh,32); add(mh,hh); add(mh,skin_settings.controlbar_overlap); sub(mh, layer[skin_scroll_layer].y_offset); copy(layer[skin_map].height, hh); );
        add(mh, layer[skin_scroll_layer].y_offset);
        set(layer[skin_scroll_layer].y, get(mh));
        skin_video_updateseekbarwidth();
        skin_arrange_buttons();
    </action>
 
 
    <!-- determine the visibility of the buttons and calculate their positions -->
    <!-- 判断是否显示按钮并且计算他们的位置 -->
    <action name="skin_arrange_buttons">
        <!-- 通过场景树是否大于1确定是否显示场景切换按钮 -->
        calc(show_selbuttons, scene.count GT 1);
        calc(show_thumbutton, skin_settings.thumbs == true);
        calc(show_mapbutton,  skin_settings.maps == true);
        calc(show_gyrobutton, plugin[skin_gyro].available == true AND (view.vlookatrange == 180 OR lp_scene === xml.scene));
        calc(show_vrbutton,   webvr.isavailable == true);
        calc(show_fsbutton,   device.fullscreensupport == true);
 
        set(lpos,6);
        set(cpos,0);
        if(show_gyrobutton, dec(cpos,20));
        if(show_vrbutton, dec(cpos,24));
        set(rpos,6);
        <!-- 非手机且展示宽度去除VR和陀螺仪按钮宽度后大于520时显示方向控制按钮 -->
        calc(show_dirbuttons, !device.mobile AND ((area.pixelwidth + 2*cpos) GT 520));
 
        copy(layer[skin_btn_navi].visible, show_dirbuttons);
 
        copy(layer[skin_btn_prev].visible, show_selbuttons);
        copy(layer[skin_btn_next].visible, show_selbuttons);
        if(show_selbuttons, inc(lpos,44); inc(rpos,44); );
 
        copy(layer[skin_btn_thumbs].visible, show_thumbutton);
        copy(layer[skin_btn_thumbs].x, lpos);
        if(show_thumbutton, inc(lpos,40));
 
        copy(layer[skin_btn_map].visible, show_mapbutton);
        copy(layer[skin_btn_map].x, lpos);
        if(show_mapbutton, inc(lpos,40));
        <!-- 如果贤惠方向控制按钮需要重新设置按钮的列方式 -->
        if(show_dirbuttons,
            copy(layer[skin_btn_navi].x, cpos);
            inc(cpos,140);
 
            set(layer[skin_btn_gyro].align, center);
            copy(layer[skin_btn_gyro].visible, show_gyrobutton);
            copy(layer[skin_btn_gyro].x, cpos);
            if(show_gyrobutton, inc(cpos,48));
 
            set(layer[skin_btn_vr].align, center);
            copy(layer[skin_btn_vr].visible, show_vrbutton);
            copy(layer[skin_btn_vr].x, cpos);
            if(show_vrbutton, inc(cpos,80));
          ,
            set(layer[skin_btn_gyro].align, left);
            copy(layer[skin_btn_gyro].visible, show_gyrobutton);
            copy(layer[skin_btn_gyro].x, lpos);
            if(show_gyrobutton, inc(lpos,40));
 
            set(layer[skin_btn_vr].align, left);
            copy(layer[skin_btn_vr].visible, show_vrbutton);
            copy(layer[skin_btn_vr].x, lpos);
            if(show_vrbutton, inc(lpos,80));
          );
 
        copy(layer[skin_btn_hide].x, rpos);
        inc(rpos,40);
 
        copy(layer[skin_btn_fs].visible, show_fsbutton);
        copy(layer[skin_btn_fs].x, rpos);
        if(show_fsbutton, inc(rpos,40));
    </action>
 
    <!-- 将当前的scene缩略图设置到正中央 -->
    <action name="skin_updatescroll">
        if(layer[skin_thumbs].loaded,
            set(cursceneindex, 0);
            if(xml.scene, copy(cursceneindex, scene[get(xml.scene)].index));
            layer[skin_thumbs].setcenter(get(scene[get(cursceneindex)].thumbx), get(scene[get(cursceneindex)].thumby));
          );
    </action>
 
    <!-- 更新滑动组件 -->
    <action name="skin_updatethumbscroll">
        copy(padding,skin_settings.thumbs_padding);
 
        if(skin_settings.thumbs_scrollbuttons,
            if(loverflow GT 0, set(layer[skin_thumbs_scrollleft].visible,true),  set(layer[skin_thumbs_scrollleft].visible,false) );
            if(roverflow GT 0, set(layer[skin_thumbs_scrollright].visible,true), set(layer[skin_thumbs_scrollright].visible,false) );
          );
 
        if(skin_settings.thumbs_scrollindicator,
            if(woverflow GT 0,
                set(layer[skin_thumbs_scrollindicator].visible,true);
                sub(iw,pixelwidth,woverflow);
                div(pw,iw,pixelwidth);
                div(px,loverflow,woverflow);
                mul(pw,iw);
                copy(layer[skin_thumbs_scrollindicator].width,pw);
                sub(iw,pw);
                sub(iw,padding);
                sub(iw,padding);
                mul(px,iw);
                add(px,padding);
                copy(layer[skin_thumbs_scrollindicator].x,px);
              ,
                set(layer[skin_thumbs_scrollindicator].visible,false);
              );
          );
    </action>
 
    <!-- 更新场景信息 -->
    <action name="skin_update_scene_infos">
        if(xml.scene !== null AND scene[get(xml.scene)].index GE 0,
            <!-- 设置场景名称 -->
            if(skin_settings.title,
                if(title, txtadd(layer[skin_title].html, get(title), ' - ', get(scene[get(xml.scene)].title) ); , copy(layer[skin_title].html, scene[get(xml.scene)].title ); );
                delayedcall(0.1, set(layer[skin_title].visible,true) );
              );
            <!-- 如果不循环根据当前场景的序号设置切换按钮显示 -->
            if(skin_settings.thumbs_loop == false,
                if(scene[get(xml.scene)].index GT 0,
                    set(layer[skin_btn_prev].enabled, true);
                    set(layer[skin_btn_prev].alpha, 1.0);
                  ,
                    set(layer[skin_btn_prev].enabled, false);
                    set(layer[skin_btn_prev].alpha, 0.3);
                  );
 
                sub(lastsceneindex, scene.count, 1);
                if(scene[get(xml.scene)].index LT lastsceneindex,
                    set(layer[skin_btn_next].enabled, true);
                    set(layer[skin_btn_next].alpha, 1.0);
                  ,
                    set(layer[skin_btn_next].enabled, false);
                    set(layer[skin_btn_next].alpha, 0.3);
                  );
              ,
                if(scene.count GT 1,
                    set(layer[skin_btn_prev].enabled, true);
                    set(layer[skin_btn_prev].alpha, 1.0);
                    set(layer[skin_btn_next].enabled, true);
                    set(layer[skin_btn_next].alpha, 1.0);
                  ,
                    set(layer[skin_btn_prev].enabled, false);
                    set(layer[skin_btn_prev].alpha, 0.3);
                    set(layer[skin_btn_next].enabled, false);
                    set(layer[skin_btn_next].alpha, 0.3);
                  );
              );
 
            if(scene.count GT 1,
                set(layer[skin_btn_prev_fs].visible, true);
                set(layer[skin_btn_next_fs].visible, true);
              ,
                set(layer[skin_btn_prev_fs].visible, false);
                set(layer[skin_btn_next_fs].visible, false);
              );
            <!-- 设置当前场景的缩略图为选中式样 -->
            txtadd(parentname, 'skin_thumb_', get(scene[get(xml.scene)].index));
            if(layer[get(parentname)],
                set(layer[skin_thumbborder].parent, get(parentname));
                set(layer[skin_thumbborder].visible, true);
              ,
                set(layer[skin_thumbborder].visible, false);
              );
 
            if(scene[get(xml.scene)].mapspotname,
                layer[skin_map].activatespot(get(scene[get(xml.scene)].mapspotname));
                layer[skin_map].pantospot(get(scene[get(xml.scene)].mapspotname));
              );
            <!-- 设置陀螺仪按钮是否显示 -->
            if(plugin[skin_gyro].isavailable == true AND view.vlookatrange == 180,
                set(layer[skin_btn_gyro].visible, true);
              ,
                set(layer[skin_btn_gyro].visible, false)
              );
            <!-- 设置反弹效果 -->
            if(view.vlookatrange LT 180,
                if(backup_control_bouncinglimits === null,
                    copy(backup_control_bouncinglimits, control.bouncinglimits);
                  );
                set(control.bouncinglimits, false);
              ,
                if(backup_control_bouncinglimits !== null,
                    copy(control.bouncinglimits, backup_control_bouncinglimits);
                  );
              );
            <!-- 如果当前场景为视频则加载视频控制条 -->
            if(scene[get(xml.scene)].isvideopano AND plugin

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
!== null,
                skin_video_addcontrols();
              ,
                skin_video_removecontrols();
              );
          );
    </action>
 
    <!-- 跳转到某一指定scene 参数为scene的序号-->
    <action name="skin_gotoscene">
        if(scene[%1],
            copy(cursceneindex, scene[get(xml.scene)].index);
            copy(newsceneindex, scene[%1].index);
            skin_loadscene(get(newsceneindex), calc(newsceneindex LT cursceneindex ? skin_settings.loadscene_blend_prev : (newsceneindex GT cursceneindex ? skin_settings.loadscene_blend_next : skin_settings.loadscene_blend)) );
          );
    </action>
 
 
    <!-- 显示下一个场景(不循环) -->
    <action name="skin_nextscene">
        add(newsceneindex, scene[get(xml.scene)].index, %1);
        if(newsceneindex GE 0 AND newsceneindex LT scene.count,
            skin_loadscene(get(newsceneindex), calc(%1 LT 0 ? skin_settings.loadscene_blend_prev : skin_settings.loadscene_blend_next));
          );
    </action>
 
    <!-- 显示下一个场景(循环) -->
    <action name="skin_nextscene_loop">
        add(newsceneindex, scene[get(xml.scene)].index, %1);
        sub(lastsceneindex, scene.count, 1);
        if(newsceneindex LT 0, copy(newsceneindex,lastsceneindex));
        if(newsceneindex GT lastsceneindex, set(newsceneindex,0));
        skin_loadscene(get(newsceneindex), calc(%1 LT 0 ? skin_settings.loadscene_blend_prev : skin_settings.loadscene_blend_next));
    </action>
 
 
    <!-- skin_loadscene(scenenameorindex, blendmode) -->
    <!-- 加载场景如果只有一个场景就WebVR的按钮隐藏,并且在场景缩略图上加上边框效果,blendmode为场景切换动画 -->
    <action name="skin_loadscene">
        if(webvr.isenabled AND scene.count GT 1,
            set(hotspot[webvr_prev_scene].visible, false);
            set(hotspot[webvr_next_scene].visible, false);
          );
 
        txtadd(layer[skin_thumbborder].parent, 'skin_thumb_', get(scene[%1].index));
        layer[skin_thumbs].scrolltocenter(get(scene[%1].thumbx), get(scene[%1].thumby));
        loadscene(get(scene[%1].name), null, get(skin_settings.loadscene_flags), %2);
    </action>
 
    <!-- 加载文字是否显示 -->
    <action name="skin_showloading">
        if(display.stereo == true,
            set(layer[skin_loadingtext].visible, false);
          ,
            set(layer[skin_loadingtext].visible, %1);
          );
    </action>
 
 
    <!-- 隐藏tips -->
    <action name="skin_hidetooltips">
        set(layer[skin_tooltip].alpha,0.0);
        set(layer[skin_tooltip].visible,false);
    </action>
 
    <!-- 按钮的点击效果,在点击的按钮下添加一个Child -->
    <action name="skin_buttonglow">
        if('%1' !== 'null',
            set(strength,0.7);
            if(%2 != null, set(strength,%2));
            set(layer[skin_buttonglow].parent, %1);
            set(layer[skin_buttonglow].visible, true);
            tween(layer[skin_buttonglow].alpha, get(strength), 0.07);
          ,
            tween(layer[skin_buttonglow].alpha, 0.0, 0.1, default,
                set(layer[skin_buttonglow].parent, null);
                set(layer[skin_buttonglow].visible, false);
              );
          );
    </action>
 
    <!-- 设置关闭打开的距离 -->
    <action name="skin_calc_opened_closed">
        if(layer[get(name)].y_closed === null,
            set(layer[get(name)].y_opened, get(layer[get(name)].y));
            set(layer[get(name)].y_closed, calc(layer[get(name)].y - skin_settings.controlbar_offset - skin_settings.controlbar_height + skin_settings.controlbar_offset_closed));
          );
    </action>
 
    <!-- 隐藏控制条,首先隐藏上方布局,其次底部最后控制条 -->
    <action name="skin_hideskin">
        callwith(layer[skin_scroll_window],   skin_calc_opened_closed() );
        callwith(layer[skin_splitter_bottom], skin_calc_opened_closed() );
        callwith(layer[skin_control_bar],     skin_calc_opened_closed() );
 
        if(layer[skin_map].state    != 'closed', skin_showmap(false);    wait(0.40); );
        if(layer[skin_thumbs].state != 'closed', skin_showthumbs(false); wait(0.25); );
 
        set(hidetime, calc('%1' == 'instant' ? 0.0 : 0.5));
        tween(layer[skin_scroll_window].y,   get(layer[skin_scroll_window  ].y_closed), get(hidetime));
        tween(layer[skin_splitter_bottom].y, get(layer[skin_splitter_bottom].y_closed), get(hidetime));
        tween(layer[skin_control_bar].y,     get(layer[skin_control_bar    ].y_closed), get(hidetime));
 
        tween(layer[skin_btn_prev_fs].x, 0, get(hidetime));
        tween(layer[skin_btn_next_fs].x, 0, get(hidetime));
 
        if(layer[skin_logo], tween(layer[skin_logo].alpha, 0.0, 0.5, default, set(layer[skin_logo].visible,false)); );
 
        stopdelayedcall(skin_btn_show_alpha);
        set(layer[skin_btn_show].visible, true);
        delayedcall(skin_btn_show_alpha, get(hidetime), tween(layer[skin_btn_show].alpha, 0.25, 0.25); );
    </action>
 
    <!-- 显示隐藏的控制条 -->
    <action name="skin_showskin">
        tween(layer[skin_scroll_window  ].y, get(layer[skin_scroll_window  ].y_opened));
        tween(layer[skin_splitter_bottom].y, get(layer[skin_splitter_bottom].y_opened));
        tween(layer[skin_control_bar    ].y, get(layer[skin_control_bar    ].y_opened));
 
        tween(layer[skin_btn_prev_fs].x, -50);
        tween(layer[skin_btn_next_fs].x, -50);
 
        if(layer[skin_logo], set(layer[skin_logo].visible,true); tween(layer[skin_logo].alpha, 1.0); );
 
        stopdelayedcall(skin_btn_show_alpha);
        set(layer[skin_btn_show].visible, false);
        delayedcall(skin_btn_show_alpha, 0.25, tween(layer[skin_btn_show].alpha, 0.0, 0.0); );
    </action>
 
    <!-- 显示缩略图, 首先判断是否已经关闭,layer[skin_scroll_layer].pixelheight=area.pixelheight的值为当前窗口的高度
    假设当前窗口高度为640 1.640*-1=-640 2.减去(layer[skin_thumbs].height)缩略图的高度100 -640+100=-540 3.减去(y_offset)背景重叠区域大小 10 -540+10=-530
    4. layer[skin_scroll_layer].y大小为负的area.pixelheight+y_offset一开始onresize时设定 则变化范围为 -630 到-530
    详细参照http://krpano.com/docu/xml/pluginalignment.png这张图,备注下对于xy属性,默认向下为Y的正向向右为X 的正向,edge未设定时默认和align一个值-->
    <action name="skin_showthumbs">
        if(%1 == null, if(layer[skin_thumbs].state == 'closed', set(show,true), set(show,false)); , set(show,%1); );
        mul(mh, layer[skin_scroll_layer].pixelheight, -1);
 
        if(show,
            set(layer[skin_thumbs].state, 'opened');
            tween(layer[skin_thumbs].alpha, 1.0, 0.25);
            add(mh, layer[skin_thumbs].height);
            add(mh, layer[skin_scroll_layer].y_offset);
            tween(layer[skin_scroll_layer].y, get(mh), 0.5, easeOutQuint);
            set(layer[skin_thumbs_container].visible, true);
            tween(layer[skin_thumbs_container].alpha, 1.0, 0.25);
            tween(layer[skin_map].alpha, 0.0, 0.25, default, set(layer[skin_map].visible,false));
          ,
            set(layer[skin_thumbs].state, 'closed');
            tween(layer[skin_thumbs].alpha, 0.0, 0.25, easeOutQuint);
            add(mh, layer[skin_scroll_layer].y_offset);
            tween(layer[skin_scroll_layer].y, get(mh), 0.5, easeOutQuint, set(layer[skin_thumbs_container].visible, false););
          );
    </action>
 
    <!-- 显示地图 -->
    <action name="skin_showmap">
        if(%1 == null, if(layer[skin_map].state == 'closed', set(show,true), set(show,false)); , set(show,%1); );
        mul(mh, layer[skin_scroll_layer].pixelheight, -1);
        if(show,
            tween(layer[skin_thumbs_container].alpha, 0.0, 0.25, default, set(layer[skin_thumbs_container].visible,false));
            set(layer[skin_map].visible, true);
            tween(layer[skin_map].alpha, 1.0, 0.25);
            set(layer[skin_map].state, 'opened');
            sub(hh,area.pixelheight,skin_settings.controlbar_offset);
            sub(hh,layer[skin_control_bar].height);
            sub(hh,32);
            add(mh,hh);
            sub(hh,skin_settings.controlbar_overlap);
            copy(layer[skin_map].height, hh);
            tween(layer[skin_scroll_layer].y, get(mh), 0.5, easeOutQuint);
          ,
            if(layer[skin_map].state != 'closed',
                set(layer[skin_map].state, 'closed');
                add(mh, layer[skin_scroll_layer].y_offset);
                tween(layer[skin_map].alpha, 0.0, 0.5, easeOutQuint);
                tween(layer[skin_scroll_layer].y, get(mh), 0.5, easeOutQuint, set(layer[skin_map].visible,false) );
              );
          );
    </action>
 
    <!-- 绑定键盘事件 -->
    <action name="skin_keydown_event">
        if(keycode == 33, skin_nextscene_loop(-1) );                <!-- Page Up   - previous scene -->
        if(keycode == 34, skin_nextscene_loop(+1) );                <!-- Page Dowm - next scene -->
        if(keycode == 35, skin_gotoscene(calc(scene.count-1)) );    <!-- End       - last scene -->
        if(keycode == 36, skin_gotoscene(0) );                      <!-- Home/Pos1 - first scene -->
    </action>
 
    <!-- 如果使用深度链接功能调用skin_deeplinking_update_url_process获取链接参数并设置 -->
    <action name="skin_deeplinking_update_url">
        if(skin_settings.deeplinking AND (!webvr OR webvr.isenabled === false),
            delayedcall(skin_deeplinking_update, calc(%1 == null ? 0.1 : %1), skin_deeplinking_update_url_process() );
          );
    </action>
    <!-- 深度链接功能,通过URL传递场景的初始位置等信息,重新设定到新的场景上 -->
    <action name="skin_deeplinking_update_url_process">
        <!-- 获取当前的URL -->
        copy(adr, browser.location);
        <!-- 获取?后的参数信息 -->
        indexoftxt(qi, get(adr), '?');
        if(qi GT 0, subtxt(adr, adr, 0, get(qi)));
        copy(si, scene[get(xml.scene)].index);
        copy(h, view.hlookat);
        copy(v, view.vlookat);
        copy(f, view.fov);
        copy(d, view.distortion);
        copy(a, view.architectural);
        clamp(d, 0.0, 1.0);
        clamp(a, 0.0, 1.0);
        set(pp, calc(f LT 10 ? 6 : 2));
        roundval(h, get(pp));
        roundval(v, get(pp));
        roundval(f, get(pp));
        roundval(d, 2);
        roundval(a, 1);
        set(adr, calc(adr + '?startscene=' + si + '&amp;startactions=lookat('+h+','+v+','+f+','+d+','+a+');'));
        js( history.replaceState(null, document.title, get(adr)); );
    </action>
 
 
    <!-- reload the scene when there is a special image for VR -->
    <!-- 如果scene标签有havevrimage属性,进入VR重载界面 -->
    <action name="skin_reloadscene_webvr">
        delayedcall(0.1,
            if(scene[get(xml.scene)].havevrimage,
                copy(keeplookingdirection_backup, skin_settings.webvr_gyro_keeplookingdirection);
                set(skin_settings.webvr_gyro_keeplookingdirection, true);
                loadscene(get(xml.scene), null, MERGE|KEEPVIEW|KEEPMOVING|KEEPHOTSPOTS|NOPREVIEW, BLEND(0.5));
                copy(skin_settings.webvr_gyro_keeplookingdirection, keeplookingdirection_backup);
                delete(keeplookingdirection_backup);
              );
          );
    </action>
 
 
    <!-- videopano support - http://krpano.com/plugins/videoplayer/ -->
    <!-- 加载视频控制条 -->
    <action name="skin_video_addcontrols">
        set(events[skin_events].onclick, skin_video_clickevent() );
 
        set(plugin

1
2
.onvideoready, skin_video_updatestate() );
        set(plugin

1
2
.onvideoplay, skin_video_updatestate() );
        set(plugin

1
2
.onvideopaused, skin_video_updatestate() );
        set(plugin

1
2
3
.onvideocomplete, skin_video_updatestate() );
 
        if(plugin

1
.ispaused AND plugin

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
.pausedonstart,
            set(layer[skin_video_playpause].state, 'visible');
            set(layer[skin_video_playpause].enabled, true);
            tween(layer[skin_video_playpause].alpha, 1.0);
          );
 
        delayedcall(skin_video_delayedvisible, 0.25, set(layer[skin_video_controls].visible, true) );
 
        skin_video_updateseekbarwidth();
        set(layer[skin_video_seekpos].x,0);
        set(layer[skin_video_loadbar].width,0);
 
        setinterval(skin_video_seek_updates, 0.5, skin_video_updatetime() );
    </action>
    <!-- 去除视频控制条 -->
    <action name="skin_video_removecontrols">
        stopdelayedcall(skin_video_delayedvisible);
 
        set(events[skin_events].onclick, null);
 
        set(layer[skin_video_playpause].alpha, 0.0);
        set(layer[skin_video_controls].visible, false);
 
        clearinterval(skin_video_seek_updates);
    </action>
    <!-- 实时更新seek的进度和时间显示 -->
    <action name="skin_video_updatetime">
        copy(t1, plugin

1
2
.time);
        copy(t2, plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
.totaltime);
        if(%1 !== null, calc(t1, %1 * t2); );
        div(t1_min, t1, 60);
        mod(t1_sec, t1, 60);
        Math.floor(t1_min);
        Math.floor(t1_sec);
        div(t2_min, t2, 60);
        mod(t2_sec, t2, 60);
        Math.floor(t2_min);
        Math.floor(t2_sec);
        calc(layer[skin_video_time].html, t1_min + ':' + (t1_sec LT 10 ? '0' : '') + t1_sec + ' / ' + t2_min + ':' + (t2_sec LT 10 ? '0' : '') + t2_sec);
        calc(layer[skin_video_seekpos].x, (t1 / t2 * 100) + '%');
        calc(layer[skin_video_loadbar].width, (plugin

1
.loadedbytes / plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
.totalbytes * 100) + '%');
    </action>
    <!-- 更新视频进度空间的宽度 -->
    <action name="skin_video_updateseekbarwidth">
        if(skin_settings.title,
            calc(layer[skin_video_seekbar_container].width, 0 - (32 + layer[skin_title].pixelwidth + layer[skin_video_time].pixelwidth));
            calc(layer[skin_video_seekbar_container].x, layer[skin_title].pixelwidth + 16);
          ,
            calc(layer[skin_video_seekbar_container].width, 0 - (24 + layer[skin_video_time].pixelwidth));
            set(layer[skin_video_seekbar_container].x, 8);
          );
    </action>
    <!-- 跳转到指定的视频进度 -->
    <action name="skin_video_ondownseeking">
        asyncloop(pressed,
            screentolayer(skin_video_seekbar, mouse.stagex,mouse.stagey, lx,ly);
            calc(seekpos, lx / layer[skin_video_seekbar].pixelwidth);
            clamp(seekpos, 0.0, 1.0);
            skin_video_updatetime(seekpos);
          ,
            plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
.seek(calc((seekpos * 100) + '%'));
          );
    </action>
    <!-- 暂停或者显示时的图层 -->
    <layer name="skin_video_playpause" keep="true"
             style="skin_base|skin_glow" crop="0|640|64|64" scale="0.75"
             align="center" alpha="0.0" autoalpha="true"
             state="hidden"
             onclick="skin_video_playpause_click();"
             />
    <!-- 状态变更时更新 -->
    <action name="skin_video_updatestate">
        calc(layer[skin_video_playpause].crop, plugin

1
2
.ispaused ? '0|640|64|64' : '64|640|64|64');
        if(plugin

1
2
3
4
5
6
7
8
.iscomplete,
            set(layer[skin_video_playpause].state, 'visible');
            tween(layer[skin_video_playpause].alpha, 1.0);
          );
    </action>
    <!-- 点击暂停按钮 -->
    <action name="skin_video_playpause_click">
        if(plugin

1
2
.ispaused,
            plugin

1
2
3
4
5
.play();
            set(layer[skin_video_playpause].state, 'hidden');
            tween(layer[skin_video_playpause].alpha, 0.0);
          ,
            plugin

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
.pause();
            set(layer[skin_video_playpause].state, 'visible');
            tween(layer[skin_video_playpause].alpha, 1.0);
            delayedcall(autohide_pp, 2.0, set(layer[skin_video_playpause].state,'hidden'); tween(layer[skin_video_playpause].alpha, 0.0); );
          );
    </action>
    <!-- 点击屏幕的事件触发视频播放和暂停 -->
    <action name="skin_video_clickevent">
        stopdelayedcall(autohide_pp);
 
        switch(layer[skin_video_playpause].state, 'visible', 'hidden');
 
        if(layer[skin_video_playpause].state == 'hidden',
            tween(layer[skin_video_playpause].alpha, 0.0);
          ,
            tween(layer[skin_video_playpause].alpha, 1.0);
            delayedcall(autohide_pp, 2.0, set(layer[skin_video_playpause].state,'hidden'); tween(layer[skin_video_playpause].alpha, 0.0); );
          );
    </action>
 
 
    <!-- context menu - http://krpano.com/docu/xml/#contextmenu -->
    <!-- 右键按钮菜单 -->
    <contextmenu>
        <item name="kr" caption="Krpano" onclick="openurl('http://www.krpano.com',_blank);"/>
        <item name="fs" caption="FULLSCREEN" />
        <item name="cc" caption="Change Controlmode" onclick="skin_changecontrolmode();"  separator="true" />
        <item name="nv" caption="Normal View"        onclick="skin_view_normal();"        showif="view.vlookatrange == 180" separator="true"      />
        <item name="fv" caption="Fisheye View"       onclick="skin_view_fisheye();"       showif="view.vlookatrange == 180" devices="flash|webgl" />
        <item name="sv" caption="Stereographic View" onclick="skin_view_stereographic();" showif="view.vlookatrange == 180" devices="flash|webgl" />
        <item name="av" caption="Architectural View" onclick="skin_view_architectural();" showif="view.vlookatrange == 180"                       />
        <item name="pv" caption="Pannini View"       onclick="skin_view_pannini();"       showif="view.vlookatrange == 180" devices="flash|webgl" />
        <item name="lp" caption="Little Planet View" onclick="skin_view_littleplanet();"  showif="view.vlookatrange == 180" devices="flash|webgl" />
    </contextmenu>
 
    <!-- 点击改变控制方式函数 -->
    <action name="skin_changecontrolmode">
        switch(control.mouse, moveto, drag);
        switch(control.touch, moveto, drag);
    </action>
    <!-- 以下为不同的全景显示模式 -->
    <action name="skin_view_look_straight">
        if(view.vlookat LT -80 OR view.vlookat GT +80,
            tween(view.vlookat, 0.0, 1.0, easeInOutSine);
            tween(view.fov,     100, distance(150,0.8));
          );
        skin_deeplinking_update_url(1.0);
    </action>
 
    <action name="skin_view_normal">
        skin_view_look_straight();
        tween(view.architectural, 0.0, distance(1.0,0.5));
        tween(view.pannini,       0.0, distance(1.0,0.5));
        tween(view.distortion,    0.0, distance(1.0,0.5));
    </action>
 
    <action name="skin_view_fisheye">
        skin_view_look_straight();
        tween(view.architectural, 0.0,  distance(1.0,0.5));
        tween(view.pannini,       0.0,  distance(1.0,0.5));
        tween(view.distortion,    0.35, distance(1.0,0.5));
    </action>
 
    <action name="skin_view_architectural">
        skin_view_look_straight();
        tween(view.architectural, 1.0, distance(1.0,0.5));
        tween(view.pannini,       0.0, distance(1.0,0.5));
        tween(view.distortion,    0.0, distance(1.0,0.5));
    </action>
 
    <action name="skin_view_stereographic">
        skin_view_look_straight();
        tween(view.architectural, 0.0, distance(1.0,0.5));
        tween(view.pannini,       0.0, distance(1.0,0.5));
        tween(view.distortion,    1.0, distance(1.0,0.8));
    </action>
 
    <action name="skin_view_pannini">
        skin_view_look_straight();
        tween(view.architectural, 0.0, distance(1.0,0.5));
        tween(view.pannini,       1.0, distance(1.0,0.8));
        if(view.distortion LT 0.1,
            tween(view.distortion, 1.0, distance(1.0,0.8));
          );
    </action>
 
    <action name="skin_view_littleplanet">
        tween(view.architectural, 0.0, distance(1.0,0.5));
        tween(view.pannini,       0.0, distance(1.0,0.5));
        tween(view.distortion,    1.0, distance(1.0,0.8));
        tween(view.fov,           150, distance(150,0.8));
        tween(view.vlookat,        90, distance(100,0.8));
        add(new_hlookat, view.hlookat, 123.0);
        tween(view.hlookat, get(new_hlookat), distance(100,0.8));
        skin_deeplinking_update_url(1.0);
    </action>
 
</krpano>

 

Electron 生成的桌面应用破解方法

2017-10-10admin阅读(6479)评论(0)

网上找的方法,亲测可用!

这次我们以 720云 客户端为例~

下载720云客户端,然后使用压缩软件解压~

解压后,在 resources 目录找到 electron.asar 文件,

然后在同级目录新建一个文件夹 tmp,进行如下操作~!

  • 安装npm(至于如何安装,网上教程很多,不赘述)
  • 安装好npm后执行命令安装asar:npm install asar -g
  • 以macOS平台为例,在Prepros.app/Contents/Resources下找到app.asar,其他平台方法类似
  • 用asar命令解包:asar e app.asar tmp
  • 到步骤4中建立的tmp目录下找到对应的js文件hack之。
  • 破解完后重新封装程序 :asar p tmp/ app.asar。

然后在tmp 目录里,就是程序源代码了!

拿到源代码,开始好好学习一下!

110003

 

使用 Electron 打包桌面应用

2017-10-10admin阅读(2696)评论(0)

首先安装  electron-packager

npm install --save-dev electron-packager

新建三个文件,分别是: package.json, main.js ,index.html

package.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "name": "test",
  "version": "1.0.0",
  "description": "test",
  "main": "main.js",
  "author": "天明",
  "scripts": {
    "start": "electron .",
  },
  "devDependencies": {
    "electron-prebuilt": "^1.3.5",
    "electron-packager": "latest"
  }
}

main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const { app, BrowserWindow } = require('electron')
let win
function createWindow() {
    win = new BrowserWindow({ width: 800, height: 600 })
    win.loadURL(`file://${__dirname}/index.html`)
    win.webContents.openDevTools() //开启调试工具
    win.on('close', () => {
        win = null
    })
    win.on('resize', () => {
        win.reload()
    })
}
app.on('ready', createWindow)
app.on('window-all-cloased', () => {
    if (process.platform !== 'drawin') {
        app.quit()
    }
})
app.on('activate', () => {
    if (win === null) {
        createWindow()
    }
})

index.html

里面写入html代码啦~

完成后, npm install 安装依赖!

打包应用

electron-packager <location of project> <name of project> <platform> <architecture> <electron version><optional options>

我现在打包应用, 直接 electron-packager ./

λ ls -lh
total 70k
drwxr-xr-x 22 Administ Administ 4.0k Oct 9 09:31 channel-win32-x64/
-rw-r–r– 1 Administ Administ 4.2k Oct 9 09:21 favicon.ico
-rw-r–r– 1 Administ Administ 159 Oct 9 09:28 index.html
-rw-r–r– 1 Administ Administ 604 Oct 9 09:28 main.js
drwxr-xr-x 1 Administ Administ 128k Oct 9 09:29 node_modules/
-rw-r–r– 1 Administ Administ 383 Oct 9 09:36 package.json

生成的 channel-win32-x64/ 就是我们的桌面应用文件了!

打开: hello world

vue-cli 实现后台实时编译修改

2017-09-07admin阅读(4497)评论(0)

首先我们安装 https://github.com/remy/nodemon

Either through cloning with git or by using npm (the recommended way):

1
2
npm install -g nodemon
 

And nodemon will be installed globally to your system path.

It is also possible to install locally:

1
2
npm install --save-dev nodemon
 

With a local installation, nodemon will not be available in your system path. Instead, the local installation of nodemon can be run by calling it from within an npm script (such as npm start) or using npx nodemon.

安装完成后,打开 package.json, 加入:  “watch”: “nodemon –watch src -e html,vue,js,less build/build.js”,

1
2
3
4
5
6
7
8
9
"scripts": {
    "dev": "node build/dev-server.js",
    "watch": "nodemon --watch src -e html,vue,js,less build/build.js",
    "start": "node build/dev-server.js",
    "build": "node build/build.js",
    "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
    "e2e": "node test/e2e/runner.js",
    "test": "npm run unit && npm run e2e"
  },

然后我们启动: npm run watch

1
2
3
4
5
6
7
8
9
λ npm run watch
 
> start@1.0.0 watch C:\www\Aweb\vr29\public_html\start\app
> nodemon --watch src -e html,vue,js,less build/build.js
 
[nodemon] 1.12.0
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: C:\www\Aweb\vr29\public_html\start\app\src/**/*
[nodemon] starting `node build/build.js`

然后有修改就会自动编译了.

研究院 – vue单页应用 SEO设置(服务端渲染,非JS动态修改)

2017-08-10admin阅读(3746)评论(0)

上一篇讲了如果设置 history 模式,

这次来讲价怎么设置SEO信息,

首先,我们在php控制器里获取一下当前的url,

每次都可以获取到当前url,

然后我们根据URl不同,匹配不一样的配置文件即可!

php:

1
2
3
4
5
6
7
8
9
public function index(){
        if(isMobile2()){
            return view('./start/index.html');
        }else{
            $seo = makeSEO($_SERVER['REQUEST_URI']);
            $this->assign('seo',current($seo));
            return view('./index/index.html');
        }
    }

在载入模板之前,先分配seo信息过去,SEO信息来自一个配置文件

1
2
3
4
5
6
7
8
function makeSEO($path='/'){
    $data = require_once './config/seoConfig.php';
    return isset($data[$path])?$data[$path]:[
        'title'=>'移动云全景 - 带上全景去旅行',
        'keywords'=>'720全景制作',
        'description'=>'720全景制作',
    ];
}

这样我们每次都可以根据url的不同,获取不一样的seo数组,然后分配给index.html,

因为index.html是vue的文件,

vue的变量是 {{ xx }} ,当然与thinkphp繁荣模板引擎 {} 不冲突, 也就是我们可以向怎么使用php数据就可以使用哈~~

所以, 我的vue的index.html 就变成这样~~~

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>{$seo.title} - 360度全景拍摄,VR制作,全景旅游,全景新闻,全景图片,虚拟漫游,VR视频,VR全景旅游</title>
    <meta name="Generator" content="PHPSTORM®">
    <meta name="Author" content="@天明">
    <meta name="Keywords" content="{$seo.keywords}, 移动云全景, 移动全景拍摄,游戏全景,全景虚拟现实,720全景摄影,全景视频,全景相机,360度全景拍摄,VR制作,全景旅游,街景地图,全景新闻,全景图片,虚拟漫游,VR视频,VR航拍">
    <meta name="Description" content="{$seo.description},移动云全景平台,是一站式解决360度全景摄影、VR全景视频拍摄、VR空中全景航拍、3D虚拟现实制作,全景上传、分享、展示、漫游,以及创作者互动交流、VR供需交易的综合性移动端及PC共享互通的全景制作平台">
    <meta name="description" itemprop="description" content="{$seo.description}">
    <meta itemprop="name" content="{$seo.title} - 移动云全景 - 带上全景去旅行">
    <meta itemprop="image" content="http://vr.he29.com/static/logo.png"><!-- 图片 -->
</head>

如果启动vue项目

1
2
3
4
5
6
λ npm run dev
 
> test@1.0.0 dev C:\www\Aweb\vr29\public_html\index\app
> node build/dev-server.js
 
> Starting dev server...

你将在本地看到{$seo.title} 这样的标题, 当然这个无所谓啦~~

编译完成,上传服务器!

{$seo.title} 就会被php 模板引擎给编译 成 <?php echo $seo[‘title’]; >

用户看到的一切都是正常的,

当然你切换页面,如果你在配置文件定义了数据,则页面标题,关键词,描述什么的都会改变哈哈~`

成品效果,欢迎 百度 : 移动云全景  查看效果哈~

也可以这样~~~chongwutupian

研究院 – thinkphp配合vue history 模式 配置

2017-08-10admin阅读(6208)评论(0)

因为想做SEO优化,但是vue做的项目, 所有的地址后面都加了#/ ,所以想办法改成了 history ,并且成功生效!

首先, 编译vue项目后,入口是index.html~~,

我们thinkphp 新增一个控制器,来载入这个index.html模板,记得配置好vue路径!

比如我的vue 项目放在 /app/public/start/ 下面, 我编译完成后, 如果想直接访问到,

那我的所以资源地址必须是 域名/app/public/start/xxx.xx

好长好丑有木有!

于是,我就把项目编译到了根目录的某个文件夹,配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
build: {
    env: require('./prod.env'),
    index: path.resolve(__dirname, '../../index.html'), //主要是这里,
    assetsRoot: path.resolve(__dirname, '../../'), //还有这里
    assetsSubDirectory: 'static',
    assetsPublicPath: '/index/', //这里是资源地址目录
    productionSourceMap: true,
    // Gzip off by default as many popular static hosts such as
    // Surge or Netlify already gzip all static assets for you.
    // Before setting to `true`, make sure to:
    // npm install --save-dev compression-webpack-plugin
    productionGzip: false,
    productionGzipExtensions: ['js', 'css'],
    // Run the build command with an extra argument to
    // View the bundle analyzer report after build finishes:
    // `npm run build --report`
    // Set to `true` or `false` to always turn it on or off
    bundleAnalyzerReport: process.env.npm_config_report
  },

这样的话, 我编译到了根目录的index目录里, 所以我访问

xxx.he29.com/index/ 就能访问到项目,

接下来就该php出场了,

php 新增一个控制器来载入模板

1
2
3
4
5
6
7
8
9
10
11
12
public function index(){
        if(isMobile2()){
            // 手机模式载入这个
            return view('./start/index.html');
        }else{
            $seo = makeSEO($_SERVER['REQUEST_URI']);
             //暂时无视seo,下一篇再讲
            $this->assign('seo',current($seo));
           // 否则载入这个
            return view('./index/index.html');
        }
    }

载入后,访问控制器,应该能载入进来文件了,如果载入错误, 建议查看资源路劲是否正确,

但是我们的前端路由和php路由重合了,无法载入啦!!!

开始配置nginx,让我们所有访问 都定向到这个控制器!

1
2
3
4
5
6
7
8
9
10
11
# nginx rewrite rule
rewrite ^(.*?)/admin/$   $1/index.php/admin      break;
rewrite ^(.*?)/index/$   $1/index.php/index      break;
rewrite ^(.*?)/api/$     $1/index.php/api      break;
rewrite ^(.*?)/app/([a-zA-Z0-9_]+)$   $1/index/index.html      break;
rewrite ^(.*?)/tool/$   $1/index.php/tool      break;
rewrite ^(.*?)/category/.*?-(d+)-(d+).html$  $1/list.html?id=$2&page=$3      break;
rewrite ^(.*?)/tag/([^/]+)/?$   $1/tag.html?w=$2        break;
rewrite ^(.*?)/tag/([^/]+)/(d+)$    $1/tag.html?w=$2&page=$3              break;
rewrite ^(.*?)/article/([a-zA-Z0-9_]+)/(.*)$   $1/index.php/article?mod=$2&id=$3     break;
# end nginx rewrite rule

于是 , 整个项目就跑起来了!

接下来,我们来探索关于SEO的部分!

ps:由于是探索阶段, 可能上文部分地方有误差!

深夜来配置一个新项目,Laravel与Vue+ElementUI组合

2017-06-22admin阅读(4290)评论(0)

下一步的计划是做一个微信机器人系统,目前开始准备了,想用一个Vue的框架,于是相中了ElementUI,接下来算是安装及使用的一些记录。

首先第一步,我们先去git上拉这个包(ElementUI官方推荐的)

git clone https://github.com/ElementUI/element-in-laravel-starter.git

第二步, 我们先把Laravel框架和npm所需要的全部依赖下载下来,

npm install (安装前端依赖)

composer install(安装后端php依赖)

依赖安装完成后,

我们更新Laravel 的key, php artisan key:generate

如果提示找不到文件,请把根目录的 .env.example 改成 .env再跑一次,

然后我们找到Laravel框架里默认的模板文件,也就是 (resources/views/welcome.blade.php) 这个文件,

其中默认给你配置好了一些东西,比如

1
2
<div id="app"></div> //vue的页面容器
<script src="{{ mix('js/app.js') }}"></script> //vue的app.js

接下来我们找到这个 app.js 文件,

在 /resources/assets/js 这个目录,找到后我们看到里面有一些默认的代码,是一个demo,我们试试能不能跑起来,

首先用过vue的都知道,

 

我们回到根目录,

npm run dev

跑一下

……

发现没有启动项目,反而被编译了…

打开package.json 文件看看,原来里面的命令和vue默认的不一样…

里面大概是这样:

1
2
3
4
5
6
7
8
9
"scripts": {
    "dev": "npm run development",
    "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
    "watch-poll": "npm run watch -- --watch-poll",
    "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
    "prod": "npm run production",
    "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
  },

好吧,那我们跑项目是 npm watch

1
2
3
4
5
6
22% building modules 108/114 modules 6 active ...dules\axios\lib\core\transformDa
24% building modules 109/114 modules 5 active ...dules\axios\lib\core\transformDa
25% building modules 110/114 modules 4 active ...dules\axios\lib\core\transformDa
26% building modules 111/114 modules 3 active ...dules\axios\lib\core\transformDa
27% building modules 112/114 modules 2 active ..._modules\axios\lib\helpers\cooki
28% building modules 113/114 modules 1 active ..._modules\axios\lib\helpers\cooki

跑了好一会儿,停止了,但是没有像vue一样默认打开浏览器…

好吧,其实这里是Laravel和vue的合体,所以我们还是要跑起来php服务

php artisan serve

1
2
λ php artisan serve
Laravel development server started: <http://127.0.0.1:8000>

php服务启动起来,然后打开浏览器,

刷新页面,如果没错,你已经看到了默认提示了,

那么接下来,我们怎么做项目呢?

因为vue 是单页引用,打开app.js 里面也只是引入了Example这个组件,所以,这里我们需要安装vue的一些其他东西了,

接下来依次安装

1
2
3
4
"vue-loader": "^9.8.0",
"vue-resource": "^1.0.3",
"vue-router": "^2.1.1",
"vue-template-compiler": "^2.1.4"

安装完成,我们开始配置路由

首先新建一个路由文件

我们在app.js同级建一个route.js,

里面内容大概如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import Vue from 'vue'
import Router from 'vue-router'
 
Vue.use(Router);
 
import Hello from './components/Hello.vue'
import Example from './components/Example.vue'
 
export default new Router({
    // mode: 'history',
    routes: [
        {
            path: '/',
            name: 'Hello',
            component: Hello
        },
        {
            path: '/abc',
            name: 'Example',
            component: Example
        }
    ]
})

然后我们回到app.js 里面引入route.js,

头部引入然后注入,

1
2
3
4
5
const app = new Vue({
    el: '#app',
    router,
    render: h => h(App)
});

打开同级目录的App.vue,把里面默认的组件删了,改成

1
2
3
<div id="app">
      <router-view></router-view>
</div>

然后,浏览器刷新,再访问 /#/abc,这样我们就完成了初步配置!

问题: 好像没有热更新,每次改完代码都要手动更新,今晚太晚了,就先到这里…睡…

第二天继续系列…

接下来我们配置Laravel自己的路由,

首先找到 routes/web.php

刚打开可以看到默认的路由信息,也就是我们刚才看到的那个页面的路由

1
2
3
Route::get('/', function () {
    return view('welcome');
});

…没有代码提示,那我们先安装一个代码提示吧!

在 composer.json 里面加入 “barryvdh/laravel-ide-helper”: “dev-master”

这是一个扩展最终会生成一个php文件,我们的phpstorm就能自动获取里面的类和方法实现代码智能提示!

接下来, composer update

然后找到 config/app.php

下拉找到一个数组

1
2
3
'providers' => [
...
]

里面加入 ‘Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider’,

加入后,打开控制台,

php artisan ide-helper:generate

现在这个命令应该会生成一个叫 “_ide_helper.php” 的文件,现在phpstorm已经支持代码提示(如下图),如果没有,可以重启IDE一下试试!

接下来简单的做个路由分组

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
Route::get('/', function () {
    return view('welcome');
});
 
Route::get('/admin', function () {
    dd('admin');
});
 
Route::group(['namespace'=>'Index','prefix'=>'index'], function(){
    Route::any('/', [
        'as' => 'index',
        'uses' => 'IndexController@index'
    ]);
    Route::any('/abc', [
        'as' => 'index',
        'uses' => 'IndexController@test'
    ]);
});
 
Route::group(['namespace'=>'Admin', 'prefix'=>'admin'], function(){
    Route::any('/', [
        'as' => 'index',
        'uses' => 'IndexController@index'
    ]);
});

创建控制器,我们可以手动创建,然后修改命名空间,或者使用命令行创建

php artisan make:controller Index/IndexController

创建控制器后,新增一个index方法,

最终如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
/**
* Created by PhpStorm.
* User: iyahe@qq.com (天明)
* Date: 2017/6/22
* Time: 9:11
*/
 
namespace App\Http\Controllers\Index;
 
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
 
class IndexController extends Controller
{
    //
    public function index(){
        dd('index/index');
    }
    public function test(){
        dd('index/test');
    }
}

然后地址栏,默认打开是 带/#/的进入vue,我们删掉/#/,

访问我们上面建的路由,没错的话,你就可以看到控制器输出的信息了!

未完待续…

  • 上一页
  • 1
  • ···
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • ...
  • 下一页
  • 共 16 页
关于我

小天明 北京·朝阳 前端搬砖工程师

碎碎念):(来自公众号)

热门文章

  • 踩坑记录——iphone上safari开启隐身模式时localStorage变为只读-雅荷心语博客踩坑记录——iphone上safari开启隐身模式时localStorage变为只读2017-02-21评论(4)
  • 程序员是怎样一群人-雅荷心语博客程序员是怎样一群人2015-12-08评论(3)
  • 百度你个大毒瘤 - 吐糟博客这几天打不开事情-雅荷心语博客百度你个大毒瘤 – 吐糟博客这几天打不开事情2015-12-28评论(2)
  • PHP 非对称加密 openssl 加密及解密方法-雅荷心语博客PHP 非对称加密 openssl 加密及解密方法2016-05-17评论(2)
  • PHPStorm10 下载安装破解汉化-雅荷心语博客PHPStorm10 下载安装破解汉化2015-12-15评论(2)
2025年7月
一 二 三 四 五 六 日
« 六    
 123456
78910111213
14151617181920
21222324252627
28293031  

最新评论

  • 前端小武 8年前 (2017-04-06)说:
    我看到了layer
  • 丁艳平 8年前 (2017-03-03)说:
  • Dawn 9年前 (2016-09-16)说:
    call_user_func_array最后的例子是错哦,你用bc方法去调用类里 另外一个方法就知道问题所在了。情况1.调用非静态方法 第一个参数应该传[类的实例,调用方法] (既然有类实例了直接-&
  • Dawn 9年前 (2016-06-21)说:
    tp框架设置了全局捕获异常的,这也没什么。坑的是 他捕获了异常。然后全部返回404。。。不知道的 还以为自己网站被删除了
  • Dawn 9年前 (2016-05-17)说:
    构造函数里的判断 用异常机制可能更好一些

其他类型

  • 芊云全景
  • 配音兔AI配音神器

博客类型

  • 芊云全景
  • 配音兔AI配音神器

左邻右舍

  • 易水寒
  • 楼教主
  • 芊云全景
  • 贤心
  • 配音兔AI配音神器

雅荷心语博客 -心之所向便是光

联系我们关于我们

© 2025 雅荷心语博客   网站地图