xxxxxxxxxx
let songs = [];
let backgrounds = [];
let currentSongIndex = 0;
let fft;
let particles = [];
function preload() {
songs[0] = loadSound("Dont Stop The Music.mp3");
songs[1] = loadSound("Back That Up To The Beat.mp3");
songs[2] = loadSound("On.mp3");
backgrounds[0] = loadImage("Rihanna (2).jpg");
backgrounds[1] = loadImage("Back That Up To The Beat.jpg");
backgrounds[2] = loadImage("BTS.jpg");
}
function setup() {
createCanvas(windowWidth, windowHeight);
// Açı kullanımı için radius yerine derece tanımladık.
angleMode(DEGREES);
// Arkaplan resimlerini merkezden hizaladık.
imageMode(CENTER);
// Arkaplandaki karaltıyı sağlayan dikdörtgenleri merkezden hizaladık.
rectMode(CENTER);
// FFT nesnesini oluşturup ve hassasiyeti ayarladık.
fft = new p5.FFT(0.02);
// Arka plan resimlerine bulanıklık efekti uyguladık.
for (let bg of backgrounds) {
bg.filter(BLUR, 4);
}
noLoop();
}
function draw() {
background(0);
// Canvas'ı ortalayıp merkez noktasını taşıdık.
translate(width / 2, height / 2);
// Müziği analiz ettik ve frekans ile genlik verilerini aldık.
fft.analyze();
let amp = fft.getEnergy(20, 200);
// Arka plan resmini hafif sallantılı çizdik.
push();
if (amp > 230) { // Genlik büyükse rastgele bir dönme efekti uyguladık.
rotate(random(-0.5, 0.5));
}
image(backgrounds[currentSongIndex], 0, 0, width + 50, height + 50);
pop();
// Şeffaf siyah bir dikdörtgen ile resmi hafif karalttık.
let alpha = map(amp, 0, 255, 180, 150); // Genliğe göre saydamlığını ayarladık.
fill(0, alpha);
noStroke();
rect(0, 0, width, height);
// Ses dalgası formunu dairesel bir şekilde çizdik.
stroke(255);
strokeWeight(3);
noFill();
drawWaveform();
// Partikülleri güncelleyip ekrana verdik.
particles.push(new Particle());
for (let i = particles.length - 1; i >= 0; i--) {
if (!particles[i].edges()) { // Partikül canvas dışından çıkıyor mu diye kontrol ettik.
particles[i].update(amp > 100); // Hareketini de genliğe göre hızlandırdık.
particles[i].show(); // Partikülleri çizdik.
} else {
particles.splice(i, 1); // Kenarı geçen partikülleri sildik.
}
}
}
// Dalga formunu "dairesel" olarak çizmemizi sağlayan fonksiyon.
function drawWaveform() {
let wave = fft.waveform(); // Dalga formunu aldık.
for (let t = -1; t <= 1; t += 2) { // Simetri için iki yönde çizdik.
beginShape();
for (let i = 0; i <= 180; i += 0.5) {
let index = floor(map(i, 0, 180, 0, wave.length - 1)); // Dalga formu indeksini haritaladık.
let r = map(wave[index], -1, 1, 150, 350); // Dalga formunun genliğini dairesel mesafeye haritaladık.
let x = r * sin(i) * t; // X koordinatı.
let y = r * cos(i); // Y koordinatı.
vertex(x, y); // Noktayı ekle.
}
endShape();
}
}
// Fareye tıklanırsa şarkıyı oynatıp durduran fonksiyon
function mouseClicked() {
if (songs[currentSongIndex].isPlaying()) {
songs[currentSongIndex].pause();
noLoop(); // Animasyonu durdur.
} else {
songs[currentSongIndex].play();
loop(); // Animasyonu başlat.
}
}
// Klavye tuşlarıyla şarkıyı değiştirmemizi sağlayan fonksiyon
function keyPressed() {
if (key === 'x' || key === 'X') {
changeSong(); // 'X' tuşuna basılırsa şarkıyı değiştir.
}
}
// Bir sonraki şarkıya geçiş yaptıran fonksiyon.
function changeSong() {
if (songs[currentSongIndex].isPlaying()) {
songs[currentSongIndex].stop(); // Şimdiki şarkıyı durdur.
}
currentSongIndex = (currentSongIndex + 1) % songs.length; // Sırayı arttır ama dizi boyutunu da aşma.
songs[currentSongIndex].play(); // Yeni şarkıyı direkt oynat.
}
// Partikülleri tanımlayan sınıf.
class Particle {
constructor() {
this.pos = p5.Vector.random2D().mult(250); // Rastgele bir pozisyon belirle
this.vel = createVector(0, 0); // Hız vektörünü başlat
this.acc = this.pos.copy().mult(random(0.0001, 0.00001)); // Hızlanma vektörü
this.w = random(3, 5); // Partiküllerin çapı
this.color = [random(200, 255), random(200, 255), random(200, 255)]; // Renk değerleri
}
update(cond) {
this.vel.add(this.acc); // İvme ekle
this.pos.add(this.vel); // Pozisyona hız ekle
if (cond) {
this.pos.add(this.vel.copy().mult(3)); // Sadece belirli bir şartta hızlandır
}
}
edges() {
// Partikül canvası aşıyor mu kontrol et
return (
this.pos.x < -width / 2 ||
this.pos.x > width / 2 ||
this.pos.y < -height / 2 ||
this.pos.y > height / 2
);
}
show() {
noStroke(); // Hiçbir stroke yok.
fill(this.color); // Renk ata
ellipse(this.pos.x, this.pos.y, this.w); // Partikülleri de çiz
}
}