xxxxxxxxxx
357
let rings = []; // Array to store ring objects
let eyes = []; // Array to store eye objects
const numRings = 4; // Number of rings
const numEyePairsPerRing = [40, 50, 60, 80]; // Number of eye pairs for each ring
let angle = 0; // Angle for rotation animation
let eyeTexture; // Texture for the eyes
let cloudTexture; // Texture for the background clouds
let outerRingSpeed = 0.01; // Speed of the outer ring rotation
let innerRingSpeed = 0.01; // Speed of the inner ring rotation
let ringAcceleration = 0.0005; // Acceleration rate for ring rotation
let outerRingTimer = 0; // Timer for outer ring acceleration and deceleration
let innerRingTimer = 0; // Timer for inner ring acceleration and deceleration
let isOuterRingAccelerating = false; // Flag to track if outer ring is accelerating
let isInnerRingAccelerating = true; // Flag to track if inner ring is accelerating
let accelerationDuration = 240; // Duration of acceleration phase
let decelerationDuration = 900; // Duration of deceleration phase
let pauseDuration = 1200; // Duration of pause between acceleration and deceleration
let backgroundMusic; // Background music sound
let rotationSound; // Sound for ring rotation
let rotationSoundVolume = 0; // Volume of the rotation sound
let fadeOutStartTime = 0; // Start time for sound fade out
let fadeOutDuration = 60; // Duration of sound fade out
// Central attractor variables
let attractorAngle = 0; // Angle for central attractor rotation
let attractorRadius = 30; // Radius of the central attractor
let attractorSpeed = 0.005; // Speed of the central attractor rotation
// Vertical attractor variables
let verticalAttractorAngle1 = 0; // Angle for vertical attractor 1
let verticalAttractorAngle2 = 0; // Angle for vertical attractor 2
let verticalAttractorAngle3 = 0; // Angle for vertical attractor 3
let verticalAttractorAmplitude1 = 12; // Amplitude of vertical attractor 1
let verticalAttractorAmplitude2 = 7; // Amplitude of vertical attractor 2
let verticalAttractorAmplitude3 = 3; // Amplitude of vertical attractor 3
let verticalAttractorSpeed1 = 0.01; // Speed of vertical attractor 1
let verticalAttractorSpeed2 = 0.023; // Speed of vertical attractor 2
let verticalAttractorSpeed3 = 0.037; // Speed of vertical attractor 3
// Giant eye variables
let giantEyeSize = 50; // Size of the giant eye
let giantEyeBlink = 0; // Blinking state of the giant eye
let giantEyeBlinkSpeed = 0.1; // Speed of the giant eye blinking
let giantEyeRotationX = 0; // Rotation angle of the giant eye along the X-axis
let giantEyeRotationY = 0; // Rotation angle of the giant eye along the Y-axis
// Mouse over canvas check
let isMouseOverCanvas = false; // Flag to track if mouse is over the canvas
let distanceScale = 0.6; // Scaling factor for distances
let fogDensity = 0.2; // Density of the fog effect
let angelZ = -200; // Z position of the angel (main object)
let zoomLevel = 1; // Current zoom level
let zoomButton; // Button for zooming
let fogButton; // Button for toggling fog effect
let isFogEnabled = true; // Flag to track if fog effect is enabled
function preload() {
// Load assets (textures and sounds) before setup
eyeTexture = loadImage('eye.jpeg'); // Load eye texture
cloudTexture = loadImage('cloud2.png'); // Load cloud texture
backgroundMusic = loadSound('heaven3.mp3'); // Load background music
rotationSound = loadSound('rotation2.mp3'); // Load rotation sound
}
function setup() {
createCanvas(800, 800, WEBGL); // Create the canvas with WebGL context
// Create and position the zoom button
zoomButton = createButton('Zoom 2x');
zoomButton.position(width + 10, 10);
zoomButton.mousePressed(toggleZoom);
// Create and position the fog button
fogButton = createButton('Disable Fog');
fogButton.position(width + 10, 40);
fogButton.mousePressed(toggleFog);
// Define ring orientations
const ringOrientations = [
{ x: 0.62, y: 0.5, z: 0.1 },
{ x: 0.2, y: 0.1, z: 0.8 },
{ x: 0.4, y: 0.8, z: 0.2 },
{ x: 0.3, y: 0.5, z: 0.5 }
];
// Create ring objects and store them in the rings array
for (let i = 0; i < numRings; i++) {
rings.push({
radius: (150 + i * 60) * distanceScale, // Ring radius
tubeRadius: random(3, 6) * distanceScale, // Tube radius of the ring
rotation: createVector(
ringOrientations[i].x * TWO_PI,
ringOrientations[i].y * TWO_PI,
ringOrientations[i].z * TWO_PI
), // Rotation angles of the ring
speed: random(0.0005, 0.001), // Rotation speed of the ring
phase: random(TWO_PI), // Phase offset for the ring rotation
spin: 0 // Additional spin angle for the ring
});
}
// Create eye objects and store them in the eyes array
for (let i = 0; i < numRings; i++) {
for (let j = 0; j < numEyePairsPerRing[i]; j++) {
let angleStep = TWO_PI / numEyePairsPerRing[i]; // Angle step between eyes
let bigEyeAngle = j * angleStep; // Angle for the big eye
let smallEyeAngle = bigEyeAngle + angleStep / 2; // Angle for the small eye
let innerEyeAngleOffset = 0.1; // Angle offset for inner eyes
eyes.push(createEye(i, bigEyeAngle, random(10, 14) * distanceScale, false, 2.0, false)); // Create big eye
eyes.push(createEye(i, smallEyeAngle, random(5, 7) * distanceScale, true, 1.5, false)); // Create small eye
eyes.push(createEye(i, smallEyeAngle + innerEyeAngleOffset, random(8, 10) * distanceScale, true, -0.5, true)); // Create inner eye
}
}
backgroundMusic.loop(); // Start looping the background music
rotationSound.loop(); // Start looping the rotation sound
rotationSound.setVolume(0); // Set initial volume of the rotation sound to 0
}
function toggleZoom() {
// Toggle zoom level between 1x and 2x
if (zoomLevel === 1) {
zoomLevel = 2;
zoomButton.html('Reset Zoom');
} else {
zoomLevel = 1;
zoomButton.html('Zoom 2x');
}
}
function toggleFog() {
// Toggle fog effect on/off
isFogEnabled = !isFogEnabled;
if (isFogEnabled) {
fogButton.html('Disable Fog');
} else {
fogButton.html('Enable Fog');
}
}
function createEye(ring, angle, size, isSmall, offset, isInner) {
// Create an eye object with specified properties
return {
ring: ring, // Index of the ring the eye belongs to
angle: angle, // Angle of the eye on the ring
size: size, // Size of the eye
blinkTime: random(100), // Random blink time for the eye
isSmall: isSmall, // Flag to indicate if the eye is small
offset: offset, // Offset distance from the ring
isInner: isInner, // Flag to indicate if the eye is an inner eye
lookX: 0, // Initial look direction along the X-axis
lookY: 0, // Initial look direction along the Y-axis
targetX: 0, // Target look direction along the X-axis
targetY: 0, // Target look direction along the Y-axis
movementSpeed: random(0.1, 0.3), // Speed of eye movement
nextMovementTime: random(30, 120) // Time until next eye movement
};
}
function updateEyeMovement(eye) {
// Update eye movement based on target look direction and movement speed
if (frameCount >= eye.nextMovementTime) {
eye.targetX = random(-1.0, 1.0); // Set new target look direction along X-axis
eye.targetY = random(-1.0, 1.0); // Set new target look direction along Y-axis
eye.nextMovementTime = frameCount + random(30, 120); // Set time for next movement
}
eye.lookX += (eye.targetX - eye.lookX) * eye.movementSpeed; // Interpolate eye look direction along X-axis
eye.lookY += (eye.targetY - eye.lookY) * eye.movementSpeed; // Interpolate eye look direction along Y-axis
}
function draw() {
scale(zoomLevel); // Apply zoom level scaling
background(200); // Set background color
// Draw cloud background
push();
noStroke();
translate(0, 0, -400);
texture(cloudTexture);
plane(width * 1.5, height * 1.5);
pop();
// Set up lighting
ambientLight(80, 80, 80);
pointLight(255, 255, 255, 0, 0, 250);
// Calculate attractor positions
let attractorX = cos(attractorAngle) * attractorRadius * distanceScale;
let attractorY = sin(attractorAngle) * attractorRadius * distanceScale;
let verticalAttractorY =
(sin(verticalAttractorAngle1) * verticalAttractorAmplitude1 +
sin(verticalAttractorAngle2) * verticalAttractorAmplitude2 +
sin(verticalAttractorAngle3) * verticalAttractorAmplitude3) * distanceScale;
// Apply transformations and draw eyes
push();
translate(0, 0, angelZ);
translate(attractorX, attractorY + verticalAttractorY, 0);
push();
rotateX(angle * 0.3);
rotateY(angle * 0.2);
updateRingSpeed(); // Update ring rotation speeds
noStroke();
for (let eye of eyes) {
updateEyeMovement(eye); // Update eye movement
drawEye(eye); // Draw the eye
}
pop();
isMouseOverCanvas = mouseX >= 0 && mouseX < width && mouseY >= 0 && mouseY < height; // Check if mouse is over the canvas
if (isMouseOverCanvas) {
let mouseXNormalized = (mouseX - width / 2) / (width / 2); // Normalize mouse X position
let mouseYNormalized = (mouseY - height / 2) / (height / 2); // Normalize mouse Y position
giantEyeRotationX = -mouseYNormalized * PI / 8; // Set giant eye rotation based on mouse Y position
giantEyeRotationY = mouseXNormalized * PI / 8; // Set giant eye rotation based on mouse X position
}
drawGiantEye(); // Draw the giant eye
pop();
// Apply fog effect if enabled
if (isFogEnabled) {
push();
noStroke();
fill(200, 200, 200, fogDensity * 255);
translate(0, 0, (angelZ + 400) / 2);
plane(width * 2, height * 2);
pop();
}
// Update animation variables
angle += 0.01;
attractorAngle += attractorSpeed;
verticalAttractorAngle1 += verticalAttractorSpeed1;
verticalAttractorAngle2 += verticalAttractorSpeed2;
verticalAttractorAngle3 += verticalAttractorSpeed3;
}
function updateRingSpeed() {
// Update outer ring speed and rotation sound volume
outerRingTimer++;
if (outerRingTimer >= pauseDuration && !isOuterRingAccelerating) {
isOuterRingAccelerating = true;
outerRingTimer = 0;
fadeOutStartTime = 0;
} else if (outerRingTimer >= accelerationDuration && isOuterRingAccelerating) {
isOuterRingAccelerating = false;
outerRingTimer = 0;
fadeOutStartTime = frameCount;
}
if (isOuterRingAccelerating) {
outerRingSpeed += ringAcceleration;
rotationSoundVolume = min(rotationSoundVolume + 0.01, 1);
} else {
outerRingSpeed = max(outerRingSpeed - ringAcceleration / 3, 0.01);
if (frameCount - fadeOutStartTime < decelerationDuration - fadeOutDuration) {
rotationSoundVolume = 1;
} else {
let fadeOutProgress = (frameCount - (fadeOutStartTime + decelerationDuration - fadeOutDuration)) / fadeOutDuration;
rotationSoundVolume = max(1 - fadeOutProgress, 0);
}
}
rotationSound.setVolume(rotationSoundVolume);
// Update inner ring speed
innerRingTimer++;
if (innerRingTimer >= pauseDuration && !isInnerRingAccelerating) {
isInnerRingAccelerating = true;
innerRingTimer = 0;
} else if (innerRingTimer >= accelerationDuration && isInnerRingAccelerating) {
isInnerRingAccelerating = false;
innerRingTimer = 0;
}
if (isInnerRingAccelerating) {
innerRingSpeed += ringAcceleration;
} else {
innerRingSpeed = max(innerRingSpeed - ringAcceleration / 3, 0.01);
}
rings[1].spin += outerRingSpeed; // Update outer ring spin
rings[3].spin += innerRingSpeed; // Update inner ring spin
}
function drawEye(eye) {
let ring = rings[eye.ring]; // Get the ring object the eye belongs to
let r = ring.radius + ring.tubeRadius * eye.offset; // Calculate the eye's distance from the center
let x = r * cos(eye.angle); // Calculate the eye's X position
let y = r * sin(eye.angle); // Calculate the eye's Y position
push();
rotateX(ring.rotation.x + sin(angle + ring.phase) * 0.1); // Apply ring rotation along X-axis
rotateY(ring.rotation.y + cos(angle * 1.3 + ring.phase) * 0.1); // Apply ring rotation along Y-axis
rotateZ(ring.rotation.z + sin(angle * 0.7 + ring.phase) * 0.1); // Apply ring rotation along Z-axis
if (eye.ring === 1 || eye.ring === 3) {
rotateZ(ring.spin); // Apply additional spin to outer and inner rings
}
translate(x, y, 0); // Translate to the eye's position
let eyePos = createVector(x, y, 0); // Create a vector for the eye's position
let screenCenter = createVector(0, 0, -1); // Create a vector for the screen center
let directionVector = p5.Vector.sub(screenCenter, eyePos).normalize(); // Calculate the direction vector from the eye to the screen center
let rotationAxis = createVector(-directionVector.y, directionVector.x, 0).normalize(); // Calculate the rotation axis perpendicular to the direction vector
let rotationAngle = acos(directionVector.z); // Calculate the rotation angle based on the direction vector's Z component
rotate(rotationAngle, rotationAxis); // Apply rotation to make the eye face the screen center
if (eye.isInner) {
rotateY(PI); // Rotate inner eyes 180 degrees along Y-axis
}
rotateX(eye.lookY); // Apply eye's look direction along Y-axis
rotateY(eye.lookX); // Apply eye's look direction along X-axis
texture(eyeTexture); // Set the eye texture
sphere(eye.size); // Draw the eye as a sphere
pop();
}
function drawGiantEye() {
push();
noStroke();
texture(eyeTexture); // Set the giant eye texture
let wobbleX = sin(frameCount * 0.05) * 2 * distanceScale; // Calculate X wobble based on frame count
let wobbleY = cos(frameCount * 0.05) * 2 * distanceScale; // Calculate Y wobble based on frame count
translate(wobbleX, wobbleY, 0); // Apply wobble translation
if (isMouseOverCanvas) {
rotateX(giantEyeRotationX); // Apply giant eye rotation based on mouse Y position
rotateY(giantEyeRotationY); // Apply giant eye rotation based on mouse X position
}
rotateZ(-PI/2); // Rotate the giant eye -90 degrees along Z-axis
rotateY(PI); // Rotate the giant eye 180 degrees along Y-axis
sphere(giantEyeSize * distanceScale); // Draw the giant eye as a sphere
pop();
}