Show:

File: platform/plugins/Q/web/js/fn/fisheye.js

(function (Q, $, window, document, undefined) {

/**
 * Q Tools
 * @module Q-tools
 */

/**
 * Adds a fisheye effect to an element and its children
 * @class Q fisheye
 * @constructor
 * @param {Object} [options] possible options
 * @param {Boolean} [options.horizontal=false] whether to do fisheye effect in horizontal direction
 * @param {Boolean} [options.vertical=false] whether to do fisheye effect in vertical direction
 * @param {Boolean} [options.useCenters=false] whether to calculate distance to the center
 *      instead of to the element
 * @param {Boolean} [options.fillContainer=false] whether to stretch elements
 *      to fill the whole container if they take up less width / height
 * @param {Function} [options.distribution] you can provide a continuous function that maps
 *      distance => scale
*/
Q.Tool.jQuery('Q/fisheye',

function _Q_actions(options) {
	var $this = $(this);
	var state = $this.state('Q/fisheye');
	$this.addClass('Q_fisheye').on([Q.Pointer.move, '.Q_fisheye'], function (e) {
		var x = Q.Pointer.getX(e);
		var y = Q.Pointer.getY(e);
		var total = 0, totalWidth = 0, totalHeight = 0;
		var scales = [], widths = [], heights = [];
		// NOTE: the following assumes that the elements have no margins, for now
		// You can fix this by using opacity
		$this.children().each(function () {
			var $child = $(this);
			var offset = $child.offset();
			var width = $child.outerWidth();
			var height = $child.outerHeight();
			var centerX = offset.left + width / 2;
			var centerY = offset.top + height / 2;
			var dx = x - centerX;
			var dy = y - centerY;
			var d;
			if (state.horizontal && state.vertical) {
				d = Math.sqrt((x-centerX)*(x-centerX) + (y-centerY)*(y-centerY));
				if (!state.useCenters) {
					
				}
			} else if (state.horizontal) {
				d = Math.abs(x-centerX);
			} else if (state.vertical) {
				d = Math.abs(y-centerY);
			} else {
				throw new Q.Error("Q/fisheye: horizontal and vertical can't both be false");
			}
			var scale = state.distribution(d);
			scales.push(scale);
			widths.push(width);
			heights.push(height);
			total += scale;
			totalWidth += width;
			totalHeight += height;
		});
		var width = totalWidth;
		var height = totalHeight;
		if (state.fillContainer) {
			width = Math.max(width, this.width());
			height = Math.max(height, this.height());
		}
		
	});
},

{	// default options:
	horizontal: false,
	vertical: true,
	useCenters: false,
	distribution: function (x) {
		return Math.pow(0.9, x) * 0.75 + 0.25;
	},
	fillContainer: false
},

{
	remove: function () {
		$(this).removeClass('Q_fisheye').off('.Q_fisheye');
	}
}

);

})(Q, jQuery, window, document);