react-vr-pannellum
Version:
react VR全景图组件 超简单实用
138 lines (126 loc) • 6.04 kB
JSX
import React, { useEffect, useRef, useState } from "react";
import "./index.css";
export default function Pannellum(props) {
const {
config = {},
scenes = {},
width,
height,
firstSceneId = "",
setViewer,
hotSpots = [],
delayTime = 0,
} = props;
const [cViewer, setCViewer] = useState(null);
const lastSceneId = useRef("");
const hots = useRef([]);
useEffect(() => {
hots.current = hotSpots.map((hot) => {
const newHot = { ...hot };
newHot.type = "info";
if (!Array.isArray(newHot.cssClass)) {
newHot.cssClass = [];
}
if (!newHot.id) {
const randomId = Math.random().toString(36).slice(-6);
newHot.id = randomId;
}
newHot.cssClass = newHot.cssClass.join(" ");
return newHot;
});
}, [hotSpots]);
useEffect(() => {
initSource();
try {
initViewer();
} catch (error) {
throw error;
}
}, []);
useEffect(() => {
if (!cViewer) return;
// 初始化init热点
initHot();
cViewer.on("load", initHot);
return () => {
cViewer.off("load", initHot);
};
}, [cViewer]);
const initViewer = () => {
let firstScene = firstSceneId;
if (!firstScene) {
firstScene = Object.keys(scenes)[0] || "";
}
const initConfig = {
firstScene, // 第一个场景值id
orientationOnByDefault: false, // 如果设置为true,则在加载全景图时将使用设备方向控制(如果设备支持)。如果为 false,则需要通过按下按钮来激活设备方向控制。默认为false
autoLoad: true, // 是否自动加载
autoRotate: 2, // 是否自动旋转
autoRotateInactivityDelay: 2000, // 用户活动停止后多少秒开始自动旋转全景图
fallback: "", // 如果设置,则在用户设备不支持 Pannellum 的情况下,该值将用作后备查看器的 URL
friction: 0.15, // 惯性控制摩擦器 0.1 到 1 值越大停的越快 默认值0.15
showFullscreenCtrl: true, // 是否显示全屏控件
showZoomCtrl: true, // 是否显示缩放控件
mouseZoom: true, // 如果设置为false,使用鼠标滚轮进行缩放将被禁用 默认为true
draggable: true, // 如果设置为false,则禁用鼠标和触摸拖动 默认为true
disableKeyboardCtrl: false, // 如果设置为true,则禁用键盘控制。默认为false 可使用键盘控制旋转缩放
touchPanSpeedCoeffFactor: 1, // 触摸时平移速度 默认1 值越大滑动越快
yaw: -10, // 初始垂直方向左右旋转角度 正值向右 负值向左,左右旋转角度控制
minYaw: -180, // 垂直方向最小旋转角度 默认-180
maxYaw: 180, // 垂直方向最大旋转角度 默认180
pitch: 0, // 初始水平方向上下移动角度 正值向上 负值向下,上下旋转角度控制
minPitch: -180, // 水平方向最小移动角度 默认 -180
maxPitch: 180, // 水平方向最大移动角度 默认 180
hfov: 100, // 初始摄像机视角,即缩放角度大小控制,太大会导致拉伸效果,默认为100
minHfov: 50, // 摄像机最小视角,默认50,
maxHfov: 120, // 摄像机最大视角 如果最大视角小于初始视角,初始视角值为最大视角值,默认120
compass: true, // true显示指南针控件 默认false
northOffset: 0, // 设置全景图中心与北的偏移量,影响指南针初始角度,只有在compass为true时有效果
preview: "", // 指定要在加载全景图之前显示的预览图像的 URL
horizonPitch: 0, // 指定图像水平的俯仰 用于校正非水平全景图 默认为0
horizonRoll: 0, // 指定图像水平的滚动 用于校正非水平全景图 默认为0
escapeHTML: true, // HTML 将从配置字符串中转义,以帮助缓解可能的 DOM XSS 攻击, 默认为false。
crossOrigin: "anonymous", // 使用的 CORS 请求类型,可以设置为 anonymous或use-credentials。默认为anonymous.
sceneFadeDuration: 1000, // 指定在场景之间转换时的淡入淡出持续时间,以毫秒为单位, 默认为1000
hotSpotDebug: false, // 为true时,单击鼠标按钮时,鼠标指针的俯仰和偏航记录到控制台。默认为false
backgroundColor: [0, 0, 0], // 指定一个包含 RGB 值 [0, 1] 的数组,该数组为没有可用图像数据的区域设置背景颜色, 默认为[0, 0, 0]
avoidShowingBackground: false, // 如果设置为true,则通过约束偏航角和视野来防止显示部分全景的超出范围的区域。即使在画布的角落和边缘,也只会显示实际属于图像的区域 因此backgroundColor如果设置了此选项,则不需要设置该选项。默认为false
...config,
};
const initViewer = window.pannellum.viewer("panorama", {
default: initConfig,
scenes,
});
if (setViewer) {
setViewer(initViewer);
}
setCViewer(initViewer);
};
function initHot() {
const currentSceneId = cViewer.getScene();
hots.current.forEach((hot) => {
if (hot.sId === lastSceneId.current) {
cViewer.removeHotSpot(hot.id, hot.sId);
}
if (hot.sId === currentSceneId) {
const timer = setTimeout(() => {
cViewer.addHotSpot(hot, hot.sId);
clearTimeout(timer);
}, delayTime);
}
});
lastSceneId.current = currentSceneId;
}
return (
<div id="panorama" className="panorama" style={{ width, height }}></div>
);
}
const initSource = () => {
const link = document.createElement("link");
link.rel = "stylesheet";
link.href = `${require("../source/pannellum.css")}`;
document.body.appendChild(link);
const script = document.createElement("script");
script.type = "text/javascript";
script.src = `${require("../source/pannellum.js")}`;
};