Angular 1.5 On-Hover Popover Example
by dominathan
HTML
<div ng-app="popoverApp" ng-controller="Ctrl">
<div on-popover-hover class="button">Hover For Popover
<p ng-show="showPopover" class="popover bottom">
<strong class="strong">You did it!</strong> Move your cursor toward the popover. It'll stay open as long as you are moving toward it, within the path between the button and the popover.
</p>
</div>
</div>
SCSS
body {
font-family: sans-serif;
padding: 30px;
}
.button {
background: #000;
border-radius: 6px;
color: #eee;
cursor: default;
display: table;
margin: 0 auto;
padding: 6px 12px;
}
.popover {
animation: popover-in .3s forwards;
background: #000;
border-radius: 6px;
color: #eee;
left: 0;
line-height: 1.4;
margin: 0 auto;
opacity: 0;
padding: 30px;
position: absolute;
right: 0;
text-align: center;
top: 120px;
transform-origin: 50% 0;
width: 300px;
}
.strong {
display: block;
font-weight: bold;
margin-bottom: 6px;
}
@keyframes popover-in {
0% {
opacity: 0;
transform: scale3d(.95,.95,1);
}
100% {
opacity: 1;
transform: scale3d(1,1,1);
}
}
JavaScript
function pointInPolygon(point, vs) {
// ray-casting algorithm based on
// http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
var x = point[0],
y = point[1];
var inside = false;
for (var i = 0, j = vs.length - 1; i < vs.length; j = i++) {
var xi = vs[i][0],
yi = vs[i][1];
var xj = vs[j][0],
yj = vs[j][1];
var intersect = ((yi > y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
if (intersect) inside = !inside;
}
return inside;
};
angular.module('popoverApp', [])
.controller('Ctrl', function($scope) {})
.directive('onPopoverHover', function($compile, $document) {
return {
restrict: '',
link: function($scope, buttonElement, attrs) {
function openPopover() {
$scope.showPopover = true;
$scope.$apply()
}
function closePopover() {
$scope.showPopover = false;
cleanupPopover();
$scope.$apply()
}
var popoverElement = angular.element(buttonElement.children()[0]);
var popoverClientRect = popoverElement[0].getBoundingClientRect();
var elementClientRect = buttonElement[0].getBoundingClientRect();
var popoverRect = {
topLeft: [popoverClientRect.left, popoverClientRect.top],
topRight: [popoverClientRect.right, popoverClientRect.top],
bottomLeft: [popoverClientRect.left, popoverClientRect.bottom],
bottomRight: [popoverClientRect.right, popoverClientRect.bottom]
};
var elementRect = {
topLeft: [elementClientRect.left, elementClientRect.top],
topRight: [elementClientRect.right, elementClientRect.top],
bottomLeft: [elementClientRect.left, elementClientRect.bottom],
bottomRight: [elementClientRect.right, elementClientRect.bottom]
};
buttonElement.on('mouseenter', onButtonEnter);
function getPath() {
if (popoverElement.hasClass('bottom')) {
...