Browse Source

3d image

graphics
Cailean Finn 4 months ago
parent
commit
4c34ef4a90
  1. 2
      app.py
  2. 44
      public/css/styles.css
  3. BIN
      public/images/favicon/beta-favicon-192x192.png
  4. BIN
      public/images/favicon/beta-favicon-32x32.png
  5. 143
      public/js/article.js
  6. 11
      templates/article.html
  7. 9
      templates/base.html
  8. 2
      templates/index.html
  9. 3
      templates/list.html

2
app.py

@ -16,7 +16,7 @@ client = contentful.Client(SPACE_ID, ACCESS_TOKEN)
@app.route('/') @app.route('/')
def index(): def index():
return render_template('index.html', title='Homepage') return render_template('index.html', title='')
@app.route('/events') @app.route('/events')
def events(): def events():

44
public/css/styles.css

@ -226,6 +226,8 @@ hr {
font-family: 'Syne Mono', monospace; font-family: 'Syne Mono', monospace;
color: #0075FF; color: #0075FF;
align-items: center; align-items: center;
overflow-x: hidden;
overflow-y: hidden;
} }
.page-info-cont { .page-info-cont {
@ -294,9 +296,14 @@ hr {
color: #0075FF; color: #0075FF;
} }
#container-article {
width: 100%;
height: 100%;
}
/* Tablet breakpoint (768px to 1024px) */ /* Tablet breakpoint (768px to 1024px) */
@media (max-width: 1024px) and (min-width: 768px) { @media (max-width: 1100px) and (min-width: 768px) {
#nav-bar { #nav-bar {
padding-left: 50px; padding-left: 50px;
padding-right: 50px; padding-right: 50px;
@ -323,15 +330,36 @@ hr {
} }
#article-container { #article-container {
display: flex;
flex-direction: column; flex-direction: column;
width: 100%;
height: 100%;
padding-top: 50px;
gap: 40px
}
#article-image {
order: 1;
width: 100%;
}
#article-text {
order: 2;
gap: 10px;
} }
#page-header { #page-header {
overflow: scroll; overflow-y: scroll;
overflow-x: hidden;
padding-right: 20px; padding-right: 20px;
padding-left: 20px; padding-left: 20px;
white-space: nowrap; white-space: nowrap;
} }
#container-article {
width: 100%;
height: 100%;
}
} }
/* Mobile breakpoint (less than 768px) */ /* Mobile breakpoint (less than 768px) */
@ -409,12 +437,12 @@ hr {
margin-left: 20px; margin-left: 20px;
margin-right: 20px; margin-right: 20px;
align-items: center; align-items: center;
padding-top: 25px; padding-top: 0px;
} }
#article-image { #article-image {
order: 1; order: 1;
flex: 0; width: 100%;
} }
#article-text { #article-text {
@ -440,7 +468,8 @@ hr {
} }
#page-header { #page-header {
overflow: scroll; overflow-y: scroll;
overflow-x: hidden;
height: 20px; height: 20px;
padding-right: 20px; padding-right: 20px;
padding-left: 20px; padding-left: 20px;
@ -455,4 +484,9 @@ hr {
.page-info-entry { .page-info-entry {
font-size: 20px; font-size: 20px;
} }
#container-article {
width: 100%;
height: 100%;
}
} }

BIN
public/images/favicon/beta-favicon-192x192.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

BIN
public/images/favicon/beta-favicon-32x32.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

143
public/js/article.js

@ -0,0 +1,143 @@
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
let container_element = document.getElementById('container-article')
let containerW = container_element.offsetWidth
let containerH = container_element.offsetHeight
let imgW, imgH, imgRatio
console.log(containerH, containerW)
var clock = new THREE.Clock();
function init(){
SetupRenderer()
scene = new THREE.Scene()
SetupCamera()
SetupControls()
composer = new EffectComposer( renderer );
const renderPixelatedPass = new RenderPixelatedPass( 1.2, scene, camera );
renderPixelatedPass.normalEdgeStrength = 1;
renderPixelatedPass.depthEdgeStrength = 1;
renderPixelatedPass.pixelAlignedPanning = false;
composer.addPass( renderPixelatedPass );
const outputPass = new OutputPass();
composer.addPass( outputPass );
AddLights()
const textureLoader = new THREE.TextureLoader()
textureLoader.crossOrigin = "Anonymous"
const texture = textureLoader.load(imageUrl, function ( tex ) {
// tex and texture are the same in this example, but that might not always be the case
console.log( tex.image.width, tex.image.height );
imgW = tex.image.width
imgH = tex.image.height
imgRatio = imgW / imgH
tex.minFilter = THREE.NearestFilter
tex.colorSpace = THREE.SRGBColorSpace;
tex.wrapS = THREE.RepeatWrapping;
tex.wrapT = THREE.RepeatWrapping;
const geom = new THREE.PlaneGeometry(imgRatio, 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(containerW, containerH)
document.getElementById('container-article').appendChild(renderer.domElement)
}
function SetupCamera(){
aspect = (containerW) / (containerH)
frustumSize = 1.5
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
controls.update()
let sin = Math.sin(clock.getElapsedTime() * 0.5)
mesh.rotation.z = sin * 0.1
mesh.rotation.x = sin * 0.15
composer.render()
}
function getContainerDimensions(){
containerW = container_element.offsetWidth
containerH = container_element.offsetHeight
}
window.addEventListener('resize', () => {
getContainerDimensions()
aspect = (containerW) / (containerH)
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(containerW, containerH)
})
init()

11
templates/article.html

@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}{{ title }}{% endblock %} {% block title %}{{ '| '+ title }}{% endblock %}
{% block content %} {% block content %}
<div id="main-wrapper"> <div id="main-wrapper">
@ -15,7 +15,7 @@
<div id="article-book">BOOK ↗</div> <div id="article-book">BOOK ↗</div>
</div> </div>
<div id="article-image"> <div id="article-image">
<img src="{{ article.image }}"> <div id="container-article"></div>
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
@ -35,10 +35,15 @@
<div class="page-info-title">/Location:</div> <div class="page-info-title">/Location:</div>
<div class="page-info-entry">{{ article.location[0] }}</div> <div class="page-info-entry">{{ article.location[0] }}</div>
</div> </div>
<script>
// Define a JavaScript variable using a Jinja variable
const imageUrl = "{{ article.image }}";
</script>
{% endfor %} {% endfor %}
</div> </div>
</div> </div>
<div id="container"></div>
<script type="module" src="{{ url_for('static', filename='js/skybox.js') }}"></script> <script type="module" src="{{ url_for('static', filename='js/skybox.js') }}"></script>
<script type="module" src="{{ url_for('static', filename='js/scrollbar.js') }}"></script> <script type="module" src="{{ url_for('static', filename='js/scrollbar.js') }}"></script>
<script type="module" src="{{ url_for('static', filename='js/article.js') }}"></script>
{% endblock content %} {% endblock content %}

9
templates/base.html

@ -3,8 +3,15 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Beta Festival 2024 | {% block title %}{% endblock %}</title> <meta name="description" content="Art and Technology Festival Ireland 2024" />
<meta name="keywords" content="beta festival, 2024, dublin, art and technology, digital art" />
<meta name="robots" content="index,follow" />
<meta name="language" content="en-ie" />
<title>Beta Festival 2024 {% block title %}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}"> <link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='css/styles.css') }}">
<link rel="icon" type="image/png" href="{{ url_for('static', filename='images/favicon/beta-favicon-32x32.png') }}" sizes="32x32">
<link rel="icon" type="image/png" href="{{ url_for('static', filename='images/favicon/beta-favicon-192x192.png') }}" sizes="192x192">
<script type="importmap"> <script type="importmap">
{ {
"imports": { "imports": {

2
templates/index.html

@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}{{ title }}{% endblock %} {% block title %}{% if title %}{{ '| '+ title }}{% endif %}{% endblock %}
{% block content %} {% block content %}
<div id="main-wrapper"> <div id="main-wrapper">

3
templates/list.html

@ -1,6 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% block title %}{{ title }}{% endblock %} {% block title %}{{ '| '+ title }}{% endblock %}
{% block content %} {% block content %}
<div id="main-wrapper"> <div id="main-wrapper">
@ -35,5 +35,4 @@
</div> </div>
<div id="container"></div> <div id="container"></div>
<script type="module" src="{{ url_for('static', filename='js/list.js') }}"></script> <script type="module" src="{{ url_for('static', filename='js/list.js') }}"></script>
<script type="module" src="{{ url_for('static', filename='js/skybox.js') }}"></script>
{% endblock content %} {% endblock content %}
Loading…
Cancel
Save