Thanks for taking the time to read me, and maybe help me on a small problem i’m encountering.
So, long story short, i’m a french astronomer, and i’m trying to build a small website for family/friends/myself to store and display my different night sky pictures.
Funny.
But.
Right now, i have a javascript who handle zooming, de-zooming, reset and displaying a single image in full screen. But. The way it works from what i get ( i’m not really good with js, and since to my knowledge php / css won’t do the deal, i’m stuck with it ), it have a flaw: if i place two same image container ( which i’ll be forced to do on the same page ), it doesn’t “know” which image to zoom in. Basically, here’s my html:
<div class="image-group">
<div class="image-container">
<img class="image" src="/Uploads/Images/IMG_7342_pipp_top_100r__651_regedited-2.jpg" alt="">
</div>
<div class="fullscreenImageContainer" onclick="closeFullscreen()">
<span class="closeButton">X</span>
<img class="fullscreenImage" src="/Uploads/Images/IMG_7342_pipp_top_100r__651_regedited-2.jpg" alt="">
</div>
<div class="zoombuttons">
<button onclick="zoomIn(this)">Zoom +</button>
<button onclick="zoomOut(this)">Zoom -</button>
<button onclick="resetZoom(this)">Réinitialiser</button>
<button onclick="openFullscreen(this)">Plein écran</button>
</div>
</div>
And my JS:
<sc <script>
const image = document.getElementById('image');
const container = document.getElementById('image-container');
let scale = 1;
let isDragging = false;
let startX, startY;
let posX = 0, posY = 0;
function zoomIn() {
scale *= 1.1;
updateImageTransform();
}
function zoomOut() {
const initialScale = 1; // échelle initiale de l'image
if (scale > initialScale) {
scale = Math.max(initialScale, scale / 1.1); // Empêche le zoom d'aller en dessous de l'échelle initiale
constrainPosition();
updateImageTransform();
}
}
function resetZoom() {
scale = 1;
posX = posY = 0;
updateImageTransform();
}
function updateImageTransform() {
image.style.transform = `translate(${posX}px, ${posY}px) scale(${scale})`;
}
function constrainPosition() {
const imageRect = image.getBoundingClientRect();
const containerRect = image.parentElement.getBoundingClientRect();
const maxPosX = (imageRect.width - containerRect.width) / 2;
const maxPosY = (imageRect.height - containerRect.height) / 2;
posX = Math.min(Math.max(posX, -maxPosX), maxPosX);
posY = Math.min(Math.max(posY, -maxPosY), maxPosY);
}
image.addEventListener('mousedown', (e) => {
e.preventDefault();
isDragging = true;
startX = e.clientX;
startY = e.clientY;
});
window.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const dx = e.clientX - startX;
const dy = e.clientY - startY;
startX = e.clientX;
startY = e.clientY;
posX += dx;
posY += dy;
constrainPosition();
updateImageTransform();
});
window.addEventListener('mouseup', () => {
isDragging = false;
});
image.addEventListener('touchstart', (e) => {
if (e.touches.length === 1) {
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
}
if (e.touches.length === 2) {
const touch1 = e.touches[0];
const touch2 = e.touches[1];
initialDistance = Math.hypot(touch2.clientX - touch1.clientX, touch2.clientY - touch1.clientY);
initialScale = scale;
}
});
image.addEventListener('touchmove', (e) => {
e.preventDefault();
if (e.touches.length === 1) {
const dx = e.touches[0].clientX - startX;
const dy = e.touches[0].clientY - startY;
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
posX += dx;
posY += dy;
constrainPosition();
updateImageTransform();
}
if (e.touches.length === 2) {
const touch1 = e.touches[0];
const touch2 = e.touches[1];
const currentDistance = Math.hypot(touch2.clientX - touch1.clientX, touch2.clientY - touch1.clientY);
const delta = currentDistance - initialDistance;
scale = Math.max(1, initialScale + delta * 0.01); // Ajustez le facteur de zoom
constrainPosition();
updateImageTransform();
}
});
image.addEventListener('touchend', (e) => {
// Rien à faire lors de la fin du toucher
});</script>
<script>
window.addEventListener('load', function() {
function adjustContainerSize() {
const imageRect = image.getBoundingClientRect();
const containerHeight = image.parentElement.clientHeight;
const imageHeight = imageRect.height;
const imageWidth = imageRect.width;
const containerWidth = (imageWidth / imageHeight) * containerHeight;
image.parentElement.style.width = containerWidth + 'px';
}
adjustContainerSize();
window.addEventListener('resize', adjustContainerSize);
}); </script>
<script>
// Fonction pour ouvrir l'image en plein écran
function openFullscreen() {
const fullscreenImageContainer = document.getElementById('fullscreenImageContainer');
fullscreenImageContainer.style.display = 'flex';
}
// Fonction pour fermer l'image en plein écran
function closeFullscreen() {
const fullscreenImageContainer = document.getElementById('fullscreenImageContainer');
fullscreenImageContainer.style.display = 'none';
}
// Gestion de l'événement ESC pour fermer l'image en plein écran
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
closeFullscreen();
}
});
ript>
<script>
// Fonction pour ouvrir l'image en plein écran
function openFullscreen() {
const fullscreenImageContainer = document.getElementById('fullscreenImageContainer');
fullscreenImageContainer.style.display = 'flex';
}
// Fonction pour fermer l'image en plein écran
function closeFullscreen() {
const fullscreenImageContainer = document.getElementById('fullscreenImageContainer');
fullscreenImageContainer.style.display = 'none';
}
// Gestion de l'événement ESC pour fermer l'image en plein écran
document.addEventListener('keydown', function(event) {
if (event.key === 'Escape') {
closeFullscreen();
}
});
</script>
What i would like it to do is to be linked to the the action is happening in. If i have two of them, the actions are hapenning in the one where the button is clicked, not the other same underneath.
( for demo purpose, you can see how it is integrated here: http://astrostuff.franceserv.com/Ref/Public/Post.php?ID=9D466F87-FC78-31C7-5C05-5AD6A55F6897 ).
The ideal situation would be to have multiple image-group, like this:
<div class="image-group">
<div class="image-container">
<img class="image" src="/Uploads/Images/IMG_7342_pipp_top_100r__651_regedited-2.jpg" alt="">
</div>
<div class="fullscreenImageContainer" onclick="closeFullscreen()">
<span class="closeButton">X</span>
<img class="fullscreenImage" src="/Uploads/Images/IMG_7342_pipp_top_100r__651_regedited-2.jpg" alt="">
</div>
<div class="zoombuttons">
<button onclick="zoomIn(this)">Zoom +</button>
<button onclick="zoomOut(this)">Zoom -</button>
<button onclick="resetZoom(this)">Réinitialiser</button>
<button onclick="openFullscreen(this)">Plein écran</button>
</div>
</div>
And another one
And another one
without interaction conflict.
But to be honest, this is not my code, i only have a few basics for simple things in js, and i have no clue of how to get it to work ( long story short, i tried a few approaches who were pretty much a disaster. So if anyone have any idea, i would really appreciate some help on this 🙂 !
Thanks and have a nice day !
I deleted the approaches i tried, so sadly i don’t have any examples. But basically, i tried an approach similar to this:
<button onclick="zoomIn(this)">Zoom +</button>
<script>
function zoomIn(button) {
const imageGroup = button.closest('.image-group');
const image = imageGroup.querySelector('.image');
let scale = parseFloat(image.dataset.scale) || 1;
scale *= 1.1;
image.dataset.scale = scale;
updateImageTransform(image);
}
</script>
and it didn't work very well. ( it prevented the top image to interact with the bottom one, but the top image still react to the button of the bottom one. )