* index68
const canvas = document.querySelector("#canvas-wrapper");
const scene = new THREE.Scene();
const fov = 95;
const nearDist = 0.1;
const farDist = 30000;
const sizes = {
w: window.innerWidth,
h: window.innerHeight
};
const camera = new THREE.PerspectiveCamera(
fov,
sizes.w / sizes.h,
nearDist,
farDist
);
camera.position.set(0, 0, Math.round(farDist / 16));
scene.add(camera);
// 렌더링
const renderer = new THREE.WebGLRenderer();
renderer.setClearColor("black");
renderer.setSize(sizes.w, sizes.h);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
canvas.appendChild(renderer.domElement);
// Custom shader
const uniforms = {
u_time: {
type: "f",
value: 1.0
},
u_resolution: {
type: "v2",
value: new THREE.Vector2()
}
};
const vertexShader = document.querySelector("#vertex").textContent;
const fragmentShader = document.querySelector("#fragment").textContent;
const shaderMaterial = new THREE.ShaderMaterial({
uniforms,
vertexShader,
fragmentShader,
transparent: true
});
function updateUniforms() {
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
}
updateUniforms();
// Resizing
window.addEventListener("resize", () => {
sizes.w = window.innerWidth;
sizes.h = window.innerHeight;
camera.aspect = sizes.w / sizes.h;
camera.updateProjectionMatrix();
renderer.setSize(sizes.w, sizes.h);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
updateUniforms();
});
const count = 8000;
const particlesPosition = [];
for (let i = 0; i < count; i++) {
const dist = count * 0.4;
const x = dist * 2 * Math.random() - dist;
const y = dist * 2 * Math.random() - dist;
const z = dist * 2 * Math.random() - dist;
particlesPosition.push(x, y, z);
}
const particlesGeometry = new THREE.BufferGeometry();
particlesGeometry.setAttribute(
"position",
new THREE.Float32BufferAttribute(particlesPosition, 3)
);
const particlesTexture = new THREE.TextureLoader().load(
"https://threejs.org/examples/textures/sprites/disc.png"
);
const particlesMaterial = new THREE.PointsMaterial({
color: "hotpink",
size: 20,
sizeAttenuation: true,
map: particlesTexture,
depthTest: false,
blending: THREE.AdditiveBlending
});
const particles = new THREE.Points(particlesGeometry, particlesMaterial);
scene.add(particles);
// Typograpghy
const typoGroup = new THREE.Group();
const typoLoader = new THREE.FontLoader();
const typoSize = Math.max(
sizes.w < 800 ? 1000 : 1200,
Math.round(sizes.w * 0.69)
);
const createTypo = (font) => {
const word = `webs`;
const typoProperties = {
font: font,
size: typoSize,
height: 20
};
const textMesh = new THREE.Mesh();
textMesh.geometry = new THREE.TextBufferGeometry(word, typoProperties);
textMesh.geometry.center();
textMesh.material = shaderMaterial;
typoGroup.add(textMesh);
};
typoLoader.load(
"https://threejs.org/examples/fonts/helvetiker_bold.typeface.json",
createTypo
);
scene.add(typoGroup);
// 마우스
let mouseX = 0;
let mouseY = 0;
const mouseFX = {
moveTypo(cX, cY) {
mouseX = (cX / sizes.w) * 2 - 1;
mouseY = -(cY / sizes.h) * 2 + 1;
const c = 3;
typoGroup.rotation.x = mouseY * c;
typoGroup.rotation.y = mouseX * c;
typoGroup.matrixAutoUpdate = false;
typoGroup.updateMatrix();
},
moveParticles(cX, cY) {
const c = 2;
mouseX = (cX - sizes.w * 0.5) * c;
mouseY = (cY - sizes.h * 0.5) * c;
},
onMouseMove(e) {
mouseFX.moveTypo(e.clientX, e.clientY);
mouseFX.moveParticles(e.clientX, e.clientY);
},
onTouchMove(e) {
const touchX = e.changedTouches[0].clientX;
const touchY = e.changedTouches[0].clientY;
mouseFX.moveTypo(touchX, touchY);
mouseFX.moveParticles(touchX, touchY);
}
};
document.addEventListener("mousemove", mouseFX.onMouseMove);
document.addEventListener("touchmove", mouseFX.onTouchMove);
// 애니메이션
const clock = new THREE.Clock();
const tick = () => {
const elapsedTime = clock.getElapsedTime();
uniforms.u_time.value = elapsedTime;
const rotX = Math.sin(elapsedTime * 0.8) * 0.3;
const rotY = Math.sin(elapsedTime * 1.2) * 0.3;
particles.rotation.x = rotX;
particles.rotation.y = rotY;
typoGroup.rotation.x = rotX;
typoGroup.rotation.y = rotY;
const cAnim = Math.sin(elapsedTime * 0.25);
particlesMaterial.color.setRGB(0.29 + cAnim, 0.5 - cAnim, 0.68 + cAnim);
const ease = 0.03;
camera.position.x += (mouseX - camera.position.x) * ease;
camera.position.y += (mouseY * -1 - camera.position.y) * ease;
camera.lookAt(scene.position);
renderer.render(scene, camera);
requestAnimationFrame(tick);
};
tick();