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