photo-sphere-viewer 全景图Vr 720全景查看(vue篇)

这篇具有很好参考价值的文章主要介绍了photo-sphere-viewer 全景图Vr 720全景查看(vue篇)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、安装以及引入方式

npm install @photo-sphere-viewer/core
/***插件安装**/
npm install @photo-sphere-viewer/markers-plugin
npm install @photo-sphere-viewer/gallery-plugin
npm install @photo-sphere-viewer/autorotate-plugin

二、PhotoSphereViewer.vue

<template>
  <div id="viewer"></div>
</template>

<script>
import { Viewer } from "@photo-sphere-viewer/core";
import { MarkersPlugin } from "@photo-sphere-viewer/markers-plugin";
import { GalleryPlugin } from "@photo-sphere-viewer/gallery-plugin";
import { AutorotatePlugin } from "@photo-sphere-viewer/autorotate-plugin";
import "@photo-sphere-viewer/core/index.css";
import "@photo-sphere-viewer/markers-plugin/index.css";
import "@photo-sphere-viewer/gallery-plugin/index.css";
export default {
  props: {
    hasAnimate: {
      type: Boolean,
      default: true,
    },
    imgList: [],
    hasGallery: {
      type: Boolean,
      default: true,
    },
  },
  components: {},
  data() {
    return {
      viewer: "",
      panoramaUrl: "",
      markersPlugin: "",
      autorotatePlugin: "",
      galleryPlugin: "",
      currIndex: 0,
      animatedValues: {
        pitch: { start: -Math.PI / 2, end: 0.2 },
        yaw: { start: Math.PI, end: 0 },
        zoom: { start: 0, end: 50 },
        fisheye: { start: 2, end: 0 },
      },
      defaultUrl: require("../assets/3.jpg"),
    };
  },
  created() {},
  mounted() {
    this.panoramaUrl = this.imgList[0].panorama || this.defaultUrl;
    this.initViewer();
    this.handelListenerViewerClick();
    this.handleSelectMarker();
    this.handleHoverMarker();
    this.handleLeaveMarker();
    this.$nextTick(() => {
      this.handleGalleryChange();
    });
  },
  watch: {},
  methods: {
    initViewer() {
      const _this = this;
      this.viewer = new Viewer({
        container: "viewer",
        panorama: this.panoramaUrl || this.defaultUrl,
        caption: "test",
        loadingImg: require("../assets/loader.gif"),
        touchmoveTwoFingers: true,
        mousewheelCtrlKey: false,
        navbar: [
          "autorotate",
          "zoom",
          "markers",
          "move",
          "download",
          "gallery",
          {
            title: "Change points",
            content: "🔄",
            onClick: _this.randomPoints,
          },
          "caption",
          "fullscreen",
        ],
        plugins: [
          [
            GalleryPlugin,
            {
              visibleOnLoad: true,
              hideOnClick: false,
            },
          ],
          [
            AutorotatePlugin,
            {
              autostartDelay: null,
              /*   autorotatePitch: _this.animatedValues.pitch.end,
              autostartOnIdle: false, */
              autorotateSpeed: "1rpm",
            },
          ],
          [
            MarkersPlugin,
            {
              markers: [],
            },
          ],
        ],
      });
      _this.markersPlugin = _this.viewer.getPlugin(MarkersPlugin);
      _this.autorotatePlugin = _this.viewer.getPlugin(AutorotatePlugin);
      _this.galleryPlugin = _this.viewer.getPlugin(GalleryPlugin);
      if (_this.hasGallery) {
        _this.galleryPlugin.setItems(_this.imgList); //设置图库
      }
      _this.viewer.addEventListener("ready", _this.handleViewerReady, {
        once: true,
      });
    },
    handleViewerReady() {
      this.markersPlugin.setMarkers(this.imgList[this.currIndex].markers); //设置标签
      this.showInitMarker();
    },
    showInitMarker() {
      const _this = this;
      this.viewer
        .animate({
          yaw: "-27deg",
          pitch: "-6deg",
          speed: 100,
        })
        .then(() => {
          _this.markersPlugin.showMarkerTooltip("new-marker1");
          _this.autorotatePlugin.start();
        });
    },
    //清除标记
    clearMarker() {
      this.markersPlugin.clearMarkers();
    },
    //更新标记
    updateMarker(id, imgUrl) {
      this.markersPlugin.updateMarker({
        id: id,
        image: imgUrl,
      });
    },
    updateIndex(index) {
      this.currIndex = index;
      this.panoramaUrl = this.imgList[index].panorama;
    },
    //选择标记事件
    handleSelectMarker() {
      const _this = this;
      this.markersPlugin.addEventListener("select-marker", ({ marker }) => {
        this.$emit("selectMarker", marker);
      });
    },
    //标记悬停事件
    handleHoverMarker() {
      this.markersPlugin.addEventListener("enter-marker", ({ marker }) => {
        /*  console.log("enter"); */
      });
    },
    handleLeaveMarker() {
      this.markersPlugin.addEventListener("leave-marker", ({ marker }) => {
        /* console.log("leave"); */
      });
    },
    //gallery图库列表切换
    handleGalleryChange() {
      const _this = this;
      let _sindex = "";
      document.addEventListener("click", function (e) {
        var element = document.elementFromPoint(e.clientX, e.clientY);
        let flag = false;
        if (element && element.dataset && element.dataset.psvGalleryItem) {
          const id = element.dataset.psvGalleryItem;
          _sindex = _this.imgList.findIndex((data) => {
            return data.id == id;
          });
          flag = true;
        } else {
          if (element&&element.className == "psv-gallery-item-thumb") {
            const eleId =
              element.parentElement.parentElement.dataset.psvGalleryItem;
            _sindex = _this.imgList.findIndex((data) => {
              return data.id == eleId;
            });
            flag = true;
          }
        }
        if (flag) {
          if (_this.currIndex == _sindex) {
            console.log("点击了未切换");
          } else {
            _this.currIndex = _sindex;
            _this.panoramaUrl = _this.imgList[_sindex].panorama;
            _this.handelChangeViewer("gallery");
          }
        }
      });
    },
    //图库列表当前选中active更新
    handelGalleryActive() {
      const galleryBox = document.getElementsByClassName(
        "psv-gallery-container"
      )[0];
      const galleryItemEle =
        document.getElementsByClassName("psv-gallery-item")[this.currIndex];
      galleryBox.childNodes.forEach((item) => {
        item.className = "psv-gallery-item";
      });
      galleryItemEle.classList.add("psv-gallery-item--active");
    },
    /***
     * viewer 切换场景
     * */

    handelChangeViewer(type) {
      const _this = this;
      if (_this.viewer) {
        _this.clearMarker();
        _this.handelGalleryActive();
        _this.viewer.setPanorama(_this.panoramaUrl).then(() => {
          _this.markersPlugin.setMarkers(
            _this.imgList[_this.currIndex].markers
          );
        });
        if (type != "gallery") {
          this.handelGalleryActive();
        }
      }
    },
    //viewer点击事件监听
    handelListenerViewerClick(addMarker) {
      const _this = this;
      const emptyMarker = {
        image: require("./../assets/local.png"),
        width: 32,
        height: 32,
      };
      addMarker = addMarker ? addMarker : emptyMarker;
      this.viewer.addEventListener("click", ({ data }) => {
        if (!data.rightclick) {
          _this.$emit("viewerClick", data);
          _this.markersPlugin.addMarker({
            id: "#" + Math.random(),
            position: { yaw: data.yaw, pitch: data.pitch },
            image: addMarker.image || require("./../assets/local.png"),
            size: {
              width: addMarker.width || 32,
              height: addMarker.height || 32,
            },
            anchor: "bottom center",
            tooltip: addMarker.tooltip || "新增标记",
            data: {
              generated: true,
            },
          });
        }
      });
    },
    randomPoints() {
      /*  this.markersPlugin.showMarkerTooltip("new-marker3"); */
      this.markersPlugin.showAllTooltips();
    },
  },
};
</script>
<style lang="scss" scoped>
#viewer {
  width: 100%;
  height: 100%;
}
</style>

图库列表切换场景及图标点击切换实现场景

注:图库插件本身对于图库列表切换,场景的标记点会是初始时设置的标记点,不会更新新的标记点,需要自己写监听调用更新标记的方法(handleGalleryChange)。同时对于标记切换场景用了viewer.setPanorama,图库列表当前选中的active没有同步,需要调用自己写的方法handelGalleryActive,同步当前的图片active样式

图库列表切换

handleGalleryChange() {
      const _this = this;
      let _sindex = "";
      document.addEventListener("click", function (e) {
        var element = document.elementFromPoint(e.clientX, e.clientY);
        let flag = false;
        if (element && element.dataset && element.dataset.psvGalleryItem) {
          const id = element.dataset.psvGalleryItem;
          _sindex = _this.imgList.findIndex((data) => {
            return data.id == id;
          });
          flag = true;
        } else {
          if (element&&element.className == "psv-gallery-item-thumb") {
            const eleId =
              element.parentElement.parentElement.dataset.psvGalleryItem;
            _sindex = _this.imgList.findIndex((data) => {
              return data.id == eleId;
            });
            flag = true;
          }
        }
        if (flag) {
          if (_this.currIndex == _sindex) {
            console.log("点击了未切换");
          } else {
            _this.currIndex = _sindex;
            _this.panoramaUrl = _this.imgList[_sindex].panorama;
            _this.handelChangeViewer("gallery");
          }
        }
      });
    },
    //图库列表当前选中active更新
    handelGalleryActive() {
      const galleryBox = document.getElementsByClassName(
        "psv-gallery-container"
      )[0];
      const galleryItemEle =
        document.getElementsByClassName("psv-gallery-item")[this.currIndex];
      galleryBox.childNodes.forEach((item) => {
        item.className = "psv-gallery-item";
      });
      galleryItemEle.classList.add("psv-gallery-item--active");
    },
    /***
     * viewer 切换场景
     * */

    handelChangeViewer(type) {
      const _this = this;
      if (_this.viewer) {
        _this.clearMarker();
        _this.handelGalleryActive();
        _this.viewer.setPanorama(_this.panoramaUrl).then(() => {
          _this.markersPlugin.setMarkers(
            _this.imgList[_this.currIndex].markers
          );
        });
        if (type != "gallery") {
          this.handelGalleryActive();
        }
      }
    },

选择标签切换: 

this.markersPlugin.addEventListener("select-marker", ({ marker }) => {
      
        this.handelChangeViewer();
      });

三、页面调用 

<template>
  <div class="">
    <photoSphereViewer
    style="width: 80vw; height: 90vh"
      ref="viewer"
      :imgList="photoList"
      @selectMarker="selectMarker"
    />
  </div>
</template>

<script>
import photoSphereViewer from "@/components/PhotoSphereViewer.vue";
import { markers, photos } from "@/components/data.js";
export default {
  props: [],
  components: { photoSphereViewer },
  data() {
    return {
      photoList: photos,
    };
  },
  created() {},
  mounted() {},
  methods: {
    selectMarker(marker) {
      console.log("here page");
      console.log(marker);
      const myViewer = this.$refs.viewer;
      if (marker.id == "new-marker1") {
        myViewer.updateIndex(1);
      }
      if (marker.id == "new-marker2") {
        myViewer.updateIndex(2);
      }
      if (marker.id == "new-marker3") {
        myViewer.updateMarker(marker.id, require("./../../assets/bao.png"));
       
      } else {
        myViewer.handelChangeViewer();
      }
    },
  },
};
</script>
<style lang="scss" scoped>
</style>

四、模拟数据

/**标记点**/
export const markers = [{
        id: 'new-marker1',
        position: {
            yaw: '-27deg',
            pitch: '-6deg'
        },
        image: require('./../assets/arrow.gif'),
        size: {
            width: 50,
            height: 50
        },
        tooltip: {
            content: "go ahead",
            className: 'custom-tooltip',
            position: 'top',
            trigger: 'chan',
        },
    },
    {
        id: 'new-marker2',
        position: {
            yaw: '-170deg',
            pitch: '20deg'
        },
        image:require('./../assets/arrow.gif'),
        size: {
            width: 50,
            height: 50
        },
    },
    {
        id: 'new-marker3',
        tooltip: {
            content: "恭喜你,获得意外宝藏!",
            class: 'custom-tooltip',
            position: 'top',
            trigger: 'click'
        },
        position: {
            yaw: '4deg',
            pitch: '-52deg'
        },
        image: require('./../assets/local.png'),
        size: {
            width: 38,
            height: 38
        },
        anchor: 'Holly',
    },
    {
        // polyline marker
        id: 'polyline',
        polylinePixels: [
            [2478, 1635], [2184, 1747], [1674, 1953], [1166, 1852],
            [709, 1669], [301, 1519], [94, 1399], [34, 1356],
        ],
        svgStyle: {
            stroke: 'rgba(140, 190, 10, 0.8)',
            strokeLinecap: 'round',
            strokeLinejoin: 'round',
            strokeWidth: '10px',
        },
        tooltip: 'A dynamic polyline marker',
    },
];
/**全景图片列表**/
export const photos = [{
        id: 'sphere',
        panorama:require('./../assets/3.jpg'),
        thumbnail: require('./../assets/3.jpg'),
        options: {
            caption: '图一',
        },
        markers:markers
    },
    {
        id: 'sphere-test',
        panorama: require('./../assets/2.jpg'),
        thumbnail: require('./../assets/2.jpg'),
        name: 'Test sphere',
        options: {
            caption: '图二',
        },
        markers:[{
            id: 'new-marker21',
            position: {
                yaw: '-27deg',
                pitch: '-6deg'
            },
            image: require('./../assets/arrow.gif'),
            size: {
                width: 50,
                height: 50
            },
        },]
    },
    {
        id: 'key-biscayne',
        panorama: require('./../assets/1.jpg'),
        thumbnail: require('./../assets/1.jpg'),
        name: 'Key Biscayne',
        options: {
            caption: '图三',
        },
        markers:[ ]
    },
]

五、补充入场动画(引入utils)

import { Viewer, utils } from "@photo-sphere-viewer/core";
  //定义动画参数
    animatedValues: {
        pitch: { start: -Math.PI / 2, end: 0.2 },
        yaw: { start: Math.PI, end: 0 },
        zoom: { start: 0, end: 50 },
        fisheye: { start: 2, end: 0 },
      },

//入场动画
    enteraAimation() {
      const _this = this;
      /*  _this.autorotatePlugin.stop(); */
      new utils.Animation({
        properties: _this.animatedValues,
        duration: 2500,
        easing: "inOutQuad",
        onTick: (properties) => {
          _this.viewer.setOption("fisheye", properties.fisheye);
          _this.viewer.rotate({ yaw: properties.yaw, pitch: properties.pitch });
          _this.viewer.zoom(properties.zoom);
          
        },
      }).then(() => {
         if (this.hasGallery) {
        this.galleryPlugin.setItems(this.imgList); //设置图库
        
      }
        /*  _this.autorotatePlugin.start(); */
      });
    },

六、事件整理

1.viewer

1)全屏

viewer.enterFullscreen();//全屏

viewer.exitFullscreen();//退出全屏

viewer.toggleFullscreen();//全屏切换

viewer.isFullscreenEnabled();//获取当前全屏状态

2)pannel

//监听 panel显示
this.viewer.addEventListener("show-panel", ({ panelId }) => {

    if (panelId === PANEL_ID) {
       viewer.navbar.getButton(BUTTON_ID).toggleActive(true);
    } 
});
//监听 panel隐藏
this.viewer.addEventListener("hide-panel", ({ panelId }) => {
    if (panelId === PANEL_ID) {
        viewer.navbar.getButton(BUTTON_ID).toggleActive(false);
        
    } 
});

//panel隐藏
 this.viewer.panel.hide();

//panel显示
this.viewer.panel.show({
    id: id,
    width: "100%",
    content: value,
})

 3)获取view相关信息

const position = viewer.getPosition();

const zoom =viewer.getZoomLevel();
      
const size = viewer.getSize();

4)对viewer的set

//rorate
viewer.rotate({yaw:0,pitch:0});

//切换场景图
viewer.setPanorama('image.jpg')
  .then(() => /* update complete */);

//setOptions
viewer.setOptions({
        defaultPitch: animatedValues.pitch.end,
        defaultYaw: animatedValues.yaw.end,
        defaultZoomLvl: animatedValues.zoom.end,
      });

5)其他监听事件

//position更新
viewer.addEventListener('position-updated', ({ position }) => ());

//view点击
viewer.addEventListener('click', ({ data }) => {
    console.log(`${data.rightclick ? 'right ' : ''}clicked at yaw: ${data.yaw} pitch: ${data.pitch}`);
});

//view Ready
viewer.addEventListener('ready', () => {
  console.log(`viewer is ready`);
}, { once: true });

//zoom-updated
viewer.addEventListener('zoom-updated', ({ zoomLevel }) => {
    console.log(`new zoom level is ${zoomLevel}`);
});

2.MarkersPlugin

//tooltip全部显示
markersPlugin.showAllTooltips();

//清除标记
markersPlugin.clearMarkers();

//更新标记
markersPlugin.updateMarker({
        id: id,
        image: imgUrl,
});
//设置标记
markersPlugin.setMarkers(markers)

//选中标记
markersPlugin.addEventListener("select-marker", ({ marker }) => {  });

//标记悬停
 markersPlugin.addEventListener("enter-marker", ({ marker }) => {
        /*  console.log("enter"); */
 });
this.markersPlugin.addEventListener("leave-marker", ({ marker }) => {
        /* console.log("leave"); */
 });

3.AutorotatePlugin

//自动旋转停止
autorotatePlugin.stop();

//开始自动自动旋转
autorotatePlugin.start();


4.GalleryPlugin文章来源地址https://www.toymoban.com/news/detail-505359.html

//图库列表显示
galleryPlugin.show();
//图库列表隐藏
galleryPlugin.hide();
//图库列表切换
galleryPlugin.toggle();

到了这里,关于photo-sphere-viewer 全景图Vr 720全景查看(vue篇)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 0基础学习VR全景平台篇第137篇:720VR全景,DJI无人机遥控器调参

    上课!全体起立~ 大家好,欢迎观看蛙色官方系列全景摄影课程! 这节课以御2为例 介绍的是无人机调参 步骤一:下载DJI Go 4并注册账号 步骤二:拿下遥杆并装好,展开遥控天线。将无人机与遥控器相连,选择相应的连接线,将手机连接至遥控器上。 步骤三:启动DJI GO4 AP

    2024年01月21日
    浏览(34)
  • 开源720VR全景制作系统源码 自适应手机电脑端

    现在很多客户对全景有着非常多的需求,因为现在很多实体厂房,工厂都需要VR全景看房,彰显实力,给大家分享一个720VR全景制作系统源码,源码全开源,可自行进行二开。 720云VR全景通应用范围广泛:政府、房产、旅游、汽车、家居、装修、家电、酒店、KTV、商场、饭店、

    2024年02月12日
    浏览(24)
  • 720VR全景通源码系统+全景视频+重力感应+地图导航 带完整的前后端搭建教程

    大家好啊,今天源码小编来和大家分享一款720VR全景通源码系统,这款源码系统不仅能够支持上传高清视频,还可以一键生成全景视频,同事还有重力感应的效果,是不是很神奇。下面是部分功能实现的核心代码: 系统特色功能一览: 1、支持VR虚拟现实、全景视频、说一说、

    2024年02月06日
    浏览(23)
  • VR全景智慧园区,沉浸式数字化体验,720度全视角展示

    导语: 随着科技的迅猛发展,虚拟现实(Virtual Reality,简称VR)全景技术已经成为了人们趋之若鹜的新兴领域。  而城市园区作为现代社会的重要组成部分,也正在积极寻求创新的方式来吸引更多的人流和投资。  一.城市园区与VR全景的完美结合 城市园区作为城市发展的新

    2024年02月10日
    浏览(34)
  • 720云手机电动云台全新上市,让手机能自动拍摄亿万像素VR全景

    2024年3月,720云正式发布手机拍摄专业级VR全景的云台——720云手机电动云台(LG-05),这款云台极大程度上把拍摄过程简化到极致。云台电机搭载先进的2.4G/蓝牙双模无线遥控功能和4500mAh电池,保证了无需连续充电的长时间使用。全自动拍摄模式和亿像素图像输出,让您轻松捕

    2024年04月26日
    浏览(25)
  • 如何纯前端实现VR查看全景

    首先需要有node环境,安装node,找到对应电脑系统的版本直接安装即可。 打开Gitee地址:https://gitee.com/muxiaogo/threejs-vr-vue3下载本地解压 打开命令行工具cmd,cd到源码解压的根目录执行命令 若安装依赖失败,有可能是node版本不对。本文使用node.v16.4.0 执行成功后会出现node_modul

    2024年02月20日
    浏览(31)
  • 如何一键将720云全景图原图下载到本地电脑里

    如何下载建E、720yun、酷雷曼、景站、酷家乐、百度街景的全景图?网上有很多的方法,但是有些方法下载需要购买或下载的图片有水印,那怎样才能下载高清全景图呢?遇到问题的小伙伴快来看看吧。 首先第一步 下载这个720全景图下载软件,地址是 http://krpano.org,下载后,

    2024年02月11日
    浏览(56)
  • VR漫游:720度实景参观,打造魅力生态小区

    随着城市的不断发展,小区的建设越发具有生态化、绿色化的特点,人们也会偏向选择更加适合居住的小区。为了让更多的用户体验小区的舒适性,不少地产开发商准备引入VR漫游技术。 VR漫游不仅能够真实地展示现场环境,还可以改变传统网络宣传枯燥的问题,720度实景参

    2024年02月12日
    浏览(30)
  • 720度vr虚拟家居展厅提升客户的参观兴致

    VR虚拟展厅线上3D交互展示的优势有以下几点: 打破了场馆的展示限制,可展示危险性制品、珍贵稀有物品、超大型设备等,同时提供了更大的展示空间和更丰富的展示内容。 可提供企业真实环境的实时VR全景参观,提升潜在客户信任度。 提供了更低的成本、更高的效率和更

    2024年02月04日
    浏览(41)
  • 上海VR全景展示,快速了解VR全景拍摄

    导语: 随着科技的不断进步,虚拟现实技术的应用日益广泛。在这其中,VR全景图片作为一种数字化助力的全景拍摄方式,正逐渐成为人们关注的焦点。通过数字化技术,VR全景图片能够以360度全方位的视角呈现真实的场景,为观众带来身临其境的感受。本文将重点探讨VR全景

    2024年02月15日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包