123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- import useWorker from "../lib/omnimatrix-video-player/omnimatrix-video-player.js";
- import FingerprintJS from "../lib/FingerprintJS/fingerprint.min.js";
- /**
- * function useWorker(url: string, className: string, device: string, callback?: Function): any
- @param url — wss连接地址 wss://origin/VideoShow/Common?UUID=uuid&DeviceID=deviceID&Token=token
- @param className — 选择器 .video-class | #video-class ...
- @param device — 设备ID
- @param callback — 画面渲染完成时的回调
- @returns — 包含两个Web Worker和一个关闭函数的对象
- */
- /**
- * @returns Promise
- * @description 获取指纹
- */
- function getFingerprint() {
- return new Promise((resolve, reject) => {
- // Get the visitor identifier when you need it.
- FingerprintJS.load()
- .then((fp) => fp.get())
- .then((result) => {
- // This is the visitor identifier:
- const visitorId = result.visitorId;
- resolve(visitorId);
- })
- .catch(reject);
- });
- }
- // 格式化时间
- function dateFormat(oDate, fmt) {
- var o = {
- "M+": oDate.getMonth() + 1, //月份
- "d+": oDate.getDate(), //日
- "h+": oDate.getHours(), //小时
- "m+": oDate.getMinutes(), //分
- "s+": oDate.getSeconds(), //秒
- "q+": Math.floor((oDate.getMonth() + 3) / 3), //季度
- S: oDate.getMilliseconds(), //毫秒
- };
- if (/(y+)/.test(fmt)) {
- fmt = fmt.replace(
- RegExp.$1,
- (oDate.getFullYear() + "").substr(4 - RegExp.$1.length)
- );
- }
- for (var k in o) {
- if (new RegExp("(" + k + ")").test(fmt)) {
- fmt = fmt.replace(
- RegExp.$1,
- RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length)
- );
- }
- }
- return fmt;
- }
- // 显示回调信息
- function showCBInfo(szInfo) {
- szInfo =
- "<div>" +
- dateFormat(new Date(), "yyyy-MM-dd hh:mm:ss") +
- " " +
- szInfo +
- "</div>";
- $("#cbinfo").html(szInfo + $("#cbinfo").html());
- }
- /**
- * 获取ws连接地址
- * @returns
- */
- function getAddress(type = "Full", params = { X: 0, Y: 0 }) {
- return `wss://${$("#Ip").val()}/VideoShow/Preview/${type}/Main?X=${
- params.X
- }&Y=${params.Y}`;
- }
- /**
- * 重置画布
- * @param {String} selector ——选择器
- */
- function resetVideo(selector) {
- let parent = $(selector).parent();
- $(selector).remove();
- parent.append(
- `<canvas id="${selector.split("#")[1]}" width='100%'></canvas>`
- );
- }
- /**
- *
- * @param {String} selector ——选择器
- * @returns
- */
- function getRatio(selector) {
- return {
- ratioX: $(selector).width() / $(selector).attr("width"),
- ratioY: $(selector).height() / $(selector).attr("height"),
- width: $(selector).width(),
- baseWidth: $(selector).attr("width"),
- baseHeight: $(selector).attr("height"),
- };
- }
- /**
- * 用于请求
- * @param {String} url ——请求地址
- * @param {String} method ——请求方式
- * @param {Object} data ——请求参数
- * @returns Promise
- */
- function request(url, method = "GET", data = {}) {
- return new Promise((resolve, reject) => {
- $.ajax({
- type: method,
- url,
- data,
- dataType: "json",
- timeout: 15000,
- success: function (response) {
- resolve(response);
- },
- error: function (error) {
- reject(error);
- },
- });
- });
- }
- // 滚轮缩放、放大逻辑
- function enableImageManipulation(containerId, imageId, options = {}) {
- const container = document.querySelector(containerId);
- const image = document.querySelector(imageId);
- let isDragging = false;
- let startX,
- startY,
- initialX = 0,
- initialY = 0,
- scale = 1;
- let currentX = 0,
- currentY = 0,
- targetX = 0,
- targetY = 0;
- // 配置选项: 最小和最大缩放比例,是否启用缩放和拖动功能
- const minScale = options.minScale || container.offsetWidth / image.width;
- const maxScale = options.maxScale || 3;
- const dragSpeed = options.dragSpeed || 0.2;
- const enableZoom = options.enableZoom !== false; // 默认启用缩放
- const enableDrag = options.enableDrag !== false; // 默认启用拖动
- // 处理缩放功能
- if (enableZoom) {
- container.addEventListener("wheel", function (event) {
- event.preventDefault();
- const { offsetX, offsetY } = event;
- const delta = Math.sign(event.deltaY) * -0.1;
- const newScale = Math.min(Math.max(scale + delta, minScale), maxScale);
- const dx = (offsetX - currentX) * (newScale / scale - 1);
- const dy = (offsetY - currentY) * (newScale / scale - 1);
- scale = newScale;
- currentX -= dx;
- currentY -= dy;
- updateImageTransform();
- adjustPosition();
- });
- }
- // 处理拖动功能
- if (enableDrag) {
- image.addEventListener("mousedown", function (event) {
- isDragging = true;
- startX = event.clientX;
- startY = event.clientY;
- const transform = image.style.transform.match(/translate\(([^)]+)\)/);
- [initialX, initialY] = transform
- ? transform[1].split(",").map(parseFloat)
- : [0, 0];
- });
- document.addEventListener("mousemove", function (event) {
- if (isDragging) {
- const dx = event.clientX - startX;
- const dy = event.clientY - startY;
- targetX = initialX + dx;
- targetY = initialY + dy;
- requestAnimationFrame(updateDrag);
- }
- });
- function reset() {
- isDragging = false;
- }
- document.addEventListener("mouseleave", reset);
- document.addEventListener("mouseup", reset);
- }
- // 更新拖动的图像位置
- function updateDrag() {
- if (!isDragging) return;
- currentX += (targetX - currentX) * dragSpeed;
- currentY += (targetY - currentY) * dragSpeed;
- updateImageTransform();
- adjustPosition();
- requestAnimationFrame(updateDrag);
- }
- // 更新图像的变换样式
- function updateImageTransform() {
- image.style.transform = `translate(${currentX}px, ${currentY}px) scale(${scale})`;
- }
- // 调整图像位置以限制在容器内
- function adjustPosition() {
- const rect = image.getBoundingClientRect();
- const containerRect = container.getBoundingClientRect();
- let newX = rect.left - containerRect.left;
- let newY = rect.top - containerRect.top;
- if (rect.width < containerRect.width) {
- newX = (containerRect.width - rect.width) / 2;
- } else {
- if (newX > 0) newX = 0;
- if (newX + rect.width < containerRect.width)
- newX = containerRect.width - rect.width;
- }
- if (rect.height < containerRect.height) {
- newY = (containerRect.height - rect.height) / 2;
- } else {
- if (newY > 0) newY = 0;
- if (newY + rect.height < containerRect.height)
- newY = containerRect.height - rect.height;
- }
- currentX = newX;
- currentY = newY;
- updateImageTransform();
- }
- return () => {
- isDragging = false;
- startX = 0;
- startY = 0;
- initialX = 0;
- initialY = 0;
- scale = 1;
- currentX = 0;
- currentY = 0;
- targetX = 0;
- targetY = 0;
- };
- }
- // 全屏方法
- function fullScreenDisplay(dom) {
- /* 全屏操作的主要方法和属性
- * 不同浏览器需要添加不同的前缀
- * chrome:webkit firefox:moz ie:ms opera:o
- * 1.requestFullScreen():开启全屏显示
- * 2.cancelFullScreen():退出全屏显示:在不同的浏览器下退出全屏只能使用document来实现
- * 3.fullScreenElement:是否是全屏状态,也只能使用document进行判断
- */
- // 判断是否全屏,全屏则退出,非全屏则全屏
- if (
- document.fullscreenElement ||
- document.webkitFullscreenElement ||
- document.mozFullScreenElement ||
- document.msFullscreenElement
- ) {
- if (document.cancelFullScreen) {
- document.cancelFullScreen();
- } else if (document.webkitCancelFullScreen) {
- document.webkitCancelFullScreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- } else if (document.msCancelFullScreen) {
- document.msCancelFullScreen();
- }
- } else {
- dom
- .requestFullscreen()
- .then(() => {
- // 进入全屏成功
- })
- .catch(() => {
- // 进入全屏失败
- });
- }
- }
- const workerObj = {}; // 视频线程对象
- const partObj = {}; // 获取的细节对象
- let partActive = 1; // 细节框选中
- let stateObj = {
- qj: false,
- part1: false,
- part2: false,
- }; // 全景录像状态
- let partXY = {}; //双击全景的x y
- let resetSF = null;
- $(async function () {
- // const fingerprint = await getFingerprint();
- $("#controlgroup").controlgroup();
- $("button").button();
- $.each($("#controlgroup > input"), function (k, v) {
- $(v).on("input", async () => {
- $("#wsUrl").text(getAddress());
- });
- });
- function jt(worker) {
- worker && worker.postMessage({ type: "jt" });
- }
- function lx(WebSocketWork, type) {
- stateObj[type] = !stateObj[type];
- if (type === "qj") {
- stateObj[type] ? showCBInfo(`全景开始录像`) : showCBInfo(`全景结束录像`);
- } else {
- stateObj[type] ? showCBInfo(`细节开始录像`) : showCBInfo(`细节结束录像`);
- }
- WebSocketWork &&
- WebSocketWork.postMessage({
- type: "lx",
- lx: stateObj[type],
- });
- }
- $("#wsUrl").text(getAddress());
- $(".play-btn-qj").click(function () {
- showCBInfo("全景播放");
- if (workerObj["qj"]) {
- $(".close-btn-qj").click();
- }
- let [ip = ""] = [$("#Ip").val()];
- if (!ip) {
- alert("请完善全局配置");
- return;
- }
- $(".video-tip").show();
- workerObj["qj"] = useWorker(getAddress(), "#video-demo", null, () => {
- showCBInfo("全景播放完成");
- $(".video-tip").hide();
- });
- function jtClick() {
- showCBInfo(`全景开始截图`);
- jt(workerObj["qj"].worker);
- }
- function lxClick() {
- lx(workerObj["qj"].WebSocketWork, "qj");
- $(this).toggleClass("lx-style");
- }
- // 关闭
- $(".close-btn-qj").click(() => {
- if (!workerObj["qj"]) return;
- $(".jt-btn-qj").off("click");
- $(".lx-btn-qj").off("click");
- workerObj["qj"].close();
- resetVideo("#video-demo");
- workerObj["qj"] = null;
- showCBInfo(`全景关闭`);
- });
- // 截屏
- $(".jt-btn-qj").click(jtClick);
- // 录像
- $(".lx-btn-qj").click(lxClick);
- // 双击全景
- $(".panorama-box #video-demo").on("dblclick", function (e) {
- showCBInfo("细节播放");
- if (!workerObj["qj"]) return;
- const closePart = (index) => {
- if (!workerObj["part" + index]) return;
- workerObj["part" + index].close();
- resetVideo(`#video-demo${index}`);
- workerObj["part" + index] = null;
- showCBInfo(`关闭细节${partActive}`);
- };
- const { ratioX, ratioY, baseWidth, baseHeight } = getRatio(
- ".panorama-box #video-demo"
- );
- const mouseX = e.offsetX;
- const mouseY = e.offsetY;
- console.log("双击全景", mouseX, mouseY);
- const params = {
- X: `${mouseX / ratioX > baseWidth ? baseWidth : mouseX / ratioX}`,
- Y: `${mouseY / ratioY > baseHeight ? baseHeight : mouseY / ratioY}`,
- };
- partXY[partActive] = params;
- // 关闭细节
- closePart(partActive);
- $(`.video-tip${partActive}`).show();
- workerObj["part" + partActive] = useWorker(
- getAddress("Part", params),
- `#video-demo${partActive}`,
- null,
- () => {
- showCBInfo(`细节${partActive}播放完成`);
- $(`.video-tip${partActive}`).hide();
- resetSF = enableImageManipulation(
- `.particulars-box .wheel${partActive}`,
- `#video-demo${partActive}`,
- {
- enableZoom: true, // 启用缩放
- enableDrag: true, // 启用拖动
- minScale: 1, // 最小缩放比例
- maxScale: 6, // 最大缩放比例
- dragSpeed: 0.15, // 拖动速度
- }
- );
- }
- );
- $.each($(".particulars-box-list>li"), function (i, v) {
- $(v).find("button.close-btn-part").off("click");
- $(v).find("button.lx-btn-part").off("click");
- $(v).find("button.jt-btn-part").off("click");
- $(v).off("mousedown");
- $(v).off("mouseup");
- let index = i + 1;
- // 关闭
- $(v)
- .find("button.close-btn-part")
- .click(function () {
- closePart(index);
- });
- // 截图
- $(v)
- .find("button.jt-btn-part")
- .click(() => {
- showCBInfo(`细节开始截图`);
- jt(workerObj["part" + index]?.worker);
- });
- // 录像
- $(v)
- .find("button.lx-btn-part")
- .click(() => {
- lx(workerObj["part" + index]?.WebSocketWork, "part" + index);
- workerObj["part" + index] &&
- $(v).find("button.lx-btn-part").toggleClass("lx-style");
- });
- });
- });
- });
- $.each($(".particulars-box-list>li"), function (i, v) {
- let index = i + 1;
- $(v).click(function () {
- if (index === partActive) return;
- partActive = index;
- $(".particulars-box-list>li").removeClass("active");
- $(v).addClass("active");
- });
- $(`#video-demo${index}`)
- .parent(".video-container")
- .on("dblclick", function () {
- resetSF();
- $(`#video-demo${index}`).css("transform", "translate(0,0) scale(1)");
- fullScreenDisplay(this);
- });
- });
- });
|