Navigation
This is archived content. Visit our new forum.

Tagged: 

  • Author
    Posts
  • #1012544
    peterok
    Participant

    Hi, I was wondering of we could add additional functions to our theme with customer scripts?

    Image Zoom Magnifying Glass Effect with CSS3 and jQuery

    I’m looking to add the above function to my shop pages.

    #1012569
    Lely
    Moderator

    Hi There,

    Thanks for posting in.
    Please add this on Appearance > Customizer > Custom > Edit Global CSS:

    .glass {
      width: 175px;
      height: 175px;
      position: absolute;
      border-radius: 50%;
      cursor: crosshair;
     
      /* Multiple box shadows to achieve the glass effect */
      box-shadow:
        0 0 0 7px rgba(255, 255, 255, 0.85),
        0 0 7px 7px rgba(0, 0, 0, 0.25),
        inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
     
      /* hide the glass by default */
      display: none;
    }

    Then add the following on Appearance > Customizer > Custom > Edit Global Javascript:

    jQuery(function($) {
    
      var native_width = 0;
      var native_height = 0;
      var mouse = {x: 0, y: 0};
      var magnify;
      var cur_img;
    
      var ui = {
        magniflier: $('.magniflier, .magniflier-shop img')
      };
    
      // Add the magnifying glass
      if (ui.magniflier.length) {
        var div = document.createElement('div');
        div.setAttribute('class', 'glass');
        ui.glass = $(div);
    
        $('body').append(div);
      }
    
      
      // All the magnifying will happen on "mousemove"
    
      var mouseMove = function(e) {
        var $el = $(this);
    
        // Container offset relative to document
        var magnify_offset = cur_img.offset();
    
        // Mouse position relative to container
        // pageX/pageY - container's offsetLeft/offetTop
        mouse.x = e.pageX - magnify_offset.left;
        mouse.y = e.pageY - magnify_offset.top;
        
        // The Magnifying glass should only show up when the mouse is inside
        // It is important to note that attaching mouseout and then hiding
        // the glass wont work cuz mouse will never be out due to the glass
        // being inside the parent and having a higher z-index (positioned above)
        if (
          mouse.x < cur_img.width() &&
          mouse.y < cur_img.height() &&
          mouse.x > 0 &&
          mouse.y > 0
          ) {
    
          magnify(e);
        }
        else {
          ui.glass.fadeOut(100);
        }
    
        return;
      };
    
      var magnify = function(e) {
    
        // The background position of div.glass will be
        // changed according to the position
        // of the mouse over the img.magniflier
        //
        // So we will get the ratio of the pixel
        // under the mouse with respect
        // to the image and use that to position the
        // large image inside the magnifying glass
    
        var rx = Math.round(mouse.x/cur_img.width()*native_width - ui.glass.width()/2)*-1;
        var ry = Math.round(mouse.y/cur_img.height()*native_height - ui.glass.height()/2)*-1;
        var bg_pos = rx + "px " + ry + "px";
        
        // Calculate pos for magnifying glass
        //
        // Easy Logic: Deduct half of width/height
        // from mouse pos.
    
        // var glass_left = mouse.x - ui.glass.width() / 2;
        // var glass_top  = mouse.y - ui.glass.height() / 2;
        var glass_left = e.pageX - ui.glass.width() / 2;
        var glass_top  = e.pageY - ui.glass.height() / 2;
        //console.log(glass_left, glass_top, bg_pos)
        // Now, if you hover on the image, you should
        // see the magnifying glass in action
        ui.glass.css({
          left: glass_left,
          top: glass_top,
          backgroundPosition: bg_pos
        });
    
        return;
      };
    
      $('.magniflier, .magniflier-shop img').on('mousemove', function() {
        
        ui.glass.fadeIn(100);
        
        cur_img = $(this);
    
        var large_img_loaded = cur_img.data('large-img-loaded');
        var src = cur_img.data('large') || cur_img.attr('src');
    
        // Set large-img-loaded to true
        // cur_img.data('large-img-loaded', true)
    
        if (src) {
          ui.glass.css({
            'background-image': 'url(' + src + ')',
            'background-repeat': 'no-repeat'
          });
        }
    
        // When the user hovers on the image, the script will first calculate
        // the native dimensions if they don't exist. Only after the native dimensions
        // are available, the script will show the zoomed version.
        //if(!native_width && !native_height) {
    
          if (!cur_img.data('native_width')) {
            // This will create a new image object with the same image as that in .small
            // We cannot directly get the dimensions from .small because of the 
            // width specified to 200px in the html. To get the actual dimensions we have
            // created this image object.
            var image_object = new Image();
    
            image_object.onload = function() {
              // This code is wrapped in the .load function which is important.
              // width and height of the object would return 0 if accessed before 
              // the image gets loaded.
              native_width = image_object.width;
              native_height = image_object.height;
    
              cur_img.data('native_width', native_width);
              cur_img.data('native_height', native_height);
    
              //console.log(native_width, native_height);
    
              mouseMove.apply(this, arguments);
    
              ui.glass.on('mousemove', mouseMove);
            };
    
            image_object.src = src;
            
            return;
          } else {
    
            native_width = cur_img.data('native_width');
            native_height = cur_img.data('native_height');
          }
        //}
        //console.log(native_width, native_height);
    
        mouseMove.apply(this, arguments);
    
        ui.glass.on('mousemove', mouseMove);
      });
    
      ui.glass.on('mouseout', function() {
        ui.glass.off('mousemove', mouseMove);
      });
    
    });
    
    

    Because this requires a template change, I’d advise that you setup a child theme. This allows you to make code changes that won’t be overwritten when an X update is released. After your child theme is setup, please review how we recommend making template changes in Customization Best Practices.

    Copy the file loop-start.php from wp-content\themes\x\woocommerce\loop
    to wp-content\themes\x-child\woocommerce\loop.

    Open the copied file and replace the entire content with the following:

    <?php
    
    // =============================================================================
    // WOOCOMMERCE/LOOP/LOOP-START.PHP
    // -----------------------------------------------------------------------------
    // @version 2.0.0
    // =============================================================================
    
    ?>
    
    <?php $columns      = x_get_option( 'x_woocommerce_shop_columns' ); ?>
    <?php $column_class = ( is_shop() || is_product_category() || is_product_tag() ) ? ' cols-' . $columns : ''; ?>
    
    <ul class="products magniflier-shop <?php echo $column_class; ?>">

    Hope this helps.

    Further customizations from here would be getting into custom development, which is outside the scope of support we can offer. If you need more in depth changes, you may wish to consult with a developer. X is quite extensible with child themes, so there are plenty of possibilities. Thanks for understanding.

    #1012655
    peterok
    Participant
    This reply has been marked as private.
    #1012690
    Lely
    Moderator

    Hi There,

    Yes, on normal images we have to add magniflier to image class field. Since on shop page, it is controlled by template, we also need to add some identifier.

    Hope this helps.

  • <script> jQuery(function($){ $("#no-reply-1012544 .bbp-template-notice, .bbp-no-topic .bbp-template-notice").removeClass('bbp-template-notice'); }); </script>