uikit
Version:
UIkit is a lightweight and modular front-end framework for developing fast and powerful web interfaces.
82 lines (56 loc) • 2.01 kB
JavaScript
import {getEventPos, on} from './event';
import {last, pointInRect} from './lang';
export function MouseTracker() {}
MouseTracker.prototype = {
positions: [],
init() {
this.positions = [];
let position;
this.unbind = on(document, 'mousemove', e => position = getEventPos(e));
this.interval = setInterval(() => {
if (!position) {
return;
}
this.positions.push(position);
if (this.positions.length > 5) {
this.positions.shift();
}
}, 50);
},
cancel() {
this.unbind && this.unbind();
this.interval && clearInterval(this.interval);
},
movesTo(target) {
if (this.positions.length < 2) {
return false;
}
const p = target.getBoundingClientRect();
const {left, right, top, bottom} = p;
const [prevPosition] = this.positions;
const position = last(this.positions);
const path = [prevPosition, position];
if (pointInRect(position, p)) {
return false;
}
const diagonals = [[{x: left, y: top}, {x: right, y: bottom}], [{x: left, y: bottom}, {x: right, y: top}]];
return diagonals.some(diagonal => {
const intersection = intersect(path, diagonal);
return intersection && pointInRect(intersection, p);
});
}
};
// Inspired by http://paulbourke.net/geometry/pointlineplane/
function intersect([{x: x1, y: y1}, {x: x2, y: y2}], [{x: x3, y: y3}, {x: x4, y: y4}]) {
const denominator = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);
// Lines are parallel
if (denominator === 0) {
return false;
}
const ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator;
if (ua < 0) {
return false;
}
// Return an object with the x and y coordinates of the intersection
return {x: x1 + ua * (x2 - x1), y: y1 + ua * (y2 - y1)};
}