Joomla Image Comparison Slider Plugin

Simply put, it's just an image comparison plugin for Joomla. After installing it, you need to enable it on plugin manager (Content - JMP Image Comparison Slider).

Buy Now ( $13 ) Demo Forum

It works with Joomla 2.5+, 3, 4 and 5.

Then go to The Article or Custom Module and add the syntax below:

{ics data-before="URL of first image" data-after="URL of second image" data-before-text="Custom text for first image (Optional)" data-after-text="Custom text for second image (Optional)" }

-------

Example:

{ics data-before="image/pic1.jpeg" data-after="image/pic2.jpeg" data-before-text="Old" data-after-text="New" }

-------

List files:

  • assets
  • jmpics.php
  • jmpics.xml

 

File: script.js

(function($){
	$(document).ready(function(){
		$('.jmpics').each(function(){
			let el=$(this), h='';

			if(typeof el.attr('data-before')=='undefined' || typeof el.attr('data-after')=='undefined') return;

			h='<figure class="cd-image-container">';
				h+='<img src="'+el.attr('data-before')+'" alt="">';
				if(typeof el.attr('data-before-text')!='undefined')
					h+='<span class="cd-image-label" data-type="original">'+el.attr('data-before-text')+'</span>';

				h+='<div class="cd-resize-img">';
					h+='<img src="'+el.attr('data-after')+'" alt="">';
					if(typeof el.attr('data-after-text')!='undefined')
						h+='<span class="cd-image-label" data-type="modified">'+el.attr('data-after-text')+'</span>';
				h+='</div>';
				h+='<span class="cd-handle"></span>';
			h+='</figure>';

			el.replaceWith(h);
		});

		// ics
		var dragging = false,
        scrolling = false,
        resizing = false;
	    
	    //cache jQuery objects
	    var imageComparisonContainers = $('.cd-image-container');
	    
	    //check if the .cd-image-container is in the viewport 
	    //if yes, animate it
	    checkPosition(imageComparisonContainers);
	    $(window).on('scroll', function(){
	        if( !scrolling) {
	            scrolling =  true;
	            ( !window.requestAnimationFrame )
	                ? setTimeout(function(){checkPosition(imageComparisonContainers);}, 100)
	                : requestAnimationFrame(function(){checkPosition(imageComparisonContainers);});
	        }
	    });
	    
	    //make the .cd-handle element draggable and modify .cd-resize-img width according to its position
	    imageComparisonContainers.each(function(){
	        var actual = $(this);
	        drags(actual.find('.cd-handle'), actual.find('.cd-resize-img'), actual, actual.find('.cd-image-label[data-type="original"]'), actual.find('.cd-image-label[data-type="modified"]'));
	    });

	    //upadate images label visibility
	    $(window).on('resize', function(){
	        if( !resizing) {
	            resizing =  true;
	            ( !window.requestAnimationFrame )
	                ? setTimeout(function(){checkLabel(imageComparisonContainers);}, 100)
	                : requestAnimationFrame(function(){checkLabel(imageComparisonContainers);});
	        }
	    });

	    function checkPosition(container) {
	        container.each(function(){
	            var actualContainer = $(this);
	            if( $(window).scrollTop() + $(window).height()*0.5 > actualContainer.offset().top) {
	                actualContainer.addClass('is-visible');
	            }
	        });

	        scrolling = false;
	    }

	    function checkLabel(container) {
	        container.each(function(){
	            var actual = $(this);
	            updateLabel(actual.find('.cd-image-label[data-type="modified"]'), actual.find('.cd-resize-img'), 'left');
	            updateLabel(actual.find('.cd-image-label[data-type="original"]'), actual.find('.cd-resize-img'), 'right');
	        });

	        resizing = false;
	    }

	    //draggable funtionality - credits to http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/
	    function drags(dragElement, resizeElement, container, labelContainer, labelResizeElement) {
	        dragElement.on("mousedown vmousedown", function(e) {
	            dragElement.addClass('draggable');
	            resizeElement.addClass('resizable');

	            var dragWidth = dragElement.outerWidth(),
	                xPosition = dragElement.offset().left + dragWidth - e.pageX,
	                containerOffset = container.offset().left,
	                containerWidth = container.outerWidth(),
	                minLeft = containerOffset + 10,
	                maxLeft = containerOffset + containerWidth - dragWidth - 10;
	            
	            dragElement.parents().on("mousemove vmousemove", function(e) {
	                if( !dragging) {
	                    dragging =  true;
	                    ( !window.requestAnimationFrame )
	                        ? setTimeout(function(){animateDraggedHandle(e, xPosition, dragWidth, minLeft, maxLeft, containerOffset, containerWidth, resizeElement, labelContainer, labelResizeElement);}, 100)
	                        : requestAnimationFrame(function(){animateDraggedHandle(e, xPosition, dragWidth, minLeft, maxLeft, containerOffset, containerWidth, resizeElement, labelContainer, labelResizeElement);});
	                }
	            }).on("mouseup vmouseup", function(e){
	                dragElement.removeClass('draggable');
	                resizeElement.removeClass('resizable');
	            });
	            e.preventDefault();
	        }).on("mouseup vmouseup", function(e) {
	            dragElement.removeClass('draggable');
	            resizeElement.removeClass('resizable');
	        });
	    }

	    function animateDraggedHandle(e, xPosition, dragWidth, minLeft, maxLeft, containerOffset, containerWidth, resizeElement, labelContainer, labelResizeElement) {
	        var leftValue = e.pageX + xPosition - dragWidth;   
	        //constrain the draggable element to move inside his container
	        if(leftValue < minLeft ) {
	            leftValue = minLeft;
	        } else if ( leftValue > maxLeft) {
	            leftValue = maxLeft;
	        }

	        var widthValue = (leftValue + dragWidth/2 - containerOffset)*100/containerWidth+'%';
	        
	        $('.draggable').css('left', widthValue).on("mouseup vmouseup", function() {
	            $(this).removeClass('draggable');
	            resizeElement.removeClass('resizable');
	        });

	        $('.resizable').css('width', widthValue); 

	        updateLabel(labelResizeElement, resizeElement, 'left');
	        updateLabel(labelContainer, resizeElement, 'right');
	        dragging =  false;
	    }

	    function updateLabel(label, resizeElement, position) {
	        if(position == 'left') {
	            ( label.offset().left + label.outerWidth() < resizeElement.offset().left + resizeElement.outerWidth() ) ? label.removeClass('is-hidden') : label.addClass('is-hidden') ;
	        } else {
	            ( label.offset().left > resizeElement.offset().left + resizeElement.outerWidth() ) ? label.removeClass('is-hidden') : label.addClass('is-hidden') ;
	        }
	    }
	});
})(jQuery);

 

File: style.css

.hidden{display:none!important}
.cd-image-container{position:relative;display:inline-block;max-width:768px;margin:0 auto}
.cd-image-container img{display:block}
.cd-image-label{position:absolute;bottom:0;right:0;color:#fff;padding:1em;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;opacity:0;-webkit-transform:translateY(20px);-moz-transform:translateY(20px);-ms-transform:translateY(20px);-o-transform:translateY(20px);transform:translateY(20px);-webkit-transition:-webkit-transform .3s 0.7s,opacity .3s .7s;-moz-transition:-moz-transform .3s 0.7s,opacity .3s .7s;transition:transform .3s 0.7s,opacity .3s .7s}
.cd-image-label.is-hidden{visibility:hidden}
.is-visible .cd-image-label{opacity:1;-webkit-transform:translateY(0);-moz-transform:translateY(0);-ms-transform:translateY(0);-o-transform:translateY(0);transform:translateY(0)}
.cd-resize-img{position:absolute;top:0;left:0;width:0;height:100%;overflow:hidden;-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0);-webkit-backface-visibility:hidden;backface-visibility:hidden}
.cd-resize-img img{position:absolute;left:0;top:0;display:block;height:100%;width:auto;max-width:none}
.cd-resize-img .cd-image-label{right:auto;left:0}
.is-visible .cd-resize-img{width:50%;-webkit-animation:cd-bounce-in .7s;-moz-animation:cd-bounce-in .7s;animation:cd-bounce-in .7s}
@-webkit-keyframes cd-bounce-in {
0%{width:0}
60%{width:55%}
100%{width:50%}
}
@-moz-keyframes cd-bounce-in {
0%{width:0}
60%{width:55%}
100%{width:50%}
}
@keyframes cd-bounce-in {
0%{width:0}
60%{width:55%}
100%{width:50%}
}
.cd-handle{position:absolute;height:44px;width:44px;left:50%;top:50%;margin-left:-22px;margin-top:-22px;border-radius:50%;background:#dc717d url(cd-arrows.svg) no-repeat center center;cursor:move;box-shadow:0 0 0 6px rgba(0,0,0,0.2),0 0 10px rgba(0,0,0,0.6),inset 0 1px 0 rgba(255,255,255,0.3);opacity:0;-webkit-transform:translate3d(0,0,0) scale(0);-moz-transform:translate3d(0,0,0) scale(0);-ms-transform:translate3d(0,0,0) scale(0);-o-transform:translate3d(0,0,0) scale(0);transform:translate3d(0,0,0) scale(0)}
.cd-handle.draggable{background-color:#445b7c}
.is-visible .cd-handle{opacity:1;-webkit-transform:translate3d(0,0,0) scale(1);-moz-transform:translate3d(0,0,0) scale(1);-ms-transform:translate3d(0,0,0) scale(1);-o-transform:translate3d(0,0,0) scale(1);transform:translate3d(0,0,0) scale(1);-webkit-transition:-webkit-transform .3s 0.7s,opacity 0 .7s;-moz-transition:-moz-transform .3s 0.7s,opacity 0 .7s;transition:transform .3s 0.7s,opacity 0 .7s}

-------

Please share it if you find it useful. The article is referenced from the CodyHouse.

You may also like

K2 to Content Migration

Restrict Username, Name field for Joomla

The Best Articles Comment Extensions on Joomla 4

Say something here...
You are a guest ( Sign Up ? )
or post as a guest
People in conversation:
Loading comment... The comment will be refreshed after 00:00.
  • This commment is unpublished.
    Théo · 1 years ago
    Hello,
    I just picked up your tool.
    I'm on Joomla 4.0.3 Php8.0.
    After installation and creation of the module with the syntax and modification of the field for images. It doesn't work on my page.
    The site displays the syntax at the top of the page without displaying anything else.

    Any ideas?
    Thanks in advance.
  • This commment is unpublished.
    David · 1 years ago
    Release Image Comparison Slider v1.2.1 - Improved drag tools.
  • This commment is unpublished.
    Carsten · 2 years ago
    Hi guys I like the plugin but it does not work with Joomla 4.23 and PHP 8.0. I was activate the plugin and droped the code for two pictures in a text

    {ics data-before="/images/beforeafterimagesslide/freisteller-service-haare.jpg" data-after="/images/beforeafterimagesslide/bilder-freistellen-transparent.jpg"}

    But unfortunately nothing appears... any ideas?

    Thanks

    Carsten
    • This commment is unpublished.
      David · 2 years ago
      @Carsten Hi,
      I used the code you provided, replaced it with my pictures and checked on Joomla the latest version, it still works. Can you let me know the website address where you put this plugin?
  • This commment is unpublished.
    mic · 2 years ago
    doesn't work on my

    Joomla! 3.10.10 Stable [ Daraja ] 18-June-2022 16:32 GMT
    • This commment is unpublished.
      mic · 2 years ago
      @mic FYI: Debug Errors shown in Console

      imagecomparision:69 Uncaught TypeError: $(...).find(...).tooltip is not a function
      at initTooltips (imagecomparision:69:194)
      at HTMLDocument.<anonymous> (imagecomparision:69:21)
      at u (jquery.min.js?ad48fcf4eded40f912920a955f1065d5:2:27579)
      at Object.fireWith [as resolveWith] (jquery.min.js?ad48fcf4eded40f912920a955f1065d5:2:28337)
      at Function.ready (jquery.min.js?ad48fcf4eded40f912920a955f1065d5:2:30124)
      at HTMLDocument._ (jquery.min.js?ad48fcf4eded40f912920a955f1065d5:2:27307)
      initTooltips @ imagecomparision:69
      (anonymous) @ imagecomparision:69
      u @ jquery.min.js?ad48fcf4eded40f912920a955f1065d5:2
      fireWith @ jquery.min.js?ad48fcf4eded40f912920a955f1065d5:2
      ready @ jquery.min.js?ad48fcf4eded40f912920a955f1065d5:2
      _ @ jquery.min.js?ad48fcf4eded40f912920a955f1065d5:2
    • This commment is unpublished.
      mic · 2 years ago
      @mic works now. needs a Slash before "image..."

Powered By JLex Comment.