Skip to content

Two new options: "inset" and "fromCenter" #102

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ $.fn.powerTip.defaults = {
placement: 'n',
smartPlacement: false,
offset: 10,
inset: 20,
fromCenter: 1.0,
mouseOnToPopup: false,
manual: false,
openEvents: [ 'mouseenter', 'focus' ],
Expand Down
9 changes: 9 additions & 0 deletions src/csscoordinates.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,13 @@ function CSSCoordinates() {
me[property] = Math.round(value);
}
};

/**
* Check if a property is set
* @private
* @param {string} property The name of the property.
*/
me.isSet = function(property) {
return $.isNumeric(me[property]);
};
}
59 changes: 43 additions & 16 deletions src/placementcalculator.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,23 @@ function PlacementCalculator() {
* @param {string} placement The placement for the tooltip.
* @param {number} tipWidth Width of the tooltip element in pixels.
* @param {number} tipHeight Height of the tooltip element in pixels.
* @param {number} offset Distance to offset tooltips in pixels.
* @param {number} options.offset Distance to offset tooltips in pixels.
* @param {number} options.fromCenter Distance along line from center (0) to boundary (1).
* @param {number} options.inset Distance from corner of tooltip to object for ne, nw, se, sw.
* @return {CSSCoordinates} A CSSCoordinates object with the position.
*/
function computePlacementCoords(element, placement, tipWidth, tipHeight, offset) {
function computePlacementCoords(element, placement, tipWidth, tipHeight, options ) {
var placementBase = placement.split('-')[0], // ignore 'alt' for corners
offset = options.offset,
fromCenter = options.fromCenter,
inset = options.inset,
coords = new CSSCoordinates(),
position;

if (isSvgElement(element)) {
position = getSvgPlacement(element, placementBase);
position = getSvgPlacement(element, placementBase, fromCenter);
} else {
position = getHtmlPlacement(element, placementBase);
position = getHtmlPlacement(element, placementBase, fromCenter);
}

// calculate the appropriate x and y position in the document
Expand All @@ -55,14 +60,14 @@ function PlacementCalculator() {
break;
case 'nw':
coords.set('bottom', session.windowHeight - position.top + offset);
coords.set('right', session.windowWidth - position.left - 20);
coords.set('right', session.windowWidth - position.left - inset);
break;
case 'nw-alt':
coords.set('left', position.left);
coords.set('bottom', session.windowHeight - position.top + offset);
break;
case 'ne':
coords.set('left', position.left - 20);
coords.set('left', position.left - inset);
coords.set('bottom', session.windowHeight - position.top + offset);
break;
case 'ne-alt':
Expand All @@ -71,14 +76,14 @@ function PlacementCalculator() {
break;
case 'sw':
coords.set('top', position.top + offset);
coords.set('right', session.windowWidth - position.left - 20);
coords.set('right', session.windowWidth - position.left - inset);
break;
case 'sw-alt':
coords.set('left', position.left);
coords.set('top', position.top + offset);
break;
case 'se':
coords.set('left', position.left - 20);
coords.set('left', position.left - inset);
coords.set('top', position.top + offset);
break;
case 'se-alt':
Expand All @@ -90,20 +95,36 @@ function PlacementCalculator() {
return coords;
}

/**
* Finds the weighted average of two values
* @private
* @param {number} a the first value (returned if weight=0)
* @param {number} b the second value (returned if weight=1)
* @param {number} weight the weight (0 <= weight <= 1)
*/
function weightedAvg(a, b, weight) {
return Math.round( b * weight + a * (1.0 - weight) );
}

/**
* Finds the tooltip attachment point in the document for a HTML DOM element
* for the specified placement.
* @private
* @param {jQuery} element The element that the tooltip should target.
* @param {string} placement The placement for the tooltip.
* @param {number} fromCenter The relative distance between center and boundary
* @return {Object} An object with the top,left position values.
*/
function getHtmlPlacement(element, placement) {
function getHtmlPlacement(element, placement, fromCenter) {
var objectOffset = element.offset(),
objectWidth = element.outerWidth(),
objectHeight = element.outerHeight(),
left,
top;
top,
objectCenter = {
top: objectOffset.top + objectHeight / 2,
left: objectOffset.left + objectWidth / 2
};

// calculate the appropriate x and y position in the document
switch (placement) {
Expand Down Expand Up @@ -142,8 +163,8 @@ function PlacementCalculator() {
}

return {
top: top,
left: left
top: weightedAvg(objectCenter.top, top, fromCenter),
left: weightedAvg(objectCenter.left, left, fromCenter)
};
}

Expand All @@ -153,9 +174,10 @@ function PlacementCalculator() {
* @private
* @param {jQuery} element The element that the tooltip should target.
* @param {string} placement The placement for the tooltip.
* @param {number} fromCenter The relative distance between center and boundary
* @return {Object} An object with the top,left position values.
*/
function getSvgPlacement(element, placement) {
function getSvgPlacement(element, placement, fromCenter) {
var svgElement = element.closest('svg')[0],
domElement = element[0],
point = svgElement.createSVGPoint(),
Expand All @@ -166,6 +188,7 @@ function PlacementCalculator() {
placements = [],
placementKeys = ['nw', 'n', 'ne', 'e', 'se', 's', 'sw', 'w'],
coords,
center = svgElement.createSVGPoint(),
rotation,
steps,
x;
Expand All @@ -174,9 +197,12 @@ function PlacementCalculator() {
placements.push(point.matrixTransform(matrix));
}

// get bounding box corners and midpoints
// Get bounding box corners and midpoints
point.x = boundingBox.x;
point.y = boundingBox.y;
center.x = point.x + halfWidth;
center.y = point.y + halfHeight;
center = center.matrixTransform(matrix);
pushPlacement();
point.x += halfWidth;
pushPlacement();
Expand All @@ -197,6 +223,7 @@ function PlacementCalculator() {
if (placements[0].y !== placements[1].y || placements[0].x !== placements[7].x) {
rotation = Math.atan2(matrix.b, matrix.a) * RAD2DEG;
steps = Math.ceil(((rotation % 360) - 22.5) / 45);
center = center.matrixTransform(matrix);
if (steps < 1) {
steps += 8;
}
Expand All @@ -214,8 +241,8 @@ function PlacementCalculator() {
}

return {
top: coords.y + session.scrollTop,
left: coords.x + session.scrollLeft
top: weightedAvg(center.y, coords.y, fromCenter) + session.scrollTop,
left: weightedAvg(center.x, coords.x, fromCenter) + session.scrollLeft
};
}

Expand Down
2 changes: 1 addition & 1 deletion src/tooltipcontroller.js
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ function TooltipController(options) {
placement,
tipWidth,
tipHeight,
options.offset
options
);

// place the tooltip
Expand Down