Krpano:打造全景漫游体验—全景开发(四)

前言

为了让全景更加生动,营造视觉奇观和增强视觉效果,我们往往会在全景更里面增加一些特效,例如飘落特效和太阳光特效等,这篇文章就来实现如何在全景中为场景添加飘落特效

预览效果

1.snow.js插件的使用

1.1snow.js插件介绍

飘落特效主要使用krpano提供的插件snow.js,这是官方实例,这是一个天气效果插件,可以为全景添加雪雨(像素)或者自定义的图像

插件中的所有属性都可以动态设置或更改,snow.js插件提供了以下属性:

  • mode:可以设置的值有snow,rain,image,雨雪像素的颜色可以通过color属性定义,掉落的线条则通过rainwidthrainalpha属性用来模拟下雨,image代表使用自定义图像,必须设置imageurl属性
  • imageurl:图像的地址
  • imagescale:图像的缩放比例,默认为1.0
  • flakes:特效的数量,默认为4000
  • color:特效的颜色,默认为0xFFFFFF
  • floor:地面高度,定义了一个虚拟地面,特效到达则停止掉落,设置的范围为 0.0 到 1.0,设置 0.0 地面高度为全景/屏幕的中间,默认设置为 0.3
  • speed:飘落的速度,默认1.0
  • spreading:范围/深度,默认为4.0
  • shake:特效抖动范围,默认为4.0
  • speedvariance:特效下落速度的随机变化,默认为2.0
  • wind:改变特效飘落方向的风力,默认为0.0
  • winddir:风向(以度为单位),0-360,默认为0
  • rainwidth:雨滴线的线宽,默认为0.5
  • rainalpha:雨滴线的透明度,默认为0.5
  • invert:图像坠落方向,向上/向下,默认为false

1.2使用插件

使用插件首先要导入插件,可以使用include元素将其他xml文件的内容嵌入到主xml中,krpano安装包中就包含了snow.xml示例文件,在krpanos\viewer\examples\snow文件夹下

image.png

然后在想要的场景中导入,并在onstart的时候加载特效(执行action动作)

// onready回调
const onReadyCallBack = (kp: any) => {
    const content = `
        <control bouncinglimits="calc:image.cube ? true : false" />
        <view hlookat="0.0" vlookat="0.0" fovtype="MFOV" fov="120" maxpixelzoom="2.0" fovmin="70" fovmax="140" limitview="auto" />
        <preview url="krpano/pano/login/preview.jpg" />
        <image>
        <cube url="krpano/pano/login/%s/l%l/%v/l%l_%s_%v_%h.jpg" multires="512,1024,2048" />
        </image>
        <include url="krpano/plugins/snow/snow.xml" />
    `
    kp.set('scene[scene_login].title', 'anima_scene')
    kp.set('scene[scene_login].thumburl', 'krpano/pano/login/thumb.jpg')
    kp.set('scene[scene_login].onstart', 'snowflakes();')
    kp.set('scene[scene_login].content', content)
}

在这里插入图片描述

2.自定义特效

但是这样只能在加载场景的时候选择是否使用include来引入插件,无法动态的include引入,所以krpano为我们提供了一个addplugin方法,可以动态的引入插件,不止插件也可以动态创建layer、hotspot元素等

addplugin方法引入snow.js插件之后就可以设置对应的属性了,特效的模式我都使用自定义的图像

// 加载特效
kp.addplugin(uid)
kp.set(`plugin[${uid}].zorder`, 1)
kp.set(`plugin[${uid}].url`, '%SWFPATH%/plugins/snow/snow.js')
kp.set(`plugin[${uid}].alturl`, '%SWFPATH%/plugins/snow/snow.js')
kp.set(`plugin[${uid}].mode`, sys_effect[index].mode)
kp.set(`plugin[${uid}].blendmode`, 'add')
kp.set(`plugin[${uid}].imageurl`, OSS_PATH + '/' + sys_effect[index].path)
kp.set(`plugin[${uid}].invert`, !!effectObj.invert)
kp.set(`plugin[${uid}].imagescale`, effectObj.imagescale)
kp.set(`plugin[${uid}].flakes`, effectObj.flakes)
kp.set(`plugin[${uid}].speed`, effectObj.speed)
kp.set(`plugin[${uid}].speedvariance`, effectObj.speedvariance)
kp.set(`plugin[${uid}].floor`, effectObj.floor)
kp.set(`plugin[${uid}].shake`, effectObj.shake)
kp.set(`plugin[${uid}].wind`, effectObj.wind)
kp.set(`plugin[${uid}].winddir`, effectObj.winddir)

然后就可以根据自己的需要去编辑设置特效的属性了,通过antd的Slider组件来绑定对象的属性,当Slider的值发生改变时,触发onChange事件,拿到改变后的值通过set方法去更新

  // 运动方向变化
  const onInvertChange = (value: number) => {
    kp.set(`plugin[${id}].invert`, !!value)
  }
  // 特效缩放变化
  const onScaleChange = (value: number) => {
    kp.set(`plugin[${id}].imagescale`, value)
  }
  // 特效数量变化
  const onFlakesChange = (value: number) => {
    kp.set(`plugin[${id}].flakes`, value)
  }
  // 运动速度变化
  const onSpeedChange = (value: number) => {
    kp.set(`plugin[${id}].speed`, value)
  }
  // 运动速度变化变化
  const onSpeedvarianceChange = (value: number) => {
    kp.set(`plugin[${id}].speedvariance`, value)
  }
  // 虚拟地板高度变化
  const onFloorChange = (value: number) => {
    kp.set(`plugin[${id}].floor`, value)
  }
  // 特效抖动变化
  const onShakeChange = (value: number) => {
    kp.set(`plugin[${id}].shake`, value)
  }
  // 风力变化
  const onWindChange = (value: number) => {
    kp.set(`plugin[${id}].wind`, value)
  }
  // 风向变化
  const onWinddirChange = (value: number) => {
    kp.set(`plugin[${id}].winddir`, value)
  }

当切换场景的时候,需要移除当前场景的所有特效,以及加载下一个场景的特效,否则下一场景还会存在前一个场景的特效
addplugin方法对应的就是removeplugin方法,用来移除指定的插件,所以在切换场景的时候移除对应特效插件

  // 切换场景
  const onSceneChange = (nextScene: ISceneType) => {
    // 判断前一场景特效列表长度
    if (scene?.effect.length) {
      scene.effect.forEach((item) => {
        kp.removeplugin(item.id)
      })
    }
  }

并且在新场景中创建特效

useEffect(() => {
    scene.effect.forEach((item) => {
      kp.addplugin(item.id)
      kp.set(`plugin[${item.id}].zorder`, 1)
      kp.set(`plugin[${item.id}].url`, '%SWFPATH%/plugins/snow/snow.js')
      kp.set(`plugin[${item.id}].alturl`, '%SWFPATH%/plugins/snow/snow.js')
      kp.set(`plugin[${item.id}].mode`, item.mode)
      kp.set(`plugin[${item.id}].blendmode`, 'add')
      kp.set(`plugin[${item.id}].imageurl`, OSS_PATH + '/' + item.imageurl)
      kp.set(`plugin[${item.id}].invert`, !!item.invert)
      kp.set(`plugin[${item.id}].imagescale`, item.imagescale)
      kp.set(`plugin[${item.id}].flakes`, item.flakes)
      kp.set(`plugin[${item.id}].speed`, item.speed)
      kp.set(`plugin[${item.id}].speedvariance`, item.speedvariance)
      kp.set(`plugin[${item.id}].floor`, item.floor)
      kp.set(`plugin[${item.id}].shake`, item.shake)
      kp.set(`plugin[${item.id}].wind`, item.wind)
      kp.set(`plugin[${item.id}].winddir`, item.winddir)
    })
}, [sceneid])

krpano特效制作demo

结尾

以上就是我对场景添加特效的实现,如果还有更好的方式也欢迎大家一起分享交流,学习学习😊🤞💋😘

  • 36
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值