mirror of
https://github.com/TheGreyDiamond/open360viewer.git
synced 2025-07-17 20:33:48 +02:00
Finally some cool ui
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
package-lock.json
|
||||
node_modules
|
||||
node_modules
|
||||
dist/*
|
33
index.js
33
index.js
@ -1,4 +1,11 @@
|
||||
const { app, BrowserWindow, protocol, Menu, dialog } = require("electron");
|
||||
const {
|
||||
app,
|
||||
BrowserWindow,
|
||||
protocol,
|
||||
Menu,
|
||||
dialog,
|
||||
ipcMain,
|
||||
} = require("electron");
|
||||
const url = require("url");
|
||||
const path = require("path");
|
||||
|
||||
@ -53,7 +60,7 @@ function createStartupInfo() {
|
||||
|
||||
win2.setFullScreen(false);
|
||||
win2.setAlwaysOnTop(false);
|
||||
win2.loadFile("ui_templates/about.html");
|
||||
win2.loadFile("dist/ui_templates/about.html");
|
||||
win2.show();
|
||||
return win2;
|
||||
}
|
||||
@ -70,7 +77,7 @@ function createWindow() {
|
||||
|
||||
win.loadURL(
|
||||
url.format({
|
||||
pathname: path.join(__dirname, "index.html"),
|
||||
pathname: "dist/ui_templates/index.html",
|
||||
protocol: "file:",
|
||||
slashes: true,
|
||||
})
|
||||
@ -81,6 +88,24 @@ function createWindow() {
|
||||
}
|
||||
|
||||
app.on("ready", function () {
|
||||
// aWin2 = createStartupInfo();
|
||||
createWindow();
|
||||
|
||||
ipcMain.on("synchronous-message", (event, arg) => {
|
||||
console.log(arg);
|
||||
if (arg == "openFile") {
|
||||
dialog
|
||||
.showOpenDialog({ properties: ["openFile", "multiSelections"] })
|
||||
.then(function (data) {
|
||||
console.log(data);
|
||||
win.webContents.send("FileData", data);
|
||||
});
|
||||
} else if (arg == "resize") {
|
||||
// A really ugly hack to force the window to update, so the canvas shows up
|
||||
win.setSize(win.getSize()[0] + 1, win.getSize()[1]);
|
||||
setTimeout(function () {
|
||||
win.setSize(win.getSize()[0] + 1, win.getSize()[1]);
|
||||
}, 200);
|
||||
}
|
||||
event.returnValue = "";
|
||||
});
|
||||
});
|
||||
|
17
package.json
17
package.json
@ -2,16 +2,29 @@
|
||||
"name": "open360viewer",
|
||||
"version": "1.0.0",
|
||||
"description": "An opensource 360° image viewer written in NodeJS using Electron and Marzipano",
|
||||
"keywords": ["360", "image", "viewer"],
|
||||
"keywords": [
|
||||
"360",
|
||||
"image",
|
||||
"viewer"
|
||||
],
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "electron ."
|
||||
"start": "electron .",
|
||||
"startDev": "npm run buildCss && npm run minify && electron .",
|
||||
"minify": "minify src/main.js > dist/main.js && minify src/ui_templates/index.html > dist/ui_templates/index.html && minify src/ui_templates/about.html > dist/ui_templates/about.html",
|
||||
"buildCss": "npx tailwindcss -i ./src/main.css -o ./dist/output.css",
|
||||
"buildCssWatch": "npx tailwindcss -i ./src/main.css -o ./dist/output.css --watch"
|
||||
},
|
||||
"author": "TheGreydiamond",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@themesberg/flowbite": "^1.2.0",
|
||||
"electron": "^16.0.5",
|
||||
"marzipano": "^0.10.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tailwindcss": "^3.0.8",
|
||||
"minify": "^8.0.3"
|
||||
}
|
||||
}
|
||||
|
3
src/main.css
Normal file
3
src/main.css
Normal file
@ -0,0 +1,3 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
43
src/main.js
Normal file
43
src/main.js
Normal file
@ -0,0 +1,43 @@
|
||||
const { ipcRenderer, ipcMain } = require("electron");
|
||||
|
||||
ipcRenderer.on("FileData", function (event, data) {
|
||||
console.log(data);
|
||||
if (data.canceled == false) {
|
||||
// newPano(data.filePaths[0])
|
||||
document.getElementById("fakeDropzone").style.display = "none";
|
||||
document.getElementById("loadingBig").style.display = "block";
|
||||
document.getElementById("state").innerHTML =
|
||||
"Loading file. If this stays empty try another file.";
|
||||
loadImageFromSource(data.filePaths[0]);
|
||||
}
|
||||
});
|
||||
|
||||
function openFile() {
|
||||
ipcRenderer.sendSync("synchronous-message", "openFile");
|
||||
}
|
||||
|
||||
var viewer = new Marzipano.Viewer(document.getElementById("pano"));
|
||||
function newPano(path) {
|
||||
var sourceIm = Marzipano.ImageUrlSource.fromString(path);
|
||||
// Create scene.
|
||||
var scene = viewer.createScene({
|
||||
source: sourceIm,
|
||||
geometry: geometry,
|
||||
view: view,
|
||||
pinFirstLevel: true,
|
||||
});
|
||||
scene.switchTo();
|
||||
setTimeout(function () {
|
||||
scene.switchTo()
|
||||
}, 20);
|
||||
ipcRenderer.sendSync("synchronous-message", "resize");
|
||||
}
|
||||
|
||||
var geometry = new Marzipano.EquirectGeometry([{ width: 4000 }]);
|
||||
|
||||
// Create view.
|
||||
var limiter = Marzipano.RectilinearView.limit.traditional(
|
||||
4000,
|
||||
(120 * Math.PI) / 180
|
||||
);
|
||||
var view = new Marzipano.RectilinearView({ yaw: Math.PI }, limiter);
|
@ -1,37 +1,54 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<html class="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>360 Viewer</title>
|
||||
<script src="node_modules/marzipano/dist/marzipano.js">
|
||||
<script src="../../node_modules/marzipano/dist/marzipano.js">
|
||||
</script>
|
||||
<link href="./static/default.css" rel="stylesheet" />
|
||||
<link href="./static/fontawesome-free-5.15.1-web/css/all.css" rel="stylesheet">
|
||||
<link href="../output.css" rel="stylesheet">
|
||||
<link href="../../static/fontawesome-free-5.15.1-web/css/all.css" rel="stylesheet">
|
||||
<script src="../../node_modules/@themesberg/flowbite/dist/flowbite.bundle.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<body class="dark:bg-gray-800">
|
||||
<center>
|
||||
<h1 id="state"></h1>
|
||||
<div id="fakeDropzone" class="fakeDropzone">
|
||||
<i class="far fa-folder-open"></i><br>
|
||||
<a>Drag & Drop a file here</a>
|
||||
<des>or</des>
|
||||
<button>Browse Files</button>
|
||||
<h1 id="state" style="display: none;"></h1>
|
||||
<div id="fakeDropzone"
|
||||
class="border-4 rounded-lg border-dashed border-gray-700 dark:border-white dark:text-white w-96 mt-12">
|
||||
<i class="far fa-folder-open text-2xl mt-6"></i><br>
|
||||
<a class="text-lg">Drag & Drop a file here</a><br>
|
||||
<des class="text-gray-700">or</des><br>
|
||||
<button onclick="openFile()" type="button"
|
||||
class="z-40 text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Browse
|
||||
Files</button>
|
||||
</div>
|
||||
<div id="loadingBig" style="display: none;">
|
||||
<svg class="animate-spin h-5 w-5 h-24 text-white" xmlns="http://www.w3.org/2000/svg" fill="none"
|
||||
viewBox="0 0 24 24" id="loadingSpinner">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z">
|
||||
</path>
|
||||
</svg>
|
||||
</div>
|
||||
</center>
|
||||
|
||||
|
||||
<div id="pano">
|
||||
|
||||
</div>
|
||||
</body>
|
||||
|
||||
<script>
|
||||
document.getElementById("pano").style.display = "none";
|
||||
document.addEventListener('drop', (event) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
document.getElementById("fakeDropzone").style.display = "none";
|
||||
document.getElementById("loadingBig").style.display = "block";
|
||||
document.getElementById("state").innerHTML = "Loading file. If this stays empty try another file."
|
||||
|
||||
const superFile = event.dataTransfer.files[0].path;
|
||||
loadImageFromSource(superFile)
|
||||
});
|
||||
@ -53,7 +70,11 @@
|
||||
testImage(path,
|
||||
function (e, suc) {
|
||||
if (suc == "success") {
|
||||
newPano(path)
|
||||
document.getElementById("pano").style.display = "block";
|
||||
setTimeout(function() {
|
||||
newPano(path)
|
||||
}, 50);
|
||||
|
||||
}
|
||||
else {
|
||||
document.getElementById("state").innerHTML = "Load failed."
|
||||
@ -89,41 +110,7 @@
|
||||
}
|
||||
|
||||
</script>
|
||||
<script>
|
||||
const { ipcRenderer } = require('electron')
|
||||
|
||||
ipcRenderer.on('FileData', function (event, data) {
|
||||
console.log(data);
|
||||
if (data.canceled == false) {
|
||||
// newPano(data.filePaths[0])
|
||||
document.getElementById("state").innerHTML = "Loading file. If this stays empty try another file."
|
||||
loadImageFromSource(data.filePaths[0])
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
var viewer = new Marzipano.Viewer(document.getElementById('pano'));
|
||||
function newPano(path) {
|
||||
var sourceIm = Marzipano.ImageUrlSource.fromString(path);
|
||||
// Create scene.
|
||||
var scene = viewer.createScene({
|
||||
source: sourceIm,
|
||||
geometry: geometry,
|
||||
view: view,
|
||||
pinFirstLevel: true
|
||||
});
|
||||
scene.switchTo()
|
||||
}
|
||||
|
||||
|
||||
var geometry = new Marzipano.EquirectGeometry([{ width: 4000 }]);
|
||||
|
||||
// Create view.
|
||||
var limiter = Marzipano.RectilinearView.limit.traditional(4000, 120 * Math.PI / 180);
|
||||
var view = new Marzipano.RectilinearView({ yaw: Math.PI }, limiter);
|
||||
</script>
|
||||
|
||||
|
||||
<script src="../main.js"></script>
|
||||
<style>
|
||||
* {
|
||||
-webkit-box-sizing: border-box;
|
8
tailwind.config.js
Normal file
8
tailwind.config.js
Normal file
@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
content: ["./src/**/*.{html,js}"],
|
||||
darkMode: "media", // or 'media' or 'class'
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [require("@themesberg/flowbite/plugin")],
|
||||
};
|
Reference in New Issue
Block a user