Cailean Finn
6 months ago
commit
e71073d709
10 changed files with 466 additions and 0 deletions
@ -0,0 +1,3 @@ |
|||||
|
.env |
||||
|
/node_modules/ |
||||
|
package-lock.json |
@ -0,0 +1,48 @@ |
|||||
|
from flask import Flask, render_template |
||||
|
import contentful |
||||
|
from dotenv import load_dotenv |
||||
|
import os |
||||
|
import datetime |
||||
|
|
||||
|
load_dotenv() |
||||
|
|
||||
|
app = Flask(__name__, static_folder='public') |
||||
|
|
||||
|
# Set your Contentful space ID and access token |
||||
|
SPACE_ID = os.getenv('SPACE_ID') |
||||
|
ACCESS_TOKEN = os.getenv('ACCESS_TOKEN') |
||||
|
|
||||
|
client = contentful.Client(SPACE_ID, ACCESS_TOKEN) |
||||
|
|
||||
|
@app.route('/') |
||||
|
def index(): |
||||
|
return render_template('index.html') |
||||
|
|
||||
|
def get_all_content(type): |
||||
|
content_list = [] |
||||
|
entries = client.entries({'content_type': type}) |
||||
|
for entry in entries: |
||||
|
date_time_obj = getattr(entry, f'{type}_date_time') |
||||
|
date_str, time_str = format_datetime(date_time_obj) |
||||
|
end_time_str = getattr(entry, f'{type}_end_date_time') |
||||
|
end_time_str = end_time_str.strftime('%I%p').upper().lstrip('0') |
||||
|
content = { |
||||
|
'title': getattr(entry, f'title_of_{type}'), |
||||
|
'information': getattr(entry, f'{type}_information'), |
||||
|
'image': 'https:{0}'.format(getattr(entry, f'{type}_reference_image').url()), |
||||
|
'artists': getattr(entry, f'{type}_artists'), |
||||
|
'date': date_str, |
||||
|
'time': time_str, |
||||
|
'end_time': end_time_str, |
||||
|
'location': getattr(entry, f'{type}_location') |
||||
|
} |
||||
|
content_list.append(content) |
||||
|
print(content_list) |
||||
|
|
||||
|
def format_datetime(dt): |
||||
|
date_str = dt.strftime('%d.%m.%y') |
||||
|
time_str = dt.strftime('%I%p').upper().lstrip('0') |
||||
|
return date_str, time_str |
||||
|
|
||||
|
if __name__ == '__main__': |
||||
|
app.run(debug=True) |
@ -0,0 +1,18 @@ |
|||||
|
{ |
||||
|
"name": "threejs-app", |
||||
|
"version": "1.0.0", |
||||
|
"description": "A simple Three.js application", |
||||
|
"main": "server.js", |
||||
|
"scripts": { |
||||
|
"start": "node server.js" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"body-parser": "^1.20.2", |
||||
|
"dotenv": "^16.4.5", |
||||
|
"express": "^4.17.1", |
||||
|
"three": "^0.164.1" |
||||
|
}, |
||||
|
"keywords": [], |
||||
|
"author": "", |
||||
|
"license": "ISC" |
||||
|
} |
@ -0,0 +1,205 @@ |
|||||
|
@import url('https://fonts.googleapis.com/css2?family=Inter:[email protected]&family=Syne+Mono&display=swap'); |
||||
|
|
||||
|
html { |
||||
|
padding: 0; |
||||
|
margin: 0; |
||||
|
} |
||||
|
|
||||
|
body { |
||||
|
font-family: 'Inter', sans-serif; |
||||
|
/* background-image: linear-gradient(rgb(255, 255, 255) 50%, #8fc3ff 100%); */ |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
overflow-x: hidden; |
||||
|
} |
||||
|
|
||||
|
#scroll { |
||||
|
background-image: |
||||
|
linear-gradient(to bottom, |
||||
|
white 0%, |
||||
|
white 30%, |
||||
|
rgba(255, 255, 255, 0) 100%), |
||||
|
url('/public/images/skybox.png'); |
||||
|
background-size: cover; |
||||
|
background-repeat: repeat-x; |
||||
|
} |
||||
|
|
||||
|
p { |
||||
|
margin: 0; |
||||
|
} |
||||
|
|
||||
|
a { |
||||
|
text-decoration: none; |
||||
|
color: #0075FF; |
||||
|
} |
||||
|
|
||||
|
hr { |
||||
|
border: 0; |
||||
|
clear:both; |
||||
|
display:block; |
||||
|
background-color:#0075FF; |
||||
|
width: 100%; |
||||
|
height: 2px; |
||||
|
z-index: -1000; |
||||
|
} |
||||
|
|
||||
|
#main-wrapper { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
min-height: 100vh; |
||||
|
} |
||||
|
|
||||
|
#nav-bar { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
justify-content: space-between; |
||||
|
padding-left: 50px; |
||||
|
padding-right: 50px; |
||||
|
padding-top: 40px; |
||||
|
padding-bottom: 40px; |
||||
|
} |
||||
|
|
||||
|
.nav-element { |
||||
|
font-size: 40px; |
||||
|
font-family: 'Syne Mono', monospace; |
||||
|
color: #0075FF; |
||||
|
} |
||||
|
|
||||
|
#main-container { |
||||
|
margin-top: 25px; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
gap: 50px; |
||||
|
margin-bottom: 50px; |
||||
|
margin-left: 50px; |
||||
|
margin-right: 50px; |
||||
|
} |
||||
|
|
||||
|
#main-text { |
||||
|
font-size: 26px; |
||||
|
width: 60%; |
||||
|
line-height: 40px; |
||||
|
color:#0075FF; |
||||
|
} |
||||
|
|
||||
|
#hyperlink-container { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
gap: 20px; |
||||
|
font-size: 30px; |
||||
|
color:#ffffff; |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
|
||||
|
.hyperlink { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
gap: 20px; |
||||
|
width: fit-content; |
||||
|
/* background-color: #0075FF; */ |
||||
|
background-image: url('/public/images/dither-txt.png'); |
||||
|
background-size: cover; /* or contain, depending on your preference */ |
||||
|
background-position: center; |
||||
|
background-repeat: no-repeat; |
||||
|
border-radius: 30px; |
||||
|
padding: 10px; |
||||
|
padding-left: 25px; |
||||
|
padding-right: 25px; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#hyperlink-container a{ |
||||
|
color: white; |
||||
|
} |
||||
|
|
||||
|
#container { |
||||
|
position: absolute; |
||||
|
top:0px; |
||||
|
left:0px; |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
z-index: -999; |
||||
|
} |
||||
|
|
||||
|
/* Tablet breakpoint (768px to 1024px) */ |
||||
|
@media (max-width: 1024px) and (min-width: 768px) { |
||||
|
#nav-bar { |
||||
|
padding-left: 50px; |
||||
|
padding-right: 50px; |
||||
|
padding-top: 20px; |
||||
|
padding-bottom: 20px; |
||||
|
} |
||||
|
|
||||
|
.nav-element { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#main-text { |
||||
|
width: 70%; |
||||
|
} |
||||
|
|
||||
|
#hyperlink-container { |
||||
|
flex-direction: column; |
||||
|
width: fit-content; |
||||
|
} |
||||
|
|
||||
|
.hyperlink { |
||||
|
padding-left: 5vw; |
||||
|
width: 80%; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* Mobile breakpoint (less than 768px) */ |
||||
|
@media (max-width: 768px) { |
||||
|
#nav-bar { |
||||
|
padding-left: 25px; |
||||
|
padding-right: 25px; |
||||
|
padding-top: 20px; |
||||
|
padding-bottom: 20px; |
||||
|
flex-direction: column; |
||||
|
text-align: center; |
||||
|
gap: 5px; |
||||
|
} |
||||
|
|
||||
|
.nav-element { |
||||
|
font-size: 20px; |
||||
|
} |
||||
|
|
||||
|
#main-container { |
||||
|
flex-direction: column-reverse; |
||||
|
margin-left: 10px; |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
#main-text { |
||||
|
font-size: 18px; |
||||
|
width: 80%; |
||||
|
padding-left: 0px; |
||||
|
text-align:justify; |
||||
|
line-height: 28px; |
||||
|
margin-left: auto; |
||||
|
margin-right: auto; |
||||
|
mix-blend-mode:multiply; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#hyperlink-container { |
||||
|
font-size: 24px; |
||||
|
flex-direction: column; |
||||
|
width: 100%; |
||||
|
padding-left: 0px; |
||||
|
align-items: normal; |
||||
|
} |
||||
|
|
||||
|
.hyperlink { |
||||
|
gap: 10px; |
||||
|
width: auto; |
||||
|
justify-content: center; |
||||
|
margin-left: 25px; |
||||
|
margin-right: 25px; |
||||
|
text-align: center; |
||||
|
} |
||||
|
|
||||
|
#container { |
||||
|
|
||||
|
} |
||||
|
} |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 79 KiB |
After Width: | Height: | Size: 228 KiB |
@ -0,0 +1,123 @@ |
|||||
|
import * as THREE from 'three' |
||||
|
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js' |
||||
|
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js'; |
||||
|
import { RenderPixelatedPass } from 'three/addons/postprocessing/RenderPixelatedPass.js'; |
||||
|
import { OutputPass } from 'three/addons/postprocessing/OutputPass.js'; |
||||
|
|
||||
|
let scene, camera, renderer |
||||
|
let aspect, frustumSize |
||||
|
let time = 0 |
||||
|
let lastTime = 0 |
||||
|
let controls |
||||
|
let mesh |
||||
|
let composer |
||||
|
|
||||
|
const texture = new THREE.TextureLoader().load("public/images/fine.png") |
||||
|
texture.minFilter = THREE.NearestFilter |
||||
|
texture.colorSpace = THREE.SRGBColorSpace; |
||||
|
texture.wrapS = THREE.RepeatWrapping; |
||||
|
texture.wrapT = THREE.RepeatWrapping; |
||||
|
|
||||
|
|
||||
|
function init(){ |
||||
|
SetupRenderer() |
||||
|
scene = new THREE.Scene() |
||||
|
SetupCamera() |
||||
|
SetupControls() |
||||
|
|
||||
|
composer = new EffectComposer( renderer ); |
||||
|
const renderPixelatedPass = new RenderPixelatedPass( 8, scene, camera ); |
||||
|
renderPixelatedPass.normalEdgeStrength = 0; |
||||
|
renderPixelatedPass.depthEdgeStrength = 1; |
||||
|
renderPixelatedPass.pixelAlignedPanning = false; |
||||
|
composer.addPass( renderPixelatedPass ); |
||||
|
|
||||
|
const outputPass = new OutputPass(); |
||||
|
composer.addPass( outputPass ); |
||||
|
|
||||
|
AddLights() |
||||
|
|
||||
|
const geom = new THREE.BoxGeometry(1, 1, 1) |
||||
|
const mat = new THREE.MeshPhongMaterial({map: texture}) |
||||
|
mesh = new THREE.Mesh(geom, mat) |
||||
|
scene.add(mesh) |
||||
|
animate() |
||||
|
} |
||||
|
|
||||
|
function SetupRenderer(){ |
||||
|
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }) |
||||
|
renderer.setClearColor(0xffffff, 0); |
||||
|
renderer.setSize(window.innerWidth, window.innerHeight) |
||||
|
document.getElementById('container').appendChild(renderer.domElement) |
||||
|
} |
||||
|
|
||||
|
function SetupCamera(){ |
||||
|
aspect = (window.innerWidth) / (window.innerHeight) |
||||
|
frustumSize = 2 |
||||
|
camera = new THREE.OrthographicCamera( |
||||
|
frustumSize * aspect / -2, |
||||
|
frustumSize * aspect / 2, |
||||
|
frustumSize / 2, |
||||
|
frustumSize / -2, |
||||
|
0.01, |
||||
|
5000 |
||||
|
) |
||||
|
|
||||
|
camera.position.x = 5 |
||||
|
} |
||||
|
|
||||
|
function SetupControls(){ |
||||
|
controls = new OrbitControls(camera, renderer.domElement) |
||||
|
controls.enableRotate = false; |
||||
|
controls.enablePan = false |
||||
|
controls.zoomToCursor = false; |
||||
|
controls.mouseButtons = { |
||||
|
RIGHT: THREE.MOUSE.ROTATE, |
||||
|
MIDDLE: THREE.MOUSE.DOLLY, |
||||
|
LEFT: THREE.MOUSE.PAN |
||||
|
} |
||||
|
camera.position.set(0, 0, 20) |
||||
|
controls.update() |
||||
|
} |
||||
|
|
||||
|
function AddLights() { |
||||
|
// Add Ambient Light
|
||||
|
const ambientLight = new THREE.AmbientLight(0xffffff, 3); // Soft white light
|
||||
|
scene.add(ambientLight); |
||||
|
|
||||
|
// Add Directional Light
|
||||
|
const directionalLight = new THREE.DirectionalLight(0xffffff, 0); // Soft white light
|
||||
|
directionalLight.position.set(-5, 0, 5).normalize(); |
||||
|
scene.add(directionalLight); |
||||
|
} |
||||
|
|
||||
|
function animate(){ |
||||
|
requestAnimationFrame(animate) |
||||
|
const deltaTime = (time - lastTime) / 1000 |
||||
|
lastTime = time |
||||
|
controls.update() |
||||
|
// Rotate the mesh on the x and z axes
|
||||
|
mesh.rotation.x += 0.001 |
||||
|
mesh.rotation.z += 0.001 |
||||
|
mesh.rotation.y += 0.001 |
||||
|
mesh.position.x = 1; |
||||
|
mesh.position.y = -0.1; |
||||
|
//texture.offset.x += 0.001;
|
||||
|
composer.render() |
||||
|
//renderer.render(scene, camera)
|
||||
|
} |
||||
|
|
||||
|
window.addEventListener('resize', () => { |
||||
|
aspect = (window.innerWidth) / (window.innerHeight) |
||||
|
camera.left = -frustumSize * aspect / 2 |
||||
|
camera.right = frustumSize * aspect / 2 |
||||
|
camera.top = frustumSize / 2 |
||||
|
camera.bottom = -frustumSize / 2 |
||||
|
camera.updateProjectionMatrix() |
||||
|
renderer.setPixelRatio(window.devicePixelRatio) |
||||
|
renderer.setSize(window.innerWidth, window.innerHeight) |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
init() |
||||
|
|
@ -0,0 +1,17 @@ |
|||||
|
const box = document.getElementById('scroll') |
||||
|
let x, y |
||||
|
|
||||
|
function init(){ |
||||
|
x = 0 |
||||
|
y = 0 |
||||
|
AnimateSkybox() |
||||
|
} |
||||
|
|
||||
|
function AnimateSkybox(){ |
||||
|
x += 0.2 |
||||
|
y = window.innerHeight / 2.2 |
||||
|
box.style.backgroundPosition = x + "px " + y + "px" |
||||
|
requestAnimationFrame(AnimateSkybox) |
||||
|
} |
||||
|
|
||||
|
init() |
@ -0,0 +1,52 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en"> |
||||
|
<head> |
||||
|
<meta charset="UTF-8"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
||||
|
<title>Beta Festival 2024</title> |
||||
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}"> |
||||
|
<script type="importmap"> |
||||
|
{ |
||||
|
"imports": { |
||||
|
"three": "https://cdn.jsdelivr.net/npm/[email protected]/build/three.module.js", |
||||
|
"three/addons/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/jsm/", |
||||
|
"three/src/": "https://cdn.jsdelivr.net/npm/[email protected]/src/", |
||||
|
"three/examples/": "https://cdn.jsdelivr.net/npm/[email protected]/examples/" |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
</head> |
||||
|
<body id="scroll"> |
||||
|
<div id="main-wrapper"> |
||||
|
<div id="nav-bar"> |
||||
|
<a href="/"><div class="nav-element">BETA FESTIVAL (2024)</div></a> |
||||
|
<div class="nav-element">NOV 1 - 2 | DUBLIN</div> |
||||
|
</div> |
||||
|
<hr> |
||||
|
<div id="main-container"> |
||||
|
<div id="main-text"> |
||||
|
<p> |
||||
|
Beta is a new festival of art and technology critically engaging with the impact of emerging technologies on society. Taking Ireland’s role as a central node in today's wired world as a starting point, Beta will showcase and celebrate Ireland’s research and artistic communities through a combination of creativity, debate and experimentation. Beta allows members of the public to engage playfully and critically with new technologies essentially beta testing ethical issues facing society. |
||||
|
</p> |
||||
|
</div> |
||||
|
<div id="hyperlink-container"> |
||||
|
<a href="/"><div class="hyperlink"> |
||||
|
<div>↗</div> |
||||
|
<div>Exhibitions</div> |
||||
|
</div></a> |
||||
|
<a href="/"><div class="hyperlink"> |
||||
|
<div>↗</div> |
||||
|
<div>Events</div> |
||||
|
</div></a> |
||||
|
<a href="/"><div class="hyperlink"> |
||||
|
<div>↗</div> |
||||
|
<div>Conferences</div> |
||||
|
</div></a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div id="container"></div> |
||||
|
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script> |
||||
|
<script type="module" src="{{ url_for('static', filename='js/skybox.js') }}"></script> |
||||
|
</body> |
||||
|
</html> |
Loading…
Reference in new issue