Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
… into fix-scroll
  • Loading branch information
Facu committed Feb 27, 2024
2 parents c0685b6 + a813bc2 commit f653771
Show file tree
Hide file tree
Showing 10 changed files with 406 additions and 371 deletions.
4 changes: 2 additions & 2 deletions src/components/HeroLogo.astro
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
fill="none"
viewBox="0 0 800 579"
role="img"
aria-label="Logotipo de la Velada 4"
><title>Logotipo de la Velada 4</title>
aria-label="Logotipo de La Velada 4"
>
<path
id="logo"
fill="currentColor"
Expand Down
216 changes: 110 additions & 106 deletions src/components/SmokeBackground.astro
Original file line number Diff line number Diff line change
Expand Up @@ -3,121 +3,125 @@
<script>
import * as THREE from "three"

const $bkg = document.getElementById("smoke-bkg")

let w = window.innerWidth
let h = window.screen.height

const THEME = {
dark: {
background: 0x666666,
light: 0xffffff,
opacity: 1,
},
light: {
background: 0xeeeeee,
light: 0xffffff,
opacity: 0.2,
},
} as const

const themePreference = window.getThemePreference()
let currentTheme = THEME[themePreference]

// inicializar Three.js
// 3 cosas básicas: escena, cámara, renderizador

// escena 🖼️
const scene = new THREE.Scene()

// camara 📹
// 75 -> ángulo de visión
const camera = new THREE.PerspectiveCamera(75, w / h, 1, 1000)
camera.position.z = 10
scene.add(camera)

// ▶️ renderizador
const renderer = new THREE.WebGLRenderer()
renderer.setSize(w, h)
// color de fondo
renderer.setClearColor(currentTheme.background, 1)

$bkg?.appendChild(renderer.domElement)

// añadir una luz directional
const light = new THREE.DirectionalLight(currentTheme.light, 0.5)
// posicion de la luz
light.position.set(-1, 3, 1)
scene.add(light)

const smokeParticles: THREE.Mesh[] = []

const loader = new THREE.TextureLoader()
loader.crossOrigin = "" // <- en localhost no pasa nada, pero si desplegamos a un servidor, puede ser necesario

loader.load("/smoke.webp", (texture) => {
// 1. geometria
// crear un plano geométrico de 300x300
const smokeGeo = new THREE.PlaneGeometry(300, 300)

// 2. material
const smokeMaterial = new THREE.MeshLambertMaterial({
map: texture,
transparent: true,
opacity: currentTheme.opacity,
})
const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)")

if (!reducedMotion.matches) {
const $bkg = document.getElementById("smoke-bkg")

let w = window.innerWidth
let h = window.screen.height

const THEME = {
dark: {
background: 0x666666,
light: 0xffffff,
opacity: 1,
},
light: {
background: 0xeeeeee,
light: 0xffffff,
opacity: 0.2,
},
} as const

const NUM_OF_PARTICLES = 300
for (let p = 0; p < NUM_OF_PARTICLES; p++) {
// crear la malla con la geometria y el material
const particle = new THREE.Mesh(smokeGeo, smokeMaterial)
// posicionar aleatoriamente
// en la x, y, z
particle.position.set(
Math.random() * 500 - 250, // X (de -250 a 250)
Math.random() * 500 - 250, // Y (de -250 a 250)
Math.random() * 1000 - 100 // Z (de -100 a 900)
)
// aleatoriamente la z
particle.rotation.z = Math.random() * 360
// añadimos la particula en la escena
scene.add(particle)
// añadimos la particula al array
smokeParticles.push(particle)
}
})
const themePreference = window.getThemePreference()
let currentTheme = THEME[themePreference]

function resize() {
h = window.screen.height
w = window.innerWidth
camera.aspect = w / h
camera.updateProjectionMatrix() // este metodo lo tenéis que ejecutar siempre que cambiais los parámetros de la cámara
renderer.setSize(w, h)
}
// inicializar Three.js
// 3 cosas básicas: escena, cámara, renderizador

function animate() {
requestAnimationFrame(animate)
// escena 🖼️
const scene = new THREE.Scene()

// camara 📹
// 75 -> ángulo de visión
const camera = new THREE.PerspectiveCamera(75, w / h, 1, 1000)
camera.position.z = 10
scene.add(camera)

// ▶️ renderizador
const renderer = new THREE.WebGLRenderer()
renderer.setSize(w, h)
// color de fondo
renderer.setClearColor(currentTheme.background, 1)

smokeParticles.forEach((particle) => {
particle.rotation.z += 0.001
$bkg?.appendChild(renderer.domElement)

// añadir una luz directional
const light = new THREE.DirectionalLight(currentTheme.light, 0.5)
// posicion de la luz
light.position.set(-1, 3, 1)
scene.add(light)

const smokeParticles: THREE.Mesh[] = []

const loader = new THREE.TextureLoader()
loader.crossOrigin = "" // <- en localhost no pasa nada, pero si desplegamos a un servidor, puede ser necesario

loader.load("/smoke.webp", (texture) => {
// 1. geometria
// crear un plano geométrico de 300x300
const smokeGeo = new THREE.PlaneGeometry(300, 300)

// 2. material
const smokeMaterial = new THREE.MeshLambertMaterial({
map: texture,
transparent: true,
opacity: currentTheme.opacity,
})

const NUM_OF_PARTICLES = 300
for (let p = 0; p < NUM_OF_PARTICLES; p++) {
// crear la malla con la geometria y el material
const particle = new THREE.Mesh(smokeGeo, smokeMaterial)
// posicionar aleatoriamente
// en la x, y, z
particle.position.set(
Math.random() * 500 - 250, // X (de -250 a 250)
Math.random() * 500 - 250, // Y (de -250 a 250)
Math.random() * 1000 - 100 // Z (de -100 a 900)
)
// aleatoriamente la z
particle.rotation.z = Math.random() * 360
// añadimos la particula en la escena
scene.add(particle)
// añadimos la particula al array
smokeParticles.push(particle)
}
})

renderer.render(scene, camera)
}
function resize() {
h = window.screen.height
w = window.innerWidth
camera.aspect = w / h
camera.updateProjectionMatrix() // este metodo lo tenéis que ejecutar siempre que cambiais los parámetros de la cámara
renderer.setSize(w, h)
}

animate()
function animate() {
requestAnimationFrame(animate)

// se va a disparar continuamente mientras hace el resize
window.addEventListener("resize", resize)
smokeParticles.forEach((particle) => {
particle.rotation.z += 0.001
})

window.addEventListener("theme-changed", () => {
const themePreference = window.getThemePreference()
currentTheme = THEME[themePreference]
light.color.setHex(currentTheme.light)
renderer.setClearColor(currentTheme.background, 1)
renderer.render(scene, camera)
}

smokeParticles.forEach((particle) => {
particle.material.opacity = currentTheme.opacity
animate()

// se va a disparar continuamente mientras hace el resize
window.addEventListener("resize", resize)

window.addEventListener("theme-changed", () => {
const themePreference = window.getThemePreference()
currentTheme = THEME[themePreference]
light.color.setHex(currentTheme.light)
renderer.setClearColor(currentTheme.background, 1)

smokeParticles.forEach((particle) => {
particle.material.opacity = currentTheme.opacity
})
})
})
}
</script>
Loading

0 comments on commit f653771

Please sign in to comment.