COMPONENT

c-comparer

Demo Section

Each variation will be presented in the following sections.

Default

Image
Image

Technical Details

Bower versionGitter Chat

Comparer

Description

The component represents a comparison handler.

It allows you to change via drag the image.


Requirements

  • Veams >= v5.0.0 - Veams Framework.

Installation

Installation with Veams

veams install vc comparer

Installation with Bower

bower install veams-component-comparer --save


Fields

c-comparer.hbs

Settings

  • settings.comparerContextClass {String} [default] - Context class of component.
  • settings.comparerClasses {String} - Modifier classes for component.
  • settings.jsOptions {Object} - JavaScript options which gets stringified.

JavaScript Options

The module gives you the possibility to override default options:

  • handle {String} [’[data-js-item=“comparer-handle”]’] - Define the handler element.
  • topContainer {String} [’[data-js-item=“comparer-top-container”]’] - Define the element for top container.
  • topContent {String} [’[data-js-item=“comparer-top-content”]’] - Define the content element in top container.
  • draggClass {String} [‘is-dragging’] - Define the dragging class.
  • dragMode {Boolean} [true] - Enable or disable drag mode.
  • topContentRight {Boolean} [false] - Reverse the drag mode direction.
  • disabled {Object} [ ‘desktop’: false, ‘tablet-large’: false, ‘tablet-small’: false, ‘mobile-large’: false, ‘mobile-medium’: false, ‘mobile-small’: false ] - Define on which viewport the module is enabled.

Sass Options

There are multiple global variables which you can change:

  • $comparer-color-light [#fff] - Handle color.
{
	"variations": {
		"default": {
			"docs": {
				"variationName": "Default"
			},
			"settings": {
				"classes": false,
				"jsOptions": {
					"isContentRight": false,
					"disabled": {
						"desktop": false,
						"tablet-large": false,
						"tablet-small": false,
						"mobile-large": false,
						"mobile-medium": false,
						"mobile-small": false
					}
				}
			},
			"content": {
				"handleIcon": "http://cdn.onlinewebfonts.com/svg/img_484240.svg",
				"contentTop": {
					"backgroundColorClass": "",
					"picture": "https://dummyimage.com/1920x1000/000/499ea2"
				},
				"contentBottom": {
					"backgroundColorClass": "",
					"picture": "https://dummyimage.com/1920x1000/499ea2/000"
				}
			}
		}
	}
}

c-comparer

<div class="c-comparer{{#if options.settings.comparerContextClass}}--{{options.settings.comparerContextClass}}{{else}}--default{{/if}}{{#if settings.classes}} {{settings.classes}}{{/if}}"
     data-js-module="comparer"
	{{#if settings.jsOptions}}
	 data-js-options="{{stringify settings.jsOptions}}"
	{{/if}}
	 data-css="c-comparer"
>
	{{#with content}}
		<!-- Top Layer -->
		{{#with contentTop}}
			<div class="comparer__top-wrapper{{#if backgroundColorClass}} {{backgroundColorClass}}{{/if}}{{#if
					../../settings.jsOptions.isContentRight}} is-right{{else}} is-left{{/if}}">

				<div class="comparer__top-container" data-js-item="comparer-top-container">

					<!-- Handle Bar -->
					<div class="comparer__handle-bar" data-js-item="comparer-handle"></div>

					<!-- Handle -->
					<div class="comparer__handle" data-js-item="comparer-handle">
						<img src="{{../handleIcon}}">
					</div>

					<!-- Top Content -->
					<div class="comparer__top">
						<div class="comparer__top-content" data-js-item="comparer-top-content">

							{{#if picture}}
								<div class="comparer__picture">
									<img src="{{picture}}" alt="Image"/>
								</div>
							{{/if}}

						</div>
					</div>
				</div>
			</div>
		{{/with}}

		<!-- Bottom Layer -->
		{{#with contentBottom}}
			<div class="comparer__bottom-wrapper{{#if backgroundColorClass}} {{backgroundColorClass}}{{/if}}{{#if
					../../settings.jsOptions.isContentRight}} is-left{{else}} is-right{{/if}}">
				<!-- Bottom Content -->
				<div class="comparer__bottom">

					{{#if picture}}
						<div class="comparer__picture">
							<img src="{{picture}}" alt="Image"/>
						</div>
					{{/if}}

				</div>
			</div>
		{{/with}}

	{{/with}}

</div>

/* ===================================================
Block: comparer
=================================================== */
$comparer-color-light: #fff;

[data-css="c-comparer"] {
	/*
	Global Styles
	----------------------- */
	position: relative;
	overflow: hidden;

	/*
	Modifiers
	----------------------- */
	.is-right {
		.comparer__top-container {
			left: auto;
			right: 0;
			border-right: none;
			border-left: 1px solid $comparer-color-light;
		}

		.comparer__top-content {
			left: auto;
			right: 0;
		}

		.comparer__handle {
			left: 0;
			right: auto;
			transform: translate(-50%, -50%);
		}
	}

	/*
	Top Container
	----------------------- */
	.comparer__top-container {
		background-color: inherit;
		position: absolute;
		left: 0;
		top: 0;
		width: 50%;
		height: 100%;
		min-width: 2%;
		max-width: 98%;
		z-index: 1;
		border-right: 1px solid $comparer-color-light;
	}

	.comparer__top {
		position: relative;
		overflow: hidden;
		height: 100%;
	}

	.comparer__top-content {
		position: absolute;
		left: 0;
		top: 0;
	}

	.comparer__handle-bar {
		height: 100%;
		width: 30px;
		position: absolute;
		right: -15px;
		z-index: 1;
		cursor: col-resize;
	}

	.comparer__handle {
		cursor: col-resize;
		position: absolute;
		top: 50%;
		right: 0;
		width: 87px;
		height: 87px;
		transform: translate(50%, -50%);
		z-index: 2;
		background-color: rgba(255, 255, 255, .5);
		padding: 8px;
		border-radius: 50%;
	}
}

/* ---------------------------------------------------
Context: Default
--------------------------------------------------- */
.c-comparer--default {}

comparer.js

/**
 * Description of ContentComparer.
 *
 * @module ContentComparer
 * @version v3.0.0
 *
 * @author koen.zigterman
 */

import { Veams } from 'app';
import VeamsComponent from 'veams/src/js/common/component';

const $ = Veams.$;

class Comparer extends VeamsComponent {
	/**
	 * Constructor for our class
	 *
	 * @see module.js
	 *
	 * @param {Object} obj - Object which is passed to our class
	 * @param {Object} obj.el - element which will be saved in this.el
	 * @param {Object} obj.options - options which will be passed in as JSON object
	 */
	constructor(obj) {
		let options = {
			handle: '[data-js-item="comparer-handle"]',
			topContainer: '[data-js-item="comparer-top-container"]',
			topContent: '[data-js-item="comparer-top-content"]',
			draggClass: 'is-dragging',
			dragMode: true,
			topContentRight: false,
			disabled: {
				'desktop': false,
				'tablet-large': false,
				'tablet-small': false,
				'mobile-large': false,
				'mobile-medium': false,
				'mobile-small': false
			}
		};

		super(obj, options);
	}

	/** =================================================
	 * GETTER & SETTER
	 * ================================================ */

	/**
	 * Get module information
	 */
	static get info() {
		return {
			version: '3.0.0'
		};
	}

	/** =================================================
	 * EVENTS
	 * ================================================ */

	/**
	 * Subscribe to global events of Veams or App namespace.
	 */
	get subscribe() {
		return {
			'{{Veams.EVENTS.resize}}': 'preRender',
			'{{Veams.EVENTS.mediachange}}': 'render'
		};
	}

	/**
	 * Bind local events to this.$el.
	 */
	get events() {
		return {
			'mousedown {{this.options.handle}}': 'mouseDown',
			'mouseup': 'mouseUp',
			'touchstart {{this.options.handle}}': 'mouseDown',
			'touchend': 'mouseUp',
			'mousemove': 'resizeContainer'
		};
	}

	/** =================================================
	 * STANDARD METHODS
	 * ================================================= */

	/**
	 * Initialize the view and merge options
	 *
	 */
	initialize() {
		this.$topContainer = $(this.options.topContainer, this.$el);
		this.$topContent = $(this.options.topContent, this.$el);
		this.$handle = $(this.options.handle, this.$el);
	}


	/**
	 * Pre-Render method
	 */
	preRender(){
		// Return if module is disabled
		if(this.disabled) return;

		this.elWidth = this.el.clientWidth;
		this.$topContent.css('width', this.elWidth);
	}

	/**
	 * Render method
	 */
	render() {
		if(this.options.disabled[Veams.currentMedia] && !this.disabled){
			this.disabled = true;
			this.resetStyles();
		} else {
			this.disabled = this.options.disabled[Veams.currentMedia];
		}

	}

	/** =================================================
	 * CUSTOM COMPARER METHODS
	 * ================================================= */

	mouseDown(e) {
		e.preventDefault();

		this.dragging = true;
		this.$handle.addClass(this.options.draggClass);
	}

	mouseUp() {
		this.dragging = false;
		this.$handle.addClass(this.options.draggClass);
	}
	/**
	 * Resize top container
	 */
	resizeContainer(e) {
		// Return if module is disabled or if it is not dragging when dragging mode is enabled
		if(this.disabled || !this.dragging && this.options.dragMode ) return;

		let mousePos = this.getMousePos(e);
		let contentWidth = this.options.topContentRight ? this.elWidth - mousePos : 0 + mousePos;

		this.$topContainer.css('width', contentWidth);
	}

	/**
	 * Reset styles
	 */
	resetStyles(){
		this.$topContent.removeAttr('style');
		this.$topContainer.removeAttr('style');
	}

	/**
	 * Get mouse position
	 */
	getMousePos(e) {
		return (e.pageX - this.$el.offset().left);
	}

}

export default Comparer;

Default

<div class="c-comparer--default" data-js-module="comparer" data-js-options="{&quot;isContentRight&quot;:false,&quot;disabled&quot;:{&quot;desktop&quot;:false,&quot;tablet-large&quot;:false,&quot;tablet-small&quot;:false,&quot;mobile-large&quot;:false,&quot;mobile-medium&quot;:false,&quot;mobile-small&quot;:false}}" data-css="c-comparer">
	<!-- Top Layer -->
	<div class="comparer__top-wrapper is-left">
		<div class="comparer__top-container" data-js-item="comparer-top-container">
			<!-- Handle Bar -->
			<div class="comparer__handle-bar" data-js-item="comparer-handle"></div>
			<!-- Handle -->
			<div class="comparer__handle" data-js-item="comparer-handle">
				<img src="http://cdn.onlinewebfonts.com/svg/img_484240.svg">
			</div>
			<!-- Top Content -->
			<div class="comparer__top">
				<div class="comparer__top-content" data-js-item="comparer-top-content">
					<div class="comparer__picture">
						<img src="https://dummyimage.com/1920x1000/000/499ea2" alt="Image" />
					</div>
				</div>
			</div>
		</div>
	</div>
	<!-- Bottom Layer -->
	<div class="comparer__bottom-wrapper is-right">
		<!-- Bottom Content -->
		<div class="comparer__bottom">
			<div class="comparer__picture">
				<img src="https://dummyimage.com/1920x1000/499ea2/000" alt="Image" />
			</div>
		</div>
	</div>
</div>