Segunda imagem em rolagem


Neste tutorial, implementaremos uma segunda imagem na listagem de produtos, que é exibida ao passar pelo produto.



HTML

1. A primeira coisa que faremos é substituir a imagem pelo componente privado de imagem para o item de produto product-item-image que inclui a segunda imagem que precisamos.

Vamos procurar o snipplet item.tpl dentro da pasta snipplets/grid. Pode ser que, no seu layout, este snipplet se chame single_product.tpl.

Dentro deste arquivo, vamos procurar o seguinte código relacionado à imagem e seu contêiner:

<div class="item-image mb-2">
    <div style="padding-bottom: {{ item_img_spacing }}%;" class="p-relative" data-store="product-item-image-{{ product.id }}">
        <a href="{{ product_url_with_selected_variant }}" title="{{ product.name }}">
            <img alt="{{ item_img_alt }}" data-expand="-10" src="{{ 'images/empty-placeholder.png' | static_url }}" data-srcset="{{ item_img_srcset | product_image_url('small')}} 240w, {{ item_img_srcset | product_image_url('medium')}} 320w, {{ item_img_srcset | product_image_url('large')}} 480w" class="js-item-image lazyload img-absolute img-absolute-centered fade-in" width="{{ item_img_width }}" height="{{ item_img_height }}" /> 
            <div class="placeholder-fade"></div>
        </a>
    </div>
</div>

E o substituímos pelo componente privado:(se você já estiver usando o componente privado, pode pular esta etapa):

{% set show_secondary_image = settings.product_hover %}
{% set image_classes = 'js-item-image lazyload img-absolute img-absolute-centered fade-in' %}

{{ component(
    'product-item-image', {
        image_lazy: true,
        image_lazy_js: true,
        image_thumbs: ['small', 'medium', 'large', 'huge', 'original'],
        image_data_expand: '-10',
        image_secondary_data_sizes: 'auto',
        secondary_image: show_secondary_image,
        placeholder: true,
        svg_sprites: false,
        product_item_image_classes: {
            image_container: 'item-image mb-2',
            image_padding_container: 'p-relative',
            image: image_classes,
            image_featured: 'item-image-featured',
            image_secondary: 'item-image-secondary',
            placeholder: 'placeholder-fade',
        },
    })
}}

O componente privado product-item-image inclui o contêiner da imagem e as imagens necessárias (tanto a principal quanto a secundária). Por sua vez, ele também utiliza outro componente privado específico para a imagem. Recomendamos revisar a documentação de cada componente para entender quais parâmetros eles aceitam:

2. Uma vez incluído o componente product-item-image, precisamos adicionar dentro deste componente todos os elementos que estão flutuando sobre a imagem, como, por exemplo, as etiquetas.

Vamos procurar este conteúdo e vamos englobá-lo em um {% set floating_elements %} da seguinte maneira:

{% set floating_elements %}
    {% if not reduced_item %}
        {% if settings.product_color_variants %}
            {% include 'snipplets/labels.tpl' with {color: true} %}
            {% include 'snipplets/grid/item-colors.tpl' %}
        {% else %}
            {% include 'snipplets/labels.tpl' %}
        {% endif %}
    {% endif %}
{% endset %}

Uma vez definido "floating_elements", vamos usá-lo no parâmetro "custom_content" do product-item-image da seguinte forma:

{{ component(
    'product-item-image', {
        image_lazy: true,
        image_lazy_js: true,
        image_thumbs: ['small', 'medium', 'large', 'huge', 'original'],
        image_data_expand: '-10',
        image_secondary_data_sizes: 'auto',
        secondary_image: show_secondary_image,
        placeholder: true,
        svg_sprites: false,
        custom_content: floating_elements,
        product_item_image_classes: {
            image_container: 'item-image mb-2',
            image_padding_container: 'p-relative',
            image: image_classes,
            image_featured: 'item-image-featured',
            image_secondary: 'item-image-secondary',
            placeholder: 'placeholder-fade',
        },
    })
}}

CSS

Requisito:

Ter adicionado helper classes em seu layout. Você pode seguir este pequeno tutorial para fazer isso (é só copiar e colar algumas classes, não leva mais que 1 minuto).

1.Adicione os estilos no arquivo static/style-critical.tpl

Se em seu layout você usar um stylesheet para o CSS crítico, precisaremos do seguinte código dentro dele.

{# /* // Grid item */ #}

.lazyloaded + .placeholder-fade,
.lazyloaded + .item-image-secondary + .placeholder-fade{
  display: none;
}
.item-image:not(.product-item-image-secondary).lazyloaded {
  z-index: 9;
  opacity: 1;
}
.item-image-secondary,
.item-image-secondary.fade-in.lazyloaded  {
  display: none;
  opacity: 0;
}
.product-item-secondary-images-loaded:not(.product-item-secondary-images-disabled):hover .item-image-featured{
  opacity: 0;
  transition-delay: .05s;
}
.product-item-secondary-images-loaded:not(.product-item-secondary-images-disabled):hover .item-image-featured ~ .item-image-secondary {
  opacity: 1;
}

JS

Como neste tutorial usamos a técnica de lazy load com o plugin Lazysizes, precisamos adicioná-lo. Para ver como fazer isso, você pode ler este pequeno artigo e continuar com este tutorial.

Configurações

No arquivo config/settings.txt, adicionaremos um checkbox que ativa a funcionalidade na seção "Lista de produtos".

    title
        title = Fotos del producto
    checkbox
        name = product_hover
        description = Mostrar la segunda foto al posar el mouse

Traduções

Nesta etapa, adicionamos os textos para as traduções no arquivo config/translations.txt.

es "Fotos del producto"
pt "Fotos do produto"
en "Product photos"
es_mx "Fotos del producto"

es "Mostrar la segunda foto al posar el mouse"
pt "Mostrar a segunda foto ao colocar o mouse"
en "Show the second photo on mouseover"
es_mx "Mostrar la segunda foto al posar el mouse"

Ativação

Por último, você pode ativar funcionalidade no Administrador Nuvem, na seção ‘Personalizar seu layout atual’ dentro de ‘Lista de produtos’:

Lembre-se, para que o produto funcione, ele deve ter pelo menos 2 imagens.