commit e71073d709760526d625ce3eab1e6bc99f68690b Author: Cailean Finn Date: Tue Jun 25 22:40:24 2024 +0100 init commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..caf262c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.env +/node_modules/ +package-lock.json \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..b69fdbc --- /dev/null +++ b/app.py @@ -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) \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..246fe08 --- /dev/null +++ b/package.json @@ -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" +} diff --git a/public/css/styles.css b/public/css/styles.css new file mode 100644 index 0000000..301daea --- /dev/null +++ b/public/css/styles.css @@ -0,0 +1,205 @@ +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@100..900&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 { + + } +} \ No newline at end of file diff --git a/public/images/dither-txt.png b/public/images/dither-txt.png new file mode 100644 index 0000000..ec8ef0b Binary files /dev/null and b/public/images/dither-txt.png differ diff --git a/public/images/fine.png b/public/images/fine.png new file mode 100644 index 0000000..cca0cfa Binary files /dev/null and b/public/images/fine.png differ diff --git a/public/images/skybox.png b/public/images/skybox.png new file mode 100644 index 0000000..b5b0462 Binary files /dev/null and b/public/images/skybox.png differ diff --git a/public/js/main.js b/public/js/main.js new file mode 100644 index 0000000..6f77235 --- /dev/null +++ b/public/js/main.js @@ -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() + diff --git a/public/js/skybox.js b/public/js/skybox.js new file mode 100644 index 0000000..ad7beab --- /dev/null +++ b/public/js/skybox.js @@ -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() \ No newline at end of file diff --git a/templates/index.html b/templates/index.html new file mode 100644 index 0000000..a52cf9e --- /dev/null +++ b/templates/index.html @@ -0,0 +1,52 @@ + + + + + + Beta Festival 2024 + + + + +
+ +
+
+
+

+ 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. +

+
+ +
+
+
+ + + +