<template>
<section class="content-center gap-8 md:gap-9 grid grid-flow-row-dense items-center justify-center justify-items-center p-5">
<!-- Third Man Records -->
<img id="third-man-records" src="https://assets.codepen.io/141041/Third+Man+Records.svg" alt="Third Man Records" class="w-72 md:w-96" />
<div id="visual" class="h-56 md:h-72 relative w-56 md:w-72">
<!-- Three JS Globe -->
<canvas id="three"></canvas>
<!-- Bottom Left Note -->
<img src="https://assets.codepen.io/141041/Third+Man+Records+Note.png" class="absolute left-0" style="bottom:20%;height:15%;width:15%" />
<!-- Top Right Double Note -->
<img src="https://assets.codepen.io/141041/Third+Man+Records+Double+Note.png" class="absolute right-0" style="height:15%;top:10%;width:15%" />
<!-- Top Right Note -->
<img src="https://assets.codepen.io/141041/Third+Man+Records+Note.png" class="absolute right-0" style="right:-20%;top:0%;height:15%;width:15%" />
</div>
<!-- Record -->
<img id="record" src="https://assets.codepen.io/141041/Third+Man+Records+Record.svg" alt="Record" class="w-60 md:w-80" />
<!-- Locations -->
<img id="locations" src="https://assets.codepen.io/141041/Third+Man+Records+Locations.svg" alt="Detroit . Nashville . London" class="w-60 md:w-80" />
</section>
</template>
<script>
export default{
methods: {
loadTexture(url) {
return new Promise((resolve, revoke) => {
// Initialize texture loader
const textureLoader = new THREE.TextureLoader()
// Load texture
textureLoader.load(url, (texture) => {
// Resolve
resolve(texture)
}, undefined, (error) => {
// Revoke
revoke(error)
})
})
},
async initializeThree() {
// Base
// ----------
// Get size
let { height, width } = document.getElementById('three').parentElement.getBoundingClientRect()
// Initialize scene
const scene = new THREE.Scene()
// Initialize camera
const camera = new THREE.PerspectiveCamera(20, 1, 0.1, 1000)
// Position camera
camera.position.z = 5.6
// Initialize renderer
const renderer = new THREE.WebGLRenderer({
alpha: true,
antialias: true,
canvas: document.getElementById('three')
})
// Set renderer pixel ratio
renderer.setPixelRatio(window.devicePixelRatio)
// Set renderer size
renderer.setSize(width, height)
// World
// ----------
// Load world texture
const worldTexture = await this.loadTexture('https://assets.codepen.io/141041/Third-Man-Records-Equirectangular.png')
// Initialize world geometry
const worldGeometry = new THREE.SphereGeometry(1, 20, 20)
// Initialize world material
const worldMaterial = new THREE.MeshBasicMaterial({
color: 0xFFD200,
map: worldTexture
})
// Initialize world
const world = new THREE.Mesh(worldGeometry, worldMaterial)
// Rotate world
world.rotation.y = THREE.MathUtils.degToRad(-25)
// Pivot
// ----------
// Add pivot group
const pivotGroup = new THREE.Group()
// Rotate pivot group
pivotGroup.rotation.z = THREE.MathUtils.degToRad(10)
// Add world to pivot group
pivotGroup.add(world)
// Add pivot group to scene
scene.add(pivotGroup)
// Rendering
// ----------
// Loop
const render = () => {
// Request animation frame
requestAnimationFrame(render)
// Rotate world
world.rotation.y -= 0.005
// Render scene
renderer.render(scene, camera)
}
// Render
render()
// Resizing
// ----------
// Listen for window resizing
window.addEventListener('resize', () => {
// Get size
let { height, width } = document.getElementById('three').parentElement.getBoundingClientRect()
// Resize renderer
renderer.setSize(width, height)
})
}
},
mounted() {
// Initialize Three
this.initializeThree()
// Tween notes with Greensock
gsap.to(document.getElementById('visual').getElementsByTagName('img'), {
duration: 2,
ease: "power1.inOut",
repeat: -1,
repeatRefresh: true,
y: "random(20%, 40%)",
yoyo: true
})
}
}
</script>
<style>
html, body, section{
height: 100%;
width: 100%;
}
body{
background: #FFD200;
}
canvas{
border: 2px solid black;
border-radius: 100%;
}
@media (min-width: 1024px) {
section{
gap: 5vh !important;
}
img#third-man-records{
width: 60vh;
}
#visual{
height: 40vh;
width: 40vh;
}
img#record{
width: 50vh;
}
img#locations{
width: 50vh;
}
}
</style>