Added main.js

This commit is contained in:
Plexi09 2026-02-22 23:05:51 +01:00
parent 33a8bd5385
commit 9770aa2be8
Signed by: Plexi09
GPG key ID: 20D439A69163544A

228
js/main.js Normal file
View file

@ -0,0 +1,228 @@
document.addEventListener('DOMContentLoaded', () => {
// 1. Initialize Lenis Smooth Scroll
const lenis = new Lenis({
duration: 1.2,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
direction: 'vertical',
gestureDirection: 'vertical',
smooth: true,
mouseMultiplier: 1,
smoothTouch: false,
touchMultiplier: 2,
infinite: false,
});
function raf(time) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
// 2. Preloader Animation
const tl = gsap.timeline();
tl.to('#loader-text', {
y: 0,
duration: 1,
ease: 'power4.out',
delay: 0.2
})
.to('#loader-text', {
y: '-100%',
duration: 1,
ease: 'power4.in',
delay: 0.5
})
.to('#preloader', {
y: '-100%',
duration: 1,
ease: 'power4.inOut'
}, '-=0.5')
.from('.hero-title', {
y: 100,
opacity: 0,
duration: 1.5,
stagger: 0.2,
ease: 'power4.out'
}, '-=0.5')
.to('.hero-subtitle', {
opacity: 1,
duration: 1,
ease: 'power2.out'
}, '-=1');
// 3. Custom Cursor
const cursor = document.getElementById('cursor');
const cursorDot = document.getElementById('cursor-dot');
const hoverTargets = document.querySelectorAll('.hover-target');
if (window.innerWidth >= 768) {
let mouseX = 0;
let mouseY = 0;
let cursorX = 0;
let cursorY = 0;
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
// Instant dot
gsap.to(cursorDot, {
x: mouseX,
y: mouseY,
duration: 0
});
});
// Smooth outer circle
gsap.ticker.add(() => {
cursorX += (mouseX - cursorX) * 0.2;
cursorY += (mouseY - cursorY) * 0.2;
gsap.set(cursor, { x: cursorX, y: cursorY });
});
hoverTargets.forEach(target => {
target.addEventListener('mouseenter', () => {
gsap.to(cursor, { scale: 2.5, backgroundColor: 'rgba(255,255,255,1)', duration: 0.3 });
gsap.to(cursorDot, { opacity: 0, duration: 0.3 });
});
target.addEventListener('mouseleave', () => {
gsap.to(cursor, { scale: 1, backgroundColor: 'transparent', duration: 0.3 });
gsap.to(cursorDot, { opacity: 1, duration: 0.3 });
});
});
}
// 4. Interactive Canvas Background (Particles)
const canvas = document.getElementById('hero-canvas');
const ctx = canvas.getContext('2d');
let width, height;
let particles = [];
function resize() {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
}
window.addEventListener('resize', resize);
resize();
class Particle {
constructor() {
this.x = Math.random() * width;
this.y = Math.random() * height;
this.vx = (Math.random() - 0.5) * 0.5;
this.vy = (Math.random() - 0.5) * 0.5;
this.radius = Math.random() * 1.5 + 0.5;
}
update() {
this.x += this.vx;
this.y += this.vy;
if (this.x < 0 || this.x > width) this.vx *= -1;
if (this.y < 0 || this.y > height) this.vy *= -1;
}
draw() {
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
ctx.fill();
}
}
for (let i = 0; i < 100; i++) {
particles.push(new Particle());
}
let mouse = { x: null, y: null };
window.addEventListener('mousemove', (e) => {
mouse.x = e.clientX;
mouse.y = e.clientY;
});
function animateParticles() {
ctx.clearRect(0, 0, width, height);
particles.forEach(p => {
p.update();
p.draw();
// Connect to mouse
if (mouse.x != null) {
const dx = mouse.x - p.x;
const dy = mouse.y - p.y;
const dist = Math.sqrt(dx * dx + dy * dy);
if (dist < 150) {
ctx.beginPath();
ctx.moveTo(p.x, p.y);
ctx.lineTo(mouse.x, mouse.y);
ctx.strokeStyle = `rgba(255, 255, 255, ${1 - dist/150})`;
ctx.lineWidth = 0.5;
ctx.stroke();
}
}
});
requestAnimationFrame(animateParticles);
}
animateParticles();
// 5. GSAP Scroll Animations
gsap.registerPlugin(ScrollTrigger);
// Reveal Text
const revealTexts = document.querySelectorAll('.reveal-text');
revealTexts.forEach(text => {
gsap.from(text, {
scrollTrigger: {
trigger: text,
start: 'top 80%',
},
y: 50,
opacity: 0,
duration: 1,
ease: 'power3.out'
});
});
// Parallax Images
const parallaxImgs = document.querySelectorAll('.parallax-img');
parallaxImgs.forEach(img => {
gsap.to(img, {
scrollTrigger: {
trigger: img.parentElement,
start: 'top bottom',
end: 'bottom top',
scrub: true
},
y: 50,
ease: 'none'
});
});
// Horizontal Scroll for Gallery
const gallery = document.getElementById('gallery');
let isDown = false;
let startX;
let scrollLeft;
gallery.addEventListener('mousedown', (e) => {
isDown = true;
gallery.classList.add('active');
startX = e.pageX - gallery.offsetLeft;
scrollLeft = gallery.scrollLeft;
});
gallery.addEventListener('mouseleave', () => {
isDown = false;
gallery.classList.remove('active');
});
gallery.addEventListener('mouseup', () => {
isDown = false;
gallery.classList.remove('active');
});
gallery.addEventListener('mousemove', (e) => {
if (!isDown) return;
e.preventDefault();
const x = e.pageX - gallery.offsetLeft;
const walk = (x - startX) * 2; // Scroll-fast
gallery.scrollLeft = scrollLeft - walk;
});
});