I want to positioning images on different screen size with different position but I use this switch case but still when I refresh page than it works otherwise its still there
import { OrbitControls } from "https://cdn.jsdelivr.net/npm/three@0.124.0/examples/jsm/controls/OrbitControls.js";
const canvas = document.querySelector("#canvas");
const leftZoomBtn = document.querySelector(".left-box-btn");
const originalBtn = document.querySelector(".original-btn");
const rightZoomBtn = document.querySelector(".right-box-btn");
let scene, camera, renderer;
let rotateAroundGroup = true;
let currentZoomedImageIndex = 0;
scene = new THREE.Scene();
scene.background = null;
camera = new THREE.PerspectiveCamera(
80,
canvas.clientWidth / canvas.clientHeight,
0.5,
90
);
camera.position.set(0, 0, 10);
const light = new THREE.HemisphereLight(0xFFA910, "cornflowerblue", 1);
scene.add(light);
const group = new THREE.Group();
renderer = new THREE.WebGLRenderer({ antialias: false, alpha: true });
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.outputEncoding = THREE.sRGBEncoding;
canvas.appendChild(renderer.domElement);
let planeMeshes = [];
const textureLoader = new THREE.TextureLoader();
function createImageMesh(texture, position, size, index, content, heading, design) {
const material = new THREE.MeshPhongMaterial({
map: texture,
transparent: true,
// Set the diffuse color to white or adjust as needed
});
const geometry = new THREE.PlaneGeometry(size.width, size.height);
const mesh = new THREE.Mesh(geometry, material);
mesh.position.set(position.x, position.y, position.z);
mesh.userData.index = index; // Storing the image index as user data
mesh.userData.originalPosition = { ...position }; // Store the original position for movement
mesh.userData.content = content; // Store the text content
mesh.userData.heading = heading;
mesh.userData.design = design;
group.add(mesh);
planeMeshes.push(mesh);
}
// design: "../assets/images/laptop-screen.png"
const images = [
{ url: "../assets/images/laptop.png", position: { x: 0, y: -1, z: 3 }, size: { width: 4, height: 4 }, content: "web development is good for our", heading: "Web Dvelopment", },
{ url: "../assets/images/mobile.png", position: { x: -7, y: -4, z: 2.5 }, size: { width: 2.5, height: 3 }, content: "Here we can do MObile development also", heading: "App Development" },
{ url: "../assets/images/reels.png", position: { x: 7, y: 2, z: 2.5 }, size: { width: 3, height: 3 }, content: "We are reels maker and video editior", heading: "Video Editor" },
{ url: "../assets/images/arrow.png", position: { x: -7, y: 4, z: 2.5 }, size: { width: 4, height: 4 }, content: "Our taarget is to achieve client satisfaction", heading: "Target" },
{ url: "../assets/images/controler.png", position: { x: 7, y: -4, z: 2.5 }, size: { width: 3, height: 3 }, content: "We can do Game development", heading: "Game Development" },
];
window.addEventListener('resize', () => {
// Recalculate and update image positions based on screen size
function calculateImagePosition(index) {
if (window.innerWidth <= 991) {
switch (index) {
case 0:
return new THREE.Vector3(0, 0, 3); // Position for image 1 on small screens
case 1:
return new THREE.Vector3(-3, -4, 2.5); // Position for image 2 on small screens
case 2:
return new THREE.Vector3(7, 2, 2.5); // Position for image 3 on small screens
case 3:
return new THREE.Vector3(-7, 4, 2.5); // Position for image 4 on small screens
case 4:
return new THREE.Vector3(7, -4, 2.5); // Position for image 5 on small screens
default:
return new THREE.Vector3(0, 0, 0); // Default position for other images on small screens
}
} else {
// Use default positions for larger screens
return new THREE.Vector3(images[index].position.x || 0, images[index].position.y || 0, images[index].position.z || 0);
}
}
images.forEach((image, index) => {
const texture = imageMeshes[index].material.map;
const position = calculateImagePosition(index);
imageMeshes[index].position.copy(position);
});
// Update camera aspect ratio and renderer size
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
});
const dummyImages = [
{ url: "../assets/images/insect.png", position: { x: 0, y: 6, z: 0 }, size: { width: 5, height: 5 } },
{ url: "../assets/images/dollar.png", position: { x: 3, y: 3, z: 1 }, size: { width: 2, height: 2 } },
{ url: "../assets/images/mic.png", position: { x: -4, y: 1, z: 2 }, size: { width: 1.5, height: 1.5 } },
{ url: "../assets/images/shapes.png", position: { x: 10, y: 4, z: 2 }, size: { width: 1.5, height: 1.5 } },
{ url: "../assets/images/nest.png", position: { x: 0, y: 0, z: -1 }, size: { width: 25, height: 20 } },
];
dummyImages.forEach((dummyImage, index) => {
const textureLoader = new THREE.TextureLoader();
textureLoader.load(dummyImage.url, function (texture) {
// texture.generateMipmaps = false; // Disable mipmaps
texture.minFilter = THREE.LinearFilter;
texture.encoding = THREE.sRGBEncoding;
const material = new THREE.MeshPhongMaterial({ map: texture, transparent: true });
const geometry = new THREE.PlaneGeometry(dummyImage.size.width, dummyImage.size.height);
const dummyMesh = new THREE.Mesh(geometry, material);
dummyMesh.position.set(dummyImage.position.x, dummyImage.position.y, dummyImage.position.z);
group.add(dummyMesh);
});
});
function handleMouseMove(event) {
const mouse = {
x: (event.touches[1].clientX / window.innerWidth) * 2 - 1,
y: -(event.touches[1].clientY / window.innerHeight) * 2 + 1
};
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(planeMeshes);
if (intersects.length > 0) {
document.body.style.cursor = 'pointer'; // Change cursor to pointer
} else {
document.body.style.cursor = 'default'; // Revert cursor to default
}
}
// Add mouse move event listener to the document
document.addEventListener('mousemove', handleMouseMove);
document.getElementById('screen').style.display = "none"
scene.add(group);
document.getElementById("content").style.display = "none"
document.getElementById("heading").style.display = "none"
rightZoomBtn.style.display = "none"
canvas.addEventListener('click', (event) => {
const mouse = {
x: (event.clientX / window.innerWidth) * 2 - 1,
y: -(event.clientY / window.innerHeight) * 2 + 1
};
const raycaster = new THREE.Raycaster();
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(planeMeshes);
if (intersects.length > 0) {
const closestIntersection = intersects[0];
let closestIndex = -1;
for (let i = 0; i < planeMeshes.length; i++) {
if (planeMeshes[i] === closestIntersection.object) {
closestIndex = i;
break;
}
}
if (closestIndex !== -1) {
// Update currentZoomedImageIndex directly
currentZoomedImageIndex = closestIndex;
// Zoom in on the clicked image
const position = planeMeshes[currentZoomedImageIndex].position;
zoomInTimeline(position.x, position.y, position.z, 3);
rotateAroundGroup = false;
const contentElement = document.getElementById("content");
// Update and show content
contentElement.textContent = planeMeshes[currentZoomedImageIndex].userData.content;
contentElement.style.display = "block";
contentElement.classList.add('context');
contentElement.style.transition = "opacity 1s";
const contentheading = document.getElementById('content-heading');
contentheading.textContent = planeMeshes[currentZoomedImageIndex].userData.heading;
contentheading.style.display = "block"
// Update and show heading
const headingElement = document.getElementById("heading");
headingElement.textContent = planeMeshes[currentZoomedImageIndex].userData.heading;
headingElement.style.display = "block";
headingElement.classList.add('headshot'); // Add any necessary CSS classes here
// Show other buttons
rightZoomBtn.style.display = "inline";
originalBtn.style.display = "block";
}
}
else {
document.body.style.cursor = 'default';
}
});
rightZoomBtn.addEventListener("click", () => {
const targetImage = planeMeshes[currentZoomedImageIndex];
zoomInTimeline(targetImage.position.x, targetImage.position.y, targetImage.position.z, 3);
currentZoomedImageIndex = (currentZoomedImageIndex + 1) % planeMeshes.length;
rotateAroundGroup = false;
const contentElement = document.getElementById("content");
contentElement.classList.add('context');
const headingElement = document.getElementById("heading");
headingElement.classList.add('headshot');
// Add transition effect for opacity change
contentElement.style.transition = "opacity 1s";
headingElement.textContent = targetImage.userData.heading
// Fade out the content if it's visible
const contentheading = document.getElementById('content-heading');
contentheading.textContent = targetImage.userData.heading
contentheading.style.display = "block"
if (contentElement.style.opacity === "1") {
contentElement.style.opacity = "0";
// After fading out, update content and fade in the new content slowly
setTimeout(() => {
contentElement.textContent = targetImage.userData.content;
contentElement.style.opacity = "1";
}, 1500); // Wait for fade-out to complete
} else {
// If no previous content is visible, directly update content and fade in
contentElement.textContent = targetImage.userData.content;
headingElement.textContent = targetImage.userData.heading
contentElement.style.opacity = "1";
}
});
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableRotate = false;
controls.enableZoom = false;
controls.enabled = false;
const onWindowResize = () => {
camera.aspect = canvas.clientWidth / canvas.clientHeight;
camera.updateProjectionMatrix();
renderer.setSize(canvas.clientWidth, canvas.clientHeight);
};
window.addEventListener("resize", onWindowResize, false);
const animate = () => {
renderer.render(scene, camera);
if (rotateAroundGroup) {
const elapsedTime = Date.now() * 0.001;
const movementSpeed = 0.5; // Adjust the speed of the movement
const amplitude = 0.4; // Adjust the amplitude of the movement
// dummyImages.forEach((dummy, index) => {
// const dummyMesh = group.children[planeMeshes.length + index]; // Get the corresponding dummy mesh
// const yOffset = Math.sin(elapsedTime * movementSpeed + index) * amplitude;
// dummyMesh.position.y = dummy.position.y + yOffset;
// });
// Loop through all the image meshes and apply the slight up and down movement
planeMeshes.forEach((mesh, index) => {
const yOffset = Math.sin(elapsedTime * movementSpeed + index) * amplitude;
mesh.position.y = mesh.userData.originalPosition.y + yOffset;
});
// Loop through all the dummy image meshes and apply the same up and down movement
}
requestAnimationFrame(animate);
};
animate();
const zoomInTimeline = (x, y, z, zoomOutFactor = 0) => {
gsap.to(camera.position, { x, y, z: z + zoomOutFactor, duration: 3, ease: "expo.out" });
};
originalBtn.style.display = "none"
originalBtn.addEventListener("click", () => {
zoomInTimeline(0, 0, 0, 10);
rotateAroundGroup = true;
document.getElementById("content").style.display = "none"
rightZoomBtn.style.display = "none"
originalBtn.style.display = "none"
document.getElementById("screen").style.display = "none";
document.getElementById("heading").style.display = "none"
document.getElementById("content-heading").style.display= "none"
});
// Function to handle the intersection
const handleIntersection = (entries, observer) => {
entries.forEach(entry => {
// If the section is intersecting with the viewport
if (entry.isIntersecting) {
// Zoom in on the first image
const position = planeMeshes[0].position;
zoomInTimeline(position.x, position.y, position.z, 3);
rotateAroundGroup = false;
// Show content and heading
const contentElement = document.getElementById("content");
contentElement.textContent = planeMeshes[0].userData.content;
contentElement.style.display = "block";
contentElement.classList.add('context');
contentElement.style.transition = "opacity 1s";
const headingElement = document.getElementById("heading");
headingElement.textContent = planeMeshes[0].userData.heading;
headingElement.style.display = "block";
headingElement.classList.add('headshot');
const contentheading = document.getElementById('content-heading');
contentheading.textContent = planeMeshes[0].userData.heading
contentheading.style.display = "block"
// Show other buttons
rightZoomBtn.style.display = "inline";
originalBtn.style.display = "block";
// Unobserve the section once the action is triggered
observer.unobserve(entry.target);
}
});
};
// Options for the intersection observer
const options = {
root: null, // Use the viewport as the root
rootMargin: '0px', // No margin around the viewport
threshold: 0.5 // Trigger when at least 50% of the section is visible
};
// Create an intersection observer
const observer = new IntersectionObserver(handleIntersection, options);
// Start observing the section
observer.observe(canvas);
// Disable default context menu for the canvas element
canvas.addEventListener('contextmenu', (event) => {
event.preventDefault();
});
// Add mouse down event listener to handle right-click
canvas.addEventListener('mousedown', (event) => {
// Check if it's a right-click (button 2 in mouse events)
if (event.button === 2) {
// Prevent default behavior to avoid browser context menu
event.preventDefault();
}
});