paper.js/src/dom/DomEvent.js
2014-03-12 13:22:41 +01:00

130 lines
3.3 KiB
JavaScript

/*
* Paper.js - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/
*
* Copyright (c) 2011 - 2014, Juerg Lehni & Jonathan Puckey
* http://scratchdisk.com/ & http://jonathanpuckey.com/
*
* Distributed under the MIT license. See LICENSE file for details.
*
* All rights reserved.
*/
/**
* @name DomEvent
* @namespace
* @private
*/
var DomEvent = /** @lends DomEvent */{
add: function(el, events) {
for (var type in events) {
var func = events[type],
parts = type.split(/[\s,]+/g);
for (var i = 0, l = parts.length; i < l; i++)
el.addEventListener(parts[i], func, false);
}
},
remove: function(el, events) {
for (var type in events) {
var func = events[type],
parts = type.split(/[\s,]+/g);
for (var i = 0, l = parts.length; i < l; i++)
el.removeEventListener(parts[i], func, false);
}
},
getPoint: function(event) {
var pos = event.targetTouches
? event.targetTouches.length
? event.targetTouches[0]
: event.changedTouches[0]
: event;
return new Point(
pos.pageX || pos.clientX + document.documentElement.scrollLeft,
pos.pageY || pos.clientY + document.documentElement.scrollTop
);
},
getTarget: function(event) {
return event.target || event.srcElement;
},
getRelatedTarget: function(event) {
return event.relatedTarget || event.toElement;
},
getOffset: function(event, target) {
// Remove target offsets from page coordinates
return DomEvent.getPoint(event).subtract(DomElement.getOffset(
target || DomEvent.getTarget(event)));
},
stop: function(event) {
event.stopPropagation();
event.preventDefault();
}
};
DomEvent.requestAnimationFrame = new function() {
var nativeRequest = DomElement.getPrefixed(window, 'requestAnimationFrame'),
requested = false,
callbacks = [],
focused = true,
timer;
DomEvent.add(window, {
focus: function() {
focused = true;
},
blur: function() {
focused = false;
}
});
function handleCallbacks() {
// Checks all installed callbacks for element visibility and
// execute if needed.
for (var i = callbacks.length - 1; i >= 0; i--) {
var entry = callbacks[i],
func = entry[0],
el = entry[1];
if (!el || (PaperScope.getAttribute(el, 'keepalive') == 'true'
|| focused) && DomElement.isInView(el)) {
// Only remove from the list once the callback was called. This
// could take a long time based on visibility. But this way we
// are sure to keep the animation loop running.
callbacks.splice(i, 1);
func();
}
}
if (nativeRequest) {
if (callbacks.length) {
// If we haven't processed all callbacks yet, we need to keep
// the loop running, as otherwise it would die off.
nativeRequest(handleCallbacks);
} else {
requested = false;
}
}
}
return function(callback, element) {
// Add to the list of callbacks to be called in the next animation
// frame.
callbacks.push([callback, element]);
if (nativeRequest) {
// Handle animation natively. We only need to request the frame
// once for all collected callbacks.
if (!requested) {
nativeRequest(handleCallbacks);
requested = true;
}
} else if (!timer) {
// Install interval timer that checks all callbacks. This
// results in faster animations than repeatedly installing
// timout timers.
timer = setInterval(handleCallbacks, 1000 / 60);
}
};
};