Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add zoom flexibility #1983

Merged
merged 10 commits into from Oct 26, 2022
43 changes: 43 additions & 0 deletions assets/magnify.js
@@ -0,0 +1,43 @@
// create a container and set the full-size image as its background
function createOverlay(image) {
overlay = document.createElement('div');
overlay.setAttribute('class', 'image-magnify-full-size');
overlay.setAttribute('aria-hidden', 'true');
overlay.style.backgroundImage = `url('${image.src}')`;
metamoni marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I'm wondering. Have we tested the difference in behaviour if we use an <img> tag instead of the background image in CSS ? We can test as a follow up but just curious to compare the potential behaviour of it. Whether one is faster to load vs the other.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried this with an img element instead of a div, but the overlay image remains constrained in its container instead of being loaded at full size. Not sure what causes it or how to test whether it would load faster.

img.mp4

image.parentElement.insertBefore(overlay, image);
return overlay;
};

function moveWithHover(image, event, zoomRatio) {
// calculate mouse position
metamoni marked this conversation as resolved.
Show resolved Hide resolved
const ratio = image.height / image.width;
const container = event.target.getBoundingClientRect();
const xPosition = event.clientX - container.left;
const yPosition = event.clientY - container.top;
const xPercent = `${xPosition / (overlay.clientWidth / 100)}%`;
const yPercent = `${yPosition / ((overlay.clientWidth * ratio) / 100)}%`;

// determine what to show in the frame
overlay.style.backgroundPosition = `${xPercent} ${yPercent}`;
overlay.style.backgroundSize = `${image.width * zoomRatio}px`;
};

function magnify(image, zoomRatio) {
// add full-size image on top of original
metamoni marked this conversation as resolved.
Show resolved Hide resolved
const overlay = createOverlay(image);
overlay.onclick = () => overlay.remove();
overlay.onmousemove = (event) => moveWithHover(image, event, zoomRatio);
metamoni marked this conversation as resolved.
Show resolved Hide resolved
metamoni marked this conversation as resolved.
Show resolved Hide resolved
overlay.onmouseleave = () => overlay.remove();
}

function enableZoomOnHover(zoomRatio) {
const images = document.querySelectorAll('.image-magnify-hover');
images.forEach(image => {
image.onclick = (event) => {
magnify(image, zoomRatio);
moveWithHover(image, event, zoomRatio);
};
});
}

enableZoomOnHover(2);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That could be an interesting value to tie to a setting in the editor. Can probably be done in the future if we see a lot of requests to change the zoom value.

40 changes: 40 additions & 0 deletions assets/section-main-product.css
Expand Up @@ -1148,6 +1148,46 @@ a.product__text {
border-color: rgb(var(--color-foreground));
}

.image-magnify-full-size {
cursor: zoom-out;
z-index: 1;
margin: 0;
metamoni marked this conversation as resolved.
Show resolved Hide resolved
border-radius: calc(var(--media-radius) - var(--media-border-width));
}

.image-magnify-hover {
cursor: zoom-in;
}

.product__modal-opener--image .product__media-zoom-none,
.product__media-icon--none {
display: none;
}

@media (hover: hover) {
.product__media-zoom-hover {
display: none;
}

.product__media-icon--hover {
display: none;
}
metamoni marked this conversation as resolved.
Show resolved Hide resolved
}

@media screen and (max-width: 23.4375rem) {
metamoni marked this conversation as resolved.
Show resolved Hide resolved
.product__media-zoom-hover {
display: flex;
}

.product__media-icon--hover {
display: flex;
}
metamoni marked this conversation as resolved.
Show resolved Hide resolved
}

.js .product__media {
overflow: hidden !important;
}

.thumbnail[aria-current]:focus-visible {
box-shadow: 0 0 0 0.3rem rgb(var(--color-background)),0 0 0rem 0.5rem rgba(var(--color-foreground), 0.5);
}
Expand Down
10 changes: 10 additions & 0 deletions assets/theme-editor.js
Expand Up @@ -18,3 +18,13 @@ document.addEventListener('shopify:block:deselect', function(event) {
const parentSlideshowComponent = event.target.closest('slideshow-component');
if (parentSlideshowComponent.autoplayButtonIsSetToPlay) parentSlideshowComponent.play();
});

document.addEventListener('shopify:section:load', () => {
const zoomOnHoverScript = document.querySelector('[id^=EnableZoomOnHover]');
if (!zoomOnHoverScript) return;
if (zoomOnHoverScript) {
const newScriptTag = document.createElement('script');
newScriptTag.src = zoomOnHoverScript.src;
zoomOnHoverScript.parentNode.replaceChild(newScriptTag, zoomOnHoverScript);
}
});
metamoni marked this conversation as resolved.
Show resolved Hide resolved
13 changes: 13 additions & 0 deletions locales/cs.schema.json
Expand Up @@ -1878,6 +1878,19 @@
"options__2": {
"label": "Vpravo"
}
},
"image_zoom": {
"label": "Zvětšení obrázků",
"info": "Klikněte a podržte kurzor nad výchozími možnostmi. Tím otevřete Lightbox na mobilním zařízení.",
"options__1": {
"label": "Otevřít Lightbox"
},
"options__2": {
"label": "Kliknout a podržet kurzor"
},
"options__3": {
"label": "Bez zvětšení"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions locales/da.schema.json
Expand Up @@ -1878,6 +1878,19 @@
"options__2": {
"label": "Højre"
}
},
"image_zoom": {
"label": "Billedzoom",
"info": "Klik og hold musen over standarder for at åbne lightbox på mobilen.",
"options__1": {
"label": "Åbn lightbox"
},
"options__2": {
"label": "Klik og hold musen over"
},
"options__3": {
"label": "Ingen zoom"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions locales/de.schema.json
Expand Up @@ -1877,6 +1877,19 @@
"options__2": {
"label": "Rechts"
}
},
"image_zoom": {
"label": "Bildzoom",
"info": "Klicke auf und fahre mit der Maus über \"Standards\", um Lightbox auf deinem Mobilgerät zu öffnen.",
"options__1": {
"label": "Lightbox öffnen"
},
"options__2": {
"label": "Klicken und mit der Maus darüber fahren"
},
"options__3": {
"label": "Nicht zoomen"
}
}
},
"name": "Produktinformationen"
Expand Down
13 changes: 13 additions & 0 deletions locales/en.default.schema.json
Expand Up @@ -1998,6 +1998,19 @@
"label": "Large"
}
},
"image_zoom": {
"label": "Image zoom",
"info": "Click and hover defaults to open lightbox on mobile.",
"options__1": {
"label": "Open lightbox"
ludoboludo marked this conversation as resolved.
Show resolved Hide resolved
},
"options__2": {
"label": "Click and hover"
},
"options__3": {
"label": "No zoom"
}
},
"media_position": {
"label": "Desktop media position",
"info": "Position is automatically optimized for mobile.",
Expand Down
13 changes: 13 additions & 0 deletions locales/es.schema.json
Expand Up @@ -1878,6 +1878,19 @@
"options__2": {
"label": "Derecha"
}
},
"image_zoom": {
"label": "Ampliar imagen",
"info": "En dispositivos móviles, la opción Hacer clic y pasar sobre el elemento cambia a Abrir Lightbox de forma predeterminada.",
"options__1": {
"label": "Abrir Lightbox"
},
"options__2": {
"label": "Hacer clic y pasar sobre el elemento"
},
"options__3": {
"label": "Sin zoom"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions locales/fi.schema.json
Expand Up @@ -1877,6 +1877,19 @@
"options__2": {
"label": "Oikea"
}
},
"image_zoom": {
"label": "Kuvan zoomaus",
"info": "Avaa lightbox-ikkuna mobiililaitteessa napsauttamalla oletusarvoja ja viemällä osoitin niiden päälle.",
"options__1": {
"label": "Avaa lightbox-ikkuna"
},
"options__2": {
"label": "Napsauta ja vie osoitin päälle"
},
"options__3": {
"label": "Ei zoomausta"
}
}
},
"name": "Tuotetiedot"
Expand Down
13 changes: 13 additions & 0 deletions locales/fr.schema.json
Expand Up @@ -1877,6 +1877,19 @@
"options__2": {
"label": "Droite"
}
},
"image_zoom": {
"label": "Le zoom sur image",
"info": "Cliquez et passez la souris sur les éléments par défaut pour ouvrir lightbox sur mobile.",
"options__1": {
"label": "Ouvrir lightbox"
},
"options__2": {
"label": "Cliquer et passer la souris"
},
"options__3": {
"label": "Pas de zoom"
}
}
},
"name": "Informations produits"
Expand Down
13 changes: 13 additions & 0 deletions locales/it.schema.json
Expand Up @@ -1878,6 +1878,19 @@
"options__2": {
"label": "A destra"
}
},
"image_zoom": {
"label": "Zoom immagine",
"info": "Clicca e fai scorrere il mouse sopra le impostazioni predefinite per aprire una lightbox sul dispositivo mobile.",
"options__1": {
"label": "Apri la lightbox"
},
"options__2": {
"label": "Clicca e fai scorrere il mouse"
},
"options__3": {
"label": "Nessuno zoom"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions locales/ja.schema.json
Expand Up @@ -1878,6 +1878,19 @@
"options__2": {
"label": "右"
}
},
"image_zoom": {
"label": "画像ズーム",
"info": "デフォルト設定では、クリックしてカーソルを合わせると、モバイルのLightboxが開きます。",
"options__1": {
"label": "Lightboxを開く"
},
"options__2": {
"label": "クリックしてカーソルを合わせる"
},
"options__3": {
"label": "ズームなし"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions locales/ko.schema.json
Expand Up @@ -1878,6 +1878,19 @@
"options__2": {
"label": "오른쪽"
}
},
"image_zoom": {
"label": "이미지 확대/축소",
"info": "클릭 및 커서 올리기는 모바일에서 라이트박스 열기로 기본값이 설정됩니다.",
"options__1": {
"label": "라이트박스 열기"
},
"options__2": {
"label": "클릭 및 커서 올리기"
},
"options__3": {
"label": "확대/축소 안 함"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions locales/nb.schema.json
Expand Up @@ -1877,6 +1877,19 @@
"options__2": {
"label": "Høyre"
}
},
"image_zoom": {
"label": "Bildezoom",
"info": "Standard for klikk og markør for å åpne lysboks på mobil.",
"options__1": {
"label": "Åpne lysboks"
},
"options__2": {
"label": "Klikk og hold markøren over"
},
"options__3": {
"label": "Ingen zoom"
}
}
},
"name": "Produktinformasjon"
Expand Down
13 changes: 13 additions & 0 deletions locales/nl.schema.json
Expand Up @@ -1878,6 +1878,19 @@
"options__2": {
"label": "Rechts"
}
},
"image_zoom": {
"label": "Inzoomen op afbeelding",
"info": "Standaarden voor klikken en aanwijzen om Lightbox te openen op mobiel.",
"options__1": {
"label": "Lightbox openen"
},
"options__2": {
"label": "Klikken en aanwijzen"
},
"options__3": {
"label": "Geen zoom"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions locales/pl.schema.json
Expand Up @@ -1878,6 +1878,19 @@
"options__2": {
"label": "Prawa strona"
}
},
"image_zoom": {
"label": "Powiększenie obrazu",
"info": "Kliknij i najedź kursorem na wartości domyślne, aby otworzyć lightbox na urządzeniu mobilnym.",
"options__1": {
"label": "Otwórz lightbox"
},
"options__2": {
"label": "Kliknij i najedź kursorem"
},
"options__3": {
"label": "Bez powiększenia"
}
}
}
},
Expand Down
13 changes: 13 additions & 0 deletions locales/pt-BR.schema.json
Expand Up @@ -1877,6 +1877,19 @@
"options__2": {
"label": "Direita"
}
},
"image_zoom": {
"label": "Zoom de imagem",
"info": "Clique e passe o cursor para abrir a janela modal no celular.",
"options__1": {
"label": "Abrir janela modal"
},
"options__2": {
"label": "Clicar e passar o cursor"
},
"options__3": {
"label": "Sem zoom"
}
}
},
"name": "Informações do produto"
Expand Down