Shopify themes, liquid, logos, and UX
Hello, I tried following this: https://shopifypartnerblog.myshopify.com/blogs/blog/jquery-image-zoom?ref=minion-made
guide to add zoom on image hove functionality on my product page. I added the zoom.min.js file to my theme and I edited my media.liquid file to look like this:(code at end of file)
But now when I open my product page it's just a blank square, seems like the plugin is not working at all. Any idea what I did wrong? Thanks
{% comment %}
Renders a media element for the product gallery.
Media types include: image, video, external_video and model.
Accepts:
- media: {Object} Media Liquid object (required)
- enable_image_zoom: {Boolean} Image zoom setting (required for media type image)
- stacked: {Boolean} Layout type set as stacked (required)
- featured: {Boolean} Media is set as featured (required)
- height: {Number} Height to be passed to the image-style snippet
- width: {Number} Width to be passed to the image-style snippet
Usage:
{%- for media in product.media -%}
{% include 'media', media: media, enable_image_zoom: true, featured: true, stacked: true %}
{%- endfor -%}
{% endcomment %}
{% capture media_id %}{{ section.id }}-{{ media.id }}{% endcapture %}
{% capture img_id_class %}product-single__media-{{ media_id }}{% endcapture %}
{% capture wrapper_id %}ProductMediaWrapper-{{ media_id }}{% endcapture %}
{% capture image_size %}{{ height }}x{{ height }}{% endcapture %}
<div id="{{ wrapper_id }}" class="product-single__media-wrapper {% unless stacked or featured %} hide{% endunless %}"
{% if media.media_type == 'video' or media.media_type == 'external_video' %} data-product-media-type-video data-enable-video-looping="{{ section.settings.enable_video_looping }}"{% endif %}
{% if media.media_type == 'model' %} data-product-media-type-model{% endif %}
{% if media.media_type == 'external_video' %} data-video-id="{{ media.external_id }}"{% endif %}
data-product-single-media-wrapper
data-media-id="{{ media_id }}"
tabindex="-1">
{% case media.media_type %}
{% when 'image' %}
{% include 'image-style' with image: media, width: width, height: height, small_style: true, wrapper_id: wrapper_id, img_id_class: img_id_class %}
<div class="product-single__media" style="padding-top:{{ 1 | divided_by: media.aspect_ratio | times: 100}}%;">
{% assign img_url = media | img_url: '1x1' | replace: '_1x1.', '_{width}x.' %}
<div class="image-container">
<img class="image-zoom" src="{{ media | img_url: '300x300' }}" alt="{{ media.alt | escape }} data-zoom="{{ media | img_url: '300x300', scale: 2 }}>
<div class="image-details"></div>
</div>
</div>
{% when 'external_video' %}
<div class="product-single__media product-single__media--video" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;">
{{ media | external_video_tag }}
</div>
{% when 'video' %}
<div class="product-single__media product-single__media--video" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;">
{{ media | video_tag: controls: false, class: 'media-video', image_size: image_size }}
</div>
{% when 'model' %}
<div class="product-single__media" style="padding-top:100%;">
{{ media | model_viewer_tag: image_size: image_size, reveal: 'interaction', toggleable: true, data-model-id: media.id}}
</div>
{% else %}
<div class="product-single__media" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;">
{{ media | media_tag: class: 'media-item', image_size: image_size }}
</div>
{% endcase %}
<noscript>
<img class="product-single__media" src="{{ media | img_url: 'master' }}"
alt="{{ media.alt | escape }}">
</noscript>
<script>
$(document).ready(function(){
$('.image-zoom')
.wrap('<span style="display:inline-block"></span>')
.css('display', 'block')
.parent()
.zoom({
url: $(this).find('img').attr('data-zoom')
});
});
</script>
</div>
Sorry for facing this issue, it's my pleasure to help us.
Welcome to the Shopify community!
and Thanks for your Good question. 😊
Please share your site URL,
So I will check and provide a solution here.
Hello @KetanKumar ,
Here is a link to one of my products: https://mkgraphics.hr/products/edge-graphics-kit-all-bikes
Thanks for the reply.
Hello @dggb
<noscript>
<img class="product-single__media" src="{{ media | img_url: 'master' }}" alt="{{ media.alt | escape }}">
</noscript>
Remove <noscript> </noscript> from your code and your image will be back
Hello @SagarSukhanandi
Thanks for the suggestion, when I removed the <noscript> tags, the image was back, but the zoom functionality still doesn't work. I tried replacing the
<img class="product-single__media" src="{{ media | img_url: 'master' }}" alt="{{ media.alt | escape }}">
with:
<div class="image-container">
<img class="image-zoom" src="{{ media | img_url: '300x300' }}" alt="{{ media.alt | escape }} data-zoom="{{ media | img_url: '300x300', scale: 2 }}>
<div class="image-details"></div>
</div>
but that again removed the image from my product page..
@dggb Change
$(document).ready(function(){
$('.image-zoom')
.wrap('<span style="display:inline-block"></span>')
.css('display', 'block')
.parent()
.zoom({
url: $(this).find('img').attr('data-zoom')
});
});
with
$(document).ready(function(){
$('.image-zoom')
.wrap('<span style="display:contents"></span>')
.css('display', 'block')
.parent()
.zoom({
url: $(this).find('img').attr('data-zoom')
});
});
Hey @SagarSukhanandi,
This worked very well thank you very much! I am facing a problem now that the entire image gets show even though I only want the part where the mouse is to zoom in. If you look at the linked article there is a example of that exact behavior. Would you be able to help me with that too? But thank you very much!
If needed, here is my current code:
{% comment %}
Renders a media element for the product gallery.
Media types include: image, video, external_video and model.
Accepts:
- media: {Object} Media Liquid object (required)
- enable_image_zoom: {Boolean} Image zoom setting (required for media type image)
- stacked: {Boolean} Layout type set as stacked (required)
- featured: {Boolean} Media is set as featured (required)
- height: {Number} Height to be passed to the image-style snippet
- width: {Number} Width to be passed to the image-style snippet
Usage:
{%- for media in product.media -%}
{% include 'media', media: media, enable_image_zoom: true, featured: true, stacked: true %}
{%- endfor -%}
{% endcomment %}
{% capture media_id %}{{ section.id }}-{{ media.id }}{% endcapture %}
{% capture img_id_class %}product-single__media-{{ media_id }}{% endcapture %}
{% capture wrapper_id %}ProductMediaWrapper-{{ media_id }}{% endcapture %}
{% capture image_size %}{{ height }}x{{ height }}{% endcapture %}
<div id="{{ wrapper_id }}" class="product-single__media-wrapper {% unless stacked or featured %} hide{% endunless %}"
{% if media.media_type == 'video' or media.media_type == 'external_video' %} data-product-media-type-video data-enable-video-looping="{{ section.settings.enable_video_looping }}"{% endif %}
{% if media.media_type == 'model' %} data-product-media-type-model{% endif %}
{% if media.media_type == 'external_video' %} data-video-id="{{ media.external_id }}"{% endif %}
data-product-single-media-wrapper
data-media-id="{{ media_id }}"
tabindex="-1">
{% case media.media_type %}
{% when 'image' %}
{% include 'image-style' with image: media, width: width, height: height, small_style: true, wrapper_id: wrapper_id, img_id_class: img_id_class %}
<div class="product-single__media" style="padding-top:{{ 1 | divided_by: media.aspect_ratio | times: 100}}%;">
{% assign img_url = media | img_url: '1x1' | replace: '_1x1.', '_{width}x.' %}
<div class="image-container">
<img class="image-zoom" src="{{ media | img_url: 'master' }}" alt="{{ media.alt | escape }} data-zoom="{{ media | img_url: 'master', scale: 2 }}>
<div class="image-details"></div>
</div>
</div>
{% when 'external_video' %}
<div class="product-single__media product-single__media--video" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;">
{{ media | external_video_tag }}
</div>
{% when 'video' %}
<div class="product-single__media product-single__media--video" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;">
{{ media | video_tag: controls: false, class: 'media-video', image_size: image_size }}
</div>
{% when 'model' %}
<div class="product-single__media" style="padding-top:100%;">
{{ media | model_viewer_tag: image_size: image_size, reveal: 'interaction', toggleable: true, data-model-id: media.id}}
</div>
{% else %}
<div class="product-single__media" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;">
{{ media | media_tag: class: 'media-item', image_size: image_size }}
</div>
{% endcase %}
<noscript>
<img class="product-single__media" src="{{ media | img_url: 'master' }}"
alt="{{ media.alt | escape }}">
</noscript>
<script>
$(document).ready(function(){
$('.image-zoom')
.wrap('<span style="display:contents"></span>')
.css('display', 'block')
.parent()
.zoom({
url: $(this).find('img').attr('data-zoom')
});
});
</script>
</div>
@dggb Have you added styles mentioned on reference which you are using?
Yes, I copied the styles but that didn't change anything. It just moved the zoomed image slightly lower down.
Online store > Themes click on Customise
Click Product pages. If you want to let customers zoom in on product images, then check Enable image zoom.
Thanks @renus but this is not the wanted behavior, I want a zoom on hover effect.
Dear Renus,
Thank you for your response. Though I cannot find the "Product pages" tab after clicking on customize. Can you help ? Below is what I get after clicking customize.
Hi @dggb. I see that you have resolved the issue on your website. Can you help me with the same? I have followed all the steps and I am facing the same issue that you were facing. When I hover over the image the image just gets enlarged to the whole screen. Can you tell me how to limit the zoomed image to the box you have in your website? And how do we create that zoomed image listener?
Thank you!
thanks for details
can you please check your file code it's don't propr update your code make your step by step add zoom code
Hi @KetanKumar
I'm sorry I don't know what exactly you mean. I followed the steps exactly one by one, but the linked article was talking about modifying the product.liquid code, but that's not where my product images code is, so I had to manually find the code where product image is.
I solve it:
First the trigger must be fired in the load event of the page, it must set a minimum height to that div and hide the tumbnails :
$(window).on('load', function () {
$('.image-zoom')
.wrap('<span style="display:block;min-height:565px;"></span>')
.css('display', 'block')
.parent()
.zoom();
$('.product-single__thumbnails').css({'opacity':'1'});
});
We add the style:
.zoomImg{
cursor: move; /* fallback if grab cursor is unsupported */
cursor: grab;
cursor: -moz-grab;
cursor: -webkit-grab;}
.product-single__thumbnails{ opacity:0;}
We must remove the padding 100% to the parent div, I paste my complete media.liquid file:
{% comment %}
Renders a media element for the product gallery.
Media types include: image, video, external_video and model.
Accepts:
- media: {Object} Media Liquid object (required)
- enable_image_zoom: {Boolean} Image zoom setting (required for media type image)
- stacked: {Boolean} Layout type set as stacked (required)
- featured: {Boolean} Media is set as featured (required)
- height: {Number} Height to be passed to the image-style snippet
- width: {Number} Width to be passed to the image-style snippet
Usage:
{%- for media in product.media -%}
{% include 'media', media: media, enable_image_zoom: true, featured: true, stacked: true %}
{%- endfor -%}
{% endcomment %}
{% capture media_id %}{{ section.id }}-{{ media.id }}{% endcapture %}
{% capture img_id_class %}product-single__media-{{ media_id }}{% endcapture %}
{% capture wrapper_id %}ProductMediaWrapper-{{ media_id }}{% endcapture %}
{% capture image_size %}{{ height }}x{{ height }}{% endcapture %}
<div id="{{ wrapper_id }}" class="product-single__media-wrapper {% unless stacked or featured %} hide{% endunless %}"
{% if media.media_type == 'video' or media.media_type == 'external_video' %} data-product-media-type-video data-enable-video-looping="{{ section.settings.enable_video_looping }}"{% endif %}
{% if media.media_type == 'model' %} data-product-media-type-model{% endif %}
{% if media.media_type == 'external_video' %} data-video-id="{{ media.external_id }}"{% endif %}
data-product-single-media-wrapper
data-media-id="{{ media_id }}"
tabindex="-1">
{% case media.media_type %}
{% when 'image' %}
{% include 'image-style' with image: media, width: width, height: height, small_style: true, wrapper_id: wrapper_id, img_id_class: img_id_class %}
<div class="product-single__media"{% comment %} style="padding-top:{{ 1 | divided_by: media.aspect_ratio | times: 100}}%;" {% endcomment %}>
{% assign img_url = media | img_url: '1x1' | replace: '_1x1.', '_{width}x.' %}
<div class="image-container">
<img class="image-zoom" src="{{ media | img_url: 'master' }}" alt="{{ media.alt | escape }} data-zoom="{{ media | img_url: 'master', scale: 2 }}>
<div class="image-details"></div>
</div>
</div>
{% when 'external_video' %}
<div class="product-single__media product-single__media--video" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;">
{{ media | external_video_tag }}
</div>
{% when 'video' %}
<div class="product-single__media product-single__media--video" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;">
{{ media | video_tag: controls: false, class: 'media-video', image_size: image_size }}
</div>
{% when 'model' %}
<div class="product-single__media" style="padding-top:100%;">
{{ media | model_viewer_tag: image_size: image_size, reveal: 'interaction', toggleable: true, data-model-id: media.id}}
</div>
{% else %}
<div class="product-single__media" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;">
{{ media | media_tag: class: 'media-item', image_size: image_size }}
</div>
{% endcase %}
<noscript>
<img class="product-single__media" src="{{ media | img_url: 'master' }}"
alt="{{ media.alt | escape }}">
</noscript>
</div>
This is all, good luck
Now if you want the enlarged image to appear in a window on the side, you must use the jquery-zoom target option, write me if you need help noranterri@gmail.com
Are you ready to take your business to the next level? Look no further than the latest ...
By SarahF_Shopify Apr 15, 2024We’re keeping the ball rolling to make sure you’re always ahead of the game. So buckle ...
By JasonH Apr 8, 2024Portrait of Stephen positioned next to an image of planet Earth, with the Stephen's World ...
By JasonH Mar 18, 2024