This app provides monitoring and information features for the common freifunk user and the technical stuff of a freifunk community.
Code base is taken from a TUM Practical Course project and added here to see if Freifunk Altdorf can use it.
https://www.freifunk-altdorf.de
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
3.7 KiB
142 lines
3.7 KiB
var Class = require('../../core/class'); |
|
var Container = require('../../dom/container'); |
|
var Element = require('../../dom/native'); |
|
|
|
var fps = 1000 / 60, invalids = [], renderTimer, renderInvalids = function(){ |
|
clearTimeout(renderTimer); |
|
renderTimer = null; |
|
var canvases = invalids; |
|
invalids = []; |
|
for (var i = 0, l = canvases.length; i < l; i++){ |
|
var c = canvases[i]; |
|
c._valid = true; |
|
c.render(); |
|
} |
|
}; |
|
|
|
var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1; |
|
|
|
var previousHit = null, previousHitSurface = null; |
|
|
|
var CanvasSurface = Class(Element, Container, { |
|
|
|
initialize: function(width, height, existingElement){ |
|
var element = this.element = existingElement || document.createElement('canvas'); |
|
var context = this.context = element.getContext('2d'); |
|
this._valid = true; |
|
if (width != null && height != null) this.resize(width, height); |
|
|
|
element.addEventListener('mousemove', this, false); |
|
element.addEventListener('mouseout', this, false); |
|
element.addEventListener('mouseover', this, false); |
|
element.addEventListener('mouseup', this, false); |
|
element.addEventListener('mousedown', this, false); |
|
element.addEventListener('click', this, false); |
|
}, |
|
|
|
handleEvent: function(event){ |
|
if (event.clientX == null) return; |
|
var element = this.element, |
|
rect = element.getBoundingClientRect(), |
|
x = event.clientX - rect.left - element.clientLeft, |
|
y = event.clientY - rect.top - element.clientTop, |
|
hit = this.hitTest(x, y); |
|
|
|
if (hit !== previousHit){ |
|
if (previousHit){ |
|
previousHit.dispatch({ |
|
type: 'mouseout', |
|
target: previousHit, |
|
relatedTarget: hit, |
|
sourceEvent: event |
|
}); |
|
} |
|
if (hit){ |
|
hit.dispatch({ |
|
type: 'mouseover', |
|
target: hit, |
|
relatedTarget: previousHit, |
|
sourceEvent: event |
|
}); |
|
} |
|
previousHit = hit; |
|
previousHitSurface = this; |
|
this.refreshCursor(); |
|
} |
|
|
|
if (hit) hit.dispatch(event); |
|
}, |
|
|
|
refreshCursor: function(){ |
|
if (previousHitSurface !== this) return; |
|
var hit = previousHit, hitCursor = '', hitTooltip = ''; |
|
while (hit){ |
|
if (!hitCursor && hit._cursor){ |
|
hitCursor = hit._cursor; |
|
if (hitTooltip) break; |
|
} |
|
if (!hitTooltip && hit._tooltip){ |
|
hitTooltip = hit._tooltip; |
|
if (hitCursor) break; |
|
} |
|
hit = hit.parentNode; |
|
} |
|
// TODO: No way to set cursor/title on the surface |
|
this.element.style.cursor = hitCursor; |
|
this.element.title = hitTooltip; |
|
}, |
|
|
|
resize: function(width, height){ |
|
var element = this.element; |
|
element.setAttribute('width', width * resolution); |
|
element.setAttribute('height', height * resolution); |
|
element.style.width = width + 'px'; |
|
element.style.height = height + 'px'; |
|
this.width = width; |
|
this.height = height; |
|
return this; |
|
}, |
|
|
|
invalidate: function(left, top, width, height){ |
|
if (this._valid){ |
|
this._valid = false; |
|
invalids.push(this); |
|
if (!renderTimer){ |
|
if (window.mozRequestAnimationFrame){ |
|
renderTimer = true; |
|
window.mozRequestAnimationFrame(renderInvalids); |
|
} else { |
|
renderTimer = setTimeout(renderInvalids, fps); |
|
} |
|
} |
|
} |
|
return this; |
|
}, |
|
|
|
hitTest: function(x, y){ |
|
if (x < 0 || y < 0 || x > this.width || y > this.height) return null; |
|
var node = this.lastChild; |
|
while (node){ |
|
var hit = node.hitTest(x, y); |
|
if (hit) return hit; |
|
node = node.previousSibling; |
|
} |
|
return null; |
|
}, |
|
|
|
render: function(){ |
|
var node = this.firstChild, context = this.context; |
|
context.setTransform(resolution, 0, 0, resolution, 0, 0); |
|
context.clearRect(0, 0, this.width, this.height); |
|
while (node){ |
|
node.renderTo(context, resolution, 0, 0, resolution, 0, 0); |
|
node = node.nextSibling; |
|
} |
|
this.refreshCursor(); |
|
} |
|
|
|
}); |
|
|
|
CanvasSurface.tagName = 'canvas'; |
|
|
|
module.exports = CanvasSurface; |