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