Cailean Finn
12 months ago
commit
8bfb336450
13 changed files with 1797 additions and 0 deletions
@ -0,0 +1 @@ |
|||||
|
## transmediale noura tafeche ## |
@ -0,0 +1,200 @@ |
|||||
|
const canvasContainer = document.getElementById('canvas-container'); |
||||
|
let zoomLevel = 0.15 |
||||
|
let stageX = 0 |
||||
|
let stageY = 0 |
||||
|
let myWindow |
||||
|
|
||||
|
// Create a Konva stage, which will be the entire w x h of the screen
|
||||
|
const stage = new Konva.Stage({ |
||||
|
container: 'canvas-container', |
||||
|
width: window.innerWidth, |
||||
|
height: window.innerHeight, |
||||
|
draggable: true, |
||||
|
}); |
||||
|
|
||||
|
// Create a Konva layer
|
||||
|
// This acts as a layer to add various shapes, images, groups to
|
||||
|
const layer = new Konva.Layer(); |
||||
|
|
||||
|
// Create a Konva image
|
||||
|
const image = new Konva.Image({ |
||||
|
draggable: false, |
||||
|
shadowColor: 'rgba(0, 0, 0, 0.5)', // Shadow color
|
||||
|
shadowBlur: 20, // Blur radius
|
||||
|
shadowOffset: { x: 0, y: 0 }, // Offset of the shadow
|
||||
|
shadowOpacity: 0, // Shadow opacity
|
||||
|
}); |
||||
|
|
||||
|
// Load the PNG image
|
||||
|
const imageURL = 'map.png'; // Replace with the path to your PNG image
|
||||
|
const imageObj = new Image(); |
||||
|
|
||||
|
imageObj.onload = function () { |
||||
|
// Set the image dimensions and center it in the stage
|
||||
|
image.width(imageObj.width); |
||||
|
image.height(imageObj.height); |
||||
|
|
||||
|
// Set the image source
|
||||
|
image.image(imageObj); |
||||
|
|
||||
|
// Add the image to the layer
|
||||
|
layer.add(image); |
||||
|
|
||||
|
const clickableRect = new Konva.Rect({ |
||||
|
id: 'public/test/lol', |
||||
|
x: 2635, // Adjust position as needed
|
||||
|
y: 441, // Adjust position as needed
|
||||
|
width: 655, |
||||
|
height: 45, |
||||
|
fill: 'rgba(255, 0, 0, 0.0)', // Red with 50% opacity
|
||||
|
draggable: false, |
||||
|
shadowColor: 'rgba(0, 0, 0, 0.5)', // Shadow color
|
||||
|
shadowBlur: 20, // Blur radius
|
||||
|
shadowOffset: { x: 0, y: 0 }, // Offset of the shadow
|
||||
|
shadowOpacity: 1, // Shadow opacity
|
||||
|
}); |
||||
|
|
||||
|
// Attach a click event listener to the rectangle
|
||||
|
clickableRect.on('click', () => { |
||||
|
// console.log(clickableRect.id())
|
||||
|
// // Data to send with the POST request
|
||||
|
// const postData = {
|
||||
|
// rectangleId: clickableRect.id()
|
||||
|
// };
|
||||
|
|
||||
|
// // Send POST request to the server
|
||||
|
// fetch('http://localhost:3000/api/change-directory', {
|
||||
|
// method: 'POST',
|
||||
|
// headers: {
|
||||
|
// 'Content-Type': 'application/json',
|
||||
|
// },
|
||||
|
// body: JSON.stringify(postData),
|
||||
|
// })
|
||||
|
// .then(response => response.json())
|
||||
|
// .then(data => {
|
||||
|
// console.log('Server response:', data);
|
||||
|
// })
|
||||
|
// .catch(error => {
|
||||
|
// console.error('Error sending POST request:', error);
|
||||
|
// });
|
||||
|
let linkName = '' |
||||
|
// Check if the window is already open
|
||||
|
if (myWindow && !myWindow.closed) { |
||||
|
// Reuse the existing window
|
||||
|
myWindow.location.href = 'http://localhost:3000/' + linkName; |
||||
|
} else { |
||||
|
// Open a new window and assign a unique name
|
||||
|
myWindow = window.open('http://localhost:3000/' + linkName, 'myWindow', 'width=600,height=400'); |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// Change cursor on hover
|
||||
|
clickableRect.on('mouseenter', () => { |
||||
|
document.body.style.cursor = 'pointer'; |
||||
|
}); |
||||
|
|
||||
|
clickableRect.on('mouseleave', () => { |
||||
|
document.body.style.cursor = 'default'; |
||||
|
}); |
||||
|
|
||||
|
// Add the clickable rectangle to the layer
|
||||
|
layer.add(clickableRect); |
||||
|
|
||||
|
// stage.scaleX(0.05)
|
||||
|
// stage.scaleY(0.05)
|
||||
|
// Center the stage initially
|
||||
|
// stage.x((stage.width() - image.width()) / 2);
|
||||
|
// stage.y((stage.height() - image.height()) / 2);
|
||||
|
|
||||
|
stage.x((stage.width()/2) - (image.width()/2) * 0.15) |
||||
|
stage.y((stage.height()/2) - (image.height()/2) * 0.15) |
||||
|
|
||||
|
|
||||
|
|
||||
|
stageX = stage.x() |
||||
|
stageY = stage.y() |
||||
|
|
||||
|
stage.scaleX(0.15) |
||||
|
stage.scaleY(0.15) |
||||
|
|
||||
|
// Add the layer to the stage
|
||||
|
stage.add(layer); |
||||
|
|
||||
|
layer.batchDraw(); |
||||
|
}; |
||||
|
|
||||
|
imageObj.src = imageURL; |
||||
|
|
||||
|
// Add the image to the layer
|
||||
|
layer.add(image); |
||||
|
|
||||
|
// Add the layer to the stage
|
||||
|
stage.add(layer); |
||||
|
|
||||
|
|
||||
|
// Handle zoom in and zoom out
|
||||
|
window.addEventListener('wheel', (e) => { |
||||
|
e.preventDefault(); |
||||
|
|
||||
|
const oldScale = stage.scaleX(); |
||||
|
|
||||
|
// Calculate the new scale based on the wheel delta
|
||||
|
zoomLevel += e.deltaY * -0.001; |
||||
|
zoomLevel = Math.max(0.15, Math.min(0.8, zoomLevel)); |
||||
|
console.log(zoomLevel) |
||||
|
|
||||
|
// Calculate the new scale factor
|
||||
|
const scale = zoomLevel / oldScale; |
||||
|
|
||||
|
// Calculate the cursor position relative to the stage
|
||||
|
const pointer = stage.getPointerPosition(); |
||||
|
const pointerX = pointer.x - stageX; |
||||
|
const pointerY = pointer.y - stageY; |
||||
|
|
||||
|
// Adjust the stage position to zoom around the cursor
|
||||
|
stageX -= pointerX * (scale - 1); |
||||
|
stageY -= pointerY * (scale - 1); |
||||
|
|
||||
|
// Set the new scale and position of the stage
|
||||
|
stage.scaleX(zoomLevel); |
||||
|
stage.scaleY(zoomLevel); |
||||
|
stage.x(stageX); |
||||
|
stage.y(stageY); |
||||
|
|
||||
|
layer.batchDraw(); |
||||
|
}, { passive: false }); |
||||
|
|
||||
|
// Slow down dragging based on the current scale
|
||||
|
const dragSpeedFactor = 0.5; // Adjust this value to control the drag speed
|
||||
|
|
||||
|
// Reset stage position on drag
|
||||
|
stage.on('dragstart', () => { |
||||
|
stageX = stage.x(); |
||||
|
stageY = stage.y(); |
||||
|
}); |
||||
|
|
||||
|
stage.on('dragmove', (e) => { |
||||
|
// Calculate drag speed factor based on scale
|
||||
|
|
||||
|
const dragSpeedFactor = 0.5 + (1-stage.scaleX()) * 1; // Adjust the multiplier as needed
|
||||
|
|
||||
|
const offsetX = e.evt.movementX * dragSpeedFactor * stage.scaleX(); |
||||
|
const offsetY = e.evt.movementY * dragSpeedFactor * stage.scaleY(); |
||||
|
|
||||
|
stageX += offsetX; |
||||
|
stageY += offsetY; |
||||
|
|
||||
|
stage.x(stageX); |
||||
|
stage.y(stageY); |
||||
|
|
||||
|
layer.batchDraw(); |
||||
|
}); |
||||
|
|
||||
|
stage.on('dragend', () => { |
||||
|
stageX = stage.x(); |
||||
|
stageY = stage.y(); |
||||
|
}); |
||||
|
|
||||
|
document.addEventListener('contextmenu', event => { |
||||
|
event.preventDefault(); |
||||
|
}); |
@ -0,0 +1,14 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
|
<title>transmediale</title> |
||||
|
<link rel="stylesheet" href="styles.css"> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div id="canvas-container"></div> |
||||
|
<script src="https://unpkg.com/konva@9/konva.min.js"></script> |
||||
|
<script src="app.js"></script> |
||||
|
</body> |
||||
|
</html> |
@ -0,0 +1,47 @@ |
|||||
|
{ |
||||
|
"sections": [ |
||||
|
{ |
||||
|
"section_name": "Adorability-Fundementalism", |
||||
|
"links": [ |
||||
|
{ |
||||
|
"id": "Title", |
||||
|
"width": 665, |
||||
|
"height": 45, |
||||
|
"x": 2635, |
||||
|
"y": 440, |
||||
|
"url": "adorability-fundementalism" |
||||
|
}, |
||||
|
{ |
||||
|
"id": "HistoryKawaii", |
||||
|
"width": 370, |
||||
|
"height": 45, |
||||
|
"x": 2525, |
||||
|
"y": 593, |
||||
|
"url": "history-of-kawaii" |
||||
|
}, |
||||
|
{ |
||||
|
"id": "CuteFactor", |
||||
|
"width": 285, |
||||
|
"height": 45, |
||||
|
"x": 2475, |
||||
|
"y": 1346, |
||||
|
"url": "cute-factor" |
||||
|
} |
||||
|
] |
||||
|
}, |
||||
|
{ |
||||
|
"section_name": "Kawaii-ASMR", |
||||
|
"links": [ |
||||
|
{ |
||||
|
"id": "Title", |
||||
|
"width": 266, |
||||
|
"height": 45, |
||||
|
"x": 4137, |
||||
|
"y": 447, |
||||
|
"url": "kawaii-asmr" |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
] |
||||
|
} |
After Width: | Height: | Size: 30 MiB |
@ -0,0 +1,23 @@ |
|||||
|
body { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
height: 100%; |
||||
|
overflow: hidden; |
||||
|
background-color: #F4F4F5; |
||||
|
/* background-image: |
||||
|
linear-gradient(45deg, #cccccc 25%, transparent 25%), |
||||
|
linear-gradient(135deg, #ccc 25%, transparent 25%), |
||||
|
linear-gradient(45deg, transparent 75%, #ccc 75%), |
||||
|
linear-gradient(135deg, transparent 75%, #ccc 75%); |
||||
|
background-size:25px 25px; /* Must be a square */ |
||||
|
/* background-position:0 0, 12.5px 0, 12.5px -12.5px, 0px 12.5px; Must be half of one side of the square */ |
||||
|
} |
||||
|
|
||||
|
#canvas-container { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
@ -0,0 +1,41 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
|
<title>Custom Directory Listing</title> |
||||
|
<style> |
||||
|
/* Add your custom styles here */ |
||||
|
body { |
||||
|
font-family: Arial, sans-serif; |
||||
|
margin: 20px; |
||||
|
} |
||||
|
h1 { |
||||
|
color: #333; |
||||
|
} |
||||
|
ul { |
||||
|
list-style-type: none; |
||||
|
padding: 0; |
||||
|
} |
||||
|
li { |
||||
|
margin-bottom: 10px; |
||||
|
} |
||||
|
a { |
||||
|
text-decoration: none; |
||||
|
color: #1a0dab; |
||||
|
} |
||||
|
a:hover { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
|
||||
|
<h1>Custom Directory Listing</h1> |
||||
|
|
||||
|
<ul> |
||||
|
{files} |
||||
|
</ul> |
||||
|
|
||||
|
</body> |
||||
|
</html> |
File diff suppressed because it is too large
@ -0,0 +1,18 @@ |
|||||
|
{ |
||||
|
"name": "24_01-transmediale-server", |
||||
|
"version": "1.0.0", |
||||
|
"description": "", |
||||
|
"main": "index.js", |
||||
|
"scripts": { |
||||
|
"test": "echo \"Error: no test specified\" && exit 1" |
||||
|
}, |
||||
|
"keywords": [], |
||||
|
"author": "", |
||||
|
"license": "ISC", |
||||
|
"dependencies": { |
||||
|
"body-parser": "^1.20.2", |
||||
|
"cors": "^2.8.5", |
||||
|
"express": "^4.18.2", |
||||
|
"serve-index": "^1.9.1" |
||||
|
} |
||||
|
} |
After Width: | Height: | Size: 1.5 MiB |
@ -0,0 +1 @@ |
|||||
|
hello |
Binary file not shown.
@ -0,0 +1,105 @@ |
|||||
|
// const express = require('express');
|
||||
|
// const serveIndex = require('serve-index');
|
||||
|
// const bodyParser = require('body-parser');
|
||||
|
// const path = require('path');
|
||||
|
// const cors = require('cors');
|
||||
|
|
||||
|
// const app = express();
|
||||
|
// const port = 3000;
|
||||
|
|
||||
|
// // Enable CORS for all routes
|
||||
|
// app.use(cors());
|
||||
|
|
||||
|
// app.use(bodyParser.json());
|
||||
|
|
||||
|
// // Initial directory path
|
||||
|
// let currentDirectory = path.join(__dirname, 'public');
|
||||
|
|
||||
|
// // Set root path for directory listing
|
||||
|
// app.use('/', express.static(currentDirectory), serveIndex(currentDirectory, { icons: true }));
|
||||
|
|
||||
|
// // Start the server
|
||||
|
// app.listen(port, () => {
|
||||
|
// console.log(`Server is running on http://localhost:${port}`);
|
||||
|
// });
|
||||
|
|
||||
|
|
||||
|
const express = require("express"); |
||||
|
const path = require("path"); |
||||
|
const fs = require("fs"); |
||||
|
const app = express(); |
||||
|
|
||||
|
const listingPath = path.join(__dirname, "public"); |
||||
|
|
||||
|
app.get("*", (req, res) => { |
||||
|
const decodedPath = decodeURIComponent(req.path); |
||||
|
const filePath = path.join(listingPath, decodedPath); |
||||
|
|
||||
|
if (!fs.existsSync(filePath)) { |
||||
|
return res.status(404).end(); |
||||
|
} |
||||
|
|
||||
|
if (fs.statSync(filePath).isDirectory()) { |
||||
|
const filesInDir = fs.readdirSync(filePath); |
||||
|
const links = filesInDir.map(file => { |
||||
|
const encodedFile = encodeURIComponent(file); |
||||
|
const fileLink = path.join(req.path, encodedFile); |
||||
|
|
||||
|
let linkAttributes = ""; |
||||
|
let fileLocationEncoding = "" |
||||
|
console.log(fileLink) |
||||
|
let convertedString = fileLink.replace(/\\/g, '/'); |
||||
|
console.log(convertedString) |
||||
|
// Check if the file is of a specific type that should open in a new window/tab
|
||||
|
const fileExtension = path.extname(file).toLowerCase(); |
||||
|
if (isFileTypeToOpenInNewTab(fileExtension)) { |
||||
|
fileLocationEncoding = 'http://localhost:3000/' + convertedString |
||||
|
linkAttributes = `onclick="window.open('${fileLocationEncoding}', 'fileWindow', 'width=600,height=400');"`; |
||||
|
return `<li ${linkAttributes}>${file}</li>`; |
||||
|
} else { |
||||
|
return `<li><a href="${fileLink}" ${linkAttributes}>${file}</a></li>`; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
}); |
||||
|
|
||||
|
return res.send(`<ul>${links.join("")}</ul>`); |
||||
|
} else { |
||||
|
const fileExtension = path.extname(filePath).toLowerCase(); |
||||
|
|
||||
|
if (fileExtension === ".pdf") { |
||||
|
// For PDF files, send the file to be displayed in the browser.
|
||||
|
const fileStream = fs.createReadStream(filePath); |
||||
|
fileStream.pipe(res); |
||||
|
} else { |
||||
|
// For other file types, set content type and send file.
|
||||
|
const contentType = getContentType(fileExtension); |
||||
|
res.set("Content-Type", contentType); |
||||
|
return res.sendFile(filePath); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
|
||||
|
// Function to get content type based on file extension
|
||||
|
function getContentType(fileExtension) { |
||||
|
switch (fileExtension) { |
||||
|
case ".txt": |
||||
|
return "text/plain"; |
||||
|
case ".png": |
||||
|
return "image/png"; |
||||
|
// Add more content types as needed
|
||||
|
default: |
||||
|
return "application/octet-stream"; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// Function to check if the file type should open in a new window/tab
|
||||
|
function isFileTypeToOpenInNewTab(fileExtension) { |
||||
|
const supportedFileTypes = [".pdf", ".png", ".txt"]; // Add more file types as needed
|
||||
|
return supportedFileTypes.includes(fileExtension); |
||||
|
} |
||||
|
|
||||
|
const PORT = 3000; |
||||
|
app.listen(PORT, () => { |
||||
|
console.log("Server is running on http://localhost:" + PORT); |
||||
|
}); |
Loading…
Reference in new issue