一、安装以及引入方式
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文章来源:https://www.toymoban.com/news/detail-505359.html
//自动旋转停止
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模板网!