/* html,
body
{
overflow: hidden;
} */
const renderer = new THREE.WebGLRenderer({
canvas: canvas,
alpha: true
})
html
{
background: #1e1a20;
}
// Material
const material = new THREE.MeshToonMaterial({ color: parameters.materialColor })
// Meshes
const mesh1 = new THREE.Mesh(
new THREE.TorusGeometry(1, 0.4, 16, 60),
material
)
const mesh2 = new THREE.Mesh(
new THREE.ConeGeometry(1, 2, 32),
material
)
const mesh3 = new THREE.Mesh(
new THREE.TorusKnotGeometry(0.8, 0.35, 100, 16),
material
)
scene.add(mesh1, mesh2, mesh3)
toonmaterial은 빛이 있을 때만 나타난다.
/**
* Lights
*/
const directionalLight = new THREE.DirectionalLight('#ffffff',3)
directionalLight.position.set(1,1,0)
scene.add(directionalLight)
// Texture
const textureLoader = new THREE.TextureLoader()
const gradientTexture= textureLoader.load('textures/gradients/3.jpg')
const material = new THREE.MeshToonMaterial({
color: parameters.materialColor,
gradientMap: gradientTexture
})
그러나 이렇게만 하면 우리가 원하는 3개의 gradient로만 나뉘지 않는다.
왜냐하면 Three.js에서 자동적으로 gradient texutre를 혼합해서 사용하기 때문이다.
이를 해결 하기 위해서 해당 texture의 magFilter를 NearestFilter로 변경해주어야한다.
gradientTexture.magFilter = THREE.NearestFilter
mesh1.position.y = 2
mesh1.scale.set(0.5, 0.5, 0.5)
mesh2.visible = false
mesh3.position.y = - 2
mesh3.scale.set(0.5, 0.5, 0.5)
const objectsDistance = 4
mesh1.position.y = - objectsDistance * 0
mesh2.position.y = - objectsDistance * 1
mesh3.position.y = - objectsDistance * 2
/**
* Scroll
*/
let scrollY = window.scrollY
window.addEventListener('scroll', () =>
{
scrollY = window.scrollY
console.log(scrollY)
})
const tick = () =>
{
// ...
// Animate camera
camera.position.y = -scrollY
// ...
}
camera.position.y = - scrollY / sizes.height * objectsDistance
const cursor = {}
cursor.x = 0
cursor.y = 0
window.addEventListener('mousemove', (event) =>
{
cursor.x = event.clientX / sizes.width - 0.5
cursor.y = event.clientY / sizes.height - 0.5
})
const tick = () =>
{
// ...
// Animate camera
camera.position.y = - scrollY / sizes.height * objectsDistance
const parallaxX = cursor.x
const parallaxY = -cursor.y
camera.position.x = parallaxX
camera.position.y = parallaxY
// ...
}
여기서 주의해야할 점은 cursor.y의 경우 아래로 내려가는게 마이너스 값이므로
camera position에 적용 할때는 - 한 값을 적용해준다.
/**
* Camera
*/
// Group
const cameraGroup = new THREE.Group()
scene.add(cameraGroup)
// Base camera
const camera = new THREE.PerspectiveCamera(35, sizes.width / sizes.height, 0.1, 100)
camera.position.z = 6
cameraGroup.add(camera)
const tick = () =>
{
// ...
// Animate camera
camera.position.y = - scrollY / sizes.height * objectsDistance
const parallaxX = cursor.x
const parallaxY = - cursor.y
cameraGroup.position.x = parallaxX
cameraGroup.position.y = parallaxY
// ...
}
cameraGroup.position.x += (parallaxX - cameraGroup.position.x) * 0.1
cameraGroup.position.y += (parallaxY - cameraGroup.position.y) * 0.1
const tick = () =>
{
const elapsedTime = clock.getElapsedTime()
const deltaTime = elapsedTime - previousTime
previousTime = elapsedTime
cameraGroup.position.x += (parallaxX - cameraGroup.position.x) * 5 * deltaTime
cameraGroup.position.y += (parallaxY - cameraGroup.position.y) * 5 * deltaTime
// ...
}
const particleCount = 2000
const particleMaterial = new THREE.PointsMaterial({
color: parameters.materialColor,
sizeAttenuation: true,
size: 0.03
})
const particleGeometry = new THREE.BufferGeometry()
const particlePosition = new Float32Array(particleCount*3)
for(let i=0;i<particleCount;i++){
const i3 = i*3
particlePosition[i3] = (Math.random()-0.5) * 10
particlePosition[i3+1] = (Math.random()-0.5) * 10
particlePosition[i3+2] = (Math.random()-0.5) * 10
}
particleGeometry.setAttribute('position', new THREE.BufferAttribute(particlePosition,3))
const particles = new THREE.Points(particleGeometry,particleMaterial)
scene.add(particles)
particlePosition[i3+1] = objectsDistance * 0.5 - Math.random()
objectsDistance * 0.5 - Math.random() * objectsDistance * sectionMeshes.length
let scrollY = window.scrollY
let currentSection = 0
window.addEventListener('scroll', () =>
{
scrollY = window.scrollY
const newSection = Math.round(scrollY / sizes.height)
if(newSection != currentSection)
{
currentSection = newSection
console.log('changed', currentSection)
}
})
import gsap from 'gsap'
window.addEventListener('scroll', () =>
{
// ...
if(newSection != currentSection)
{
// ...
gsap.to(
sectionMeshes[currentSection].rotation,
{
duration: 1.5,
ease: 'power2.inOut',
x: '+=6',
y: '+=3',
z: '+=1.5'
}
)
}
})
const tick = () =>
{
// ...
for(const mesh of sectionMeshes)
{
mesh.rotation.x += deltaTime * 0.1
mesh.rotation.y += deltaTime * 0.12
}
// ...
}
https://19-scroll-d0dcrj6r5-hwangsangjins-projects.vercel.app/