hotspots


I want to a add hotspots circles on these two images in multicolumn section. the purpose of the hotspots is to display the price tag when the user hover on the hotspot item.

Hi @rehamessawy
You can follow the below instructions to make the image hotspot

Step 1: Create a section and name it tooltips So once saved, It will be tooltips.liquid

Step 2: Add the below code to the tooltips.liquid

{%- comment -%} ---------------- THE CSS --------------------- {%- endcomment -%}

{%- assign button_width_small = 28 -%}
{%- assign button_width_large = 20 -%}
{%- assign tooltip_max_width = 320 -%}
{%- assign image_aspect_ratio = section.settings.image.aspect_ratio | default: 1 -%}
{%- assign section_selector = '[data-tooltips="' | append: section.id | append: '"]'-%}
{%- style -%}
  .section-{{ section.id }}-padding {
    padding-top: {{ section.settings.padding_top | times: 0.5 | round: 0 }}px;
    padding-bottom: {{ section.settings.padding_bottom | times: 0.5 | round: 0 }}px;
  }

  @media screen and (min-width: 750px) {
    .section-{{ section.id }}-padding {
      padding-top: {{ section.settings.padding_top }}px;
      padding-bottom: {{ section.settings.padding_bottom }}px;
    }
  }
{%- endstyle -%}

{%- comment -%} ---------------- THE NO-JS ------------------- {%- endcomment -%}

{%- comment -%} ---------------- THE MARKUP ------------------ {%- endcomment -%}

  
  
  
  
    {%- for block in section.blocks -%}
      {% if block.settings.selected_product %}
        {% assign product = block.settings.selected_product %}
    1. 
        {% endif %}
    {%- endfor -%}
  

  
  
{%- comment -%} ---------------- THE CONFIG ------------------ {%- endcomment -%}
  
  

{%- comment -%} ------------------ THE JS -------------------- {%- endcomment -%}

{%- comment -%} --------------- THEME EDITOR ----------------- {%- endcomment -%}

{%- if section.blocks.last.shopify_attributes != blank -%}

{%- endif -%}

{%- comment -%} ---------------- THE SETTINGS ---------------- {%- endcomment -%}

{% schema %}
{
  "name": "Image Tag",
  "class": "sd-tooltips",
  "settings": [
    {
      "type": "paragraph",
      "content": "Image tag section"
    },
    {
      "type": "image_picker",
      "id": "image",
      "label": "Background image"
    },
    {
      "type": "color",
      "id": "tooltip_background_color",
      "label": "Dots background color",
      "default": "#64cbdf"
    },
    {
      "type": "header",
      "content": "t:sections.all.padding.section_padding_heading"
    },
    {
      "type": "range",
      "id": "padding_top",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_top",
      "default": 0
    },
    {
      "type": "range",
      "id": "padding_bottom",
      "min": 0,
      "max": 100,
      "step": 4,
      "unit": "px",
      "label": "t:sections.all.padding.padding_bottom",
      "default": 0
    }
  ],
  "blocks": [
    {
      "type": "Tooltip",
      "name": "Tag",
      "settings": [
        {
          "type": "product",
          "id": "selected_product",
          "label": "Select product to show on this Tag"
        },
        {
          "type": "range",
          "id": "top",
          "min": 0,
          "max": 100,
          "step": 1,
          "unit": "%",
          "label": "Top position",
          "default": 50
        },
        {
          "type": "range",
          "id": "left",
          "min": 0,
          "max": 100,
          "step": 1,
          "unit": "%",
          "label": "Left position",
          "default": 50
        },
         {
          "type": "range",
          "id": "right",
          "min": 0,
          "max": 100,
          "step": 1,
          "unit": "%",
          "label": "Right position",
          "default": 0
        },
        {
          "type": "text",
          "id": "button_label",
          "label": "Button Label"
        },
        {
          "type": "checkbox",
          "id": "new_window",
         "default":false,
          "label": "Open link in new window"
        }
      ]
    }
  ],
  "presets": [
    {
      "name": "Image Tag",
      "blocks": [
        {
          "type": "Tooltip"
        }
      ]
    }
  ]
}
{% endschema %}

Step 3: Go to assets and add JS file and name it tooltips So once saved, It will be tooltips.js

Step 4: Add the below code to the tooltips.js

(function Tooltips(SD){
  'use strict';
  
  var support = getSupport();
  var instances = nodeList('[data-tooltips-config]');

  instances.map(function(instance){
    var config = Object.freeze(getConfig(instance));

    var publicAPI = {
      tooltips: function() { return getTooltips(config) },
      tooltip: getTooltip,
      select: select,
      deselect: deselect,
      config: config,
      init: init
    }

    if (!SD[config.sectionId]) init(config);    
    SD[config.sectionId] = publicAPI;
    
    return publicAPI;
  })

  // ******************************

  function init(config) {
    var tooltips = getTooltips(config);
    var triggers = pluck(tooltips, 'trigger');

    triggers.map(function(element) {
      element.addEventListener('click', function triggerClick() {
        tooltipClick(tooltips, element.value);
      });
    });
  }

  function getConfig(instance) {
    return JSON.parse(instance.innerHTML);
  }

  function getTooltips(config) {
    return config.blocksId.map(getTooltip);
  }

  function getTooltip(id) {
    var host = document.getElementById('tooltip-' + id);

    return {
      id: id,
      trigger: host.querySelector('[data-tooltip-trigger]'),
      overlay: host.querySelector('[data-tooltip-overlay]'),
      markup: host.querySelector('[data-tooltip-markup]'),
      get collapsed() { return isCollapsed(this) }
    }
  }

  function tooltipClick(tooltips, id) {
    var isSelected = partial(idMatch, id);
    tooltips.filter(isSelected).map(toggle);
    tooltips.filter(not(isSelected)).filter(not(isCollapsed)).map(collapse);
  }
  
  function toggle(tooltip) {
    tooltip.collapsed ? expand(tooltip) : collapse(tooltip);
  }

  function expand(tooltip) {
    tooltip.overlay.innerHTML = tooltip.markup.textContent;
    tooltip.overlay.style.setProperty('--end-h', height(tooltip));
    tooltip.overlay.style.setProperty('--start-h', '0px');
    tooltip.trigger.setAttribute('aria-expanded', true);

    tooltip.overlay.addEventListener('animationend', function animationEndFn() {
      animationReset(tooltip.overlay, animationEndFn);
    });

    return tooltip;
  }

  function collapse(tooltip) {
    tooltip.overlay.style.setProperty('--start-h',  height(tooltip));
    tooltip.overlay.style.setProperty('--end-h', '0px');
    tooltip.trigger.setAttribute('aria-expanded', false);
    
    if (!support.customProperties) tooltip.overlay.innerHTML = '';

    tooltip.overlay.addEventListener('animationend', function animationEndFn() {
      animationReset(tooltip.overlay, animationEndFn);
      tooltip.overlay.innerHTML = '';
    });

    return tooltip;
  }

  function animationReset(element, callback) {
    element.removeAttribute('style');
    element.removeEventListener('animationend', callback);
  }

  function idMatch(id, tooltip) {
    return tooltip.id === id;
  }

  function isCollapsed(tooltip) {
    return attr('aria-expanded', tooltip.trigger) === 'false';
  }

  function height(tooltip) {
    return px(tooltip.overlay.offsetHeight.toString());
  }

  function px(n) {
    return n + 'px';
  }

  /* DOM */
  function attr(str, element) {
    return element.getAttribute(str);
  }

  function nodeList(str, root) {
    if (!root) root = document;
    var nodeList = root.querySelectorAll(str);
    return Array.prototype.slice.call(nodeList);
  }

  /* Fn */
  function not(predicate) {
    return function negated() {
      return !predicate.apply(undefined, arguments);
    };
  }

  function pluck(array, key) {
    return array.map(function(obj) {
      return obj[key];
    });
  }

  function partial(fn) {
    var slice = Array.prototype.slice;
    var args = slice.call(arguments, 1);
    return function() {
      return fn.apply(this, args.concat(slice.call(arguments, 0)));
    };
  }

  /* Support */
  function getSupport() {
    return {
      customProperties: window.CSS && CSS.supports('color', 'var(--primary)'),
    }
  }

  /* Theme editor */
  function select(blockId) {
    return expand(getTooltip(blockId));
  }

  function deselect(blockId) {
    return collapse(getTooltip(blockId));
  }
  
})(window.SectionsDesign = window.SectionsDesign || {});

const tooltipButtons = document.querySelectorAll('.tooltip-button');
document.addEventListener('click', function (e) {
  const target = e.target.closest('.tooltip-close');
  if(target){
    tooltipButtons.forEach(function(e){
      e.setAttribute('aria-expanded', 'false');
    });
  } else {
    let isClickInside = false;
    tooltipButtons.forEach(function(button) {
      if(button.contains(e.target)) {
        isClickInside = true;
      }
    });
    if(!isClickInside) {
      tooltipButtons.forEach(function(button){
        button.setAttribute('aria-expanded', 'false');
      });
    }
  }
});

Once the code is added goto the theme customizer and add section Image Tag where you can upload Background image and dots color then you can add the tag and select the product you want to show with that you can also change the position of the tag on the image. You can add upto 50 tags / hotspot on the image.

Thank you

D.P.

idk if i did something wrong but the tag is not linked to the image it appears on my header and this error appears:

  1. 1
    Liquid error (sections/tooltips line 233): Could not find asset snippets/icon-close-large.liquid Liquid error (sections/tooltips line 240): Could not find asset snippets/price.liquid Translation missing: es.products.product.tooltip_button

    Help?