Forum:Cool optional tool ready for your use: Difference between revisions

From Tardis Wiki, the free Doctor Who reference
No edit summary
No edit summary
Line 6: Line 6:


<pre>
<pre>
/*!
/*!
  * Fokus 0.3
  * Fokus 0.3
Line 61: Line 59:
}
}


/**
* Is this browser capable of running Fokus?
*/
function capable() {
return !!(
'addEventListener' in document &&
'pointerEvents' in document.body.style
);
}
/**
* Redraws an animates the overlay.
*/
function redraw() {
// Cache the response of this for re-use below
var _hasSelection = hasSelection();
// Reset to a solid (less opacity) overlay fill
overlayContext.clearRect( 0, 0, overlay.width, overlay.height );
overlayContext.fillStyle = 'rgba( 0, 0, 0, '+ overlayAlpha +' )';
overlayContext.fillRect( 0, 0, overlay.width, overlay.height );
if( _hasSelection ) {
if( overlayAlpha < 0.1 ) {
// Clear the selection instantly
clearedRegion = selectedRegion;
}
else {
// Ease the cleared region towards the current selection
clearedRegion.left += ( selectedRegion.left - clearedRegion.left ) * 0.15;
clearedRegion.top += ( selectedRegion.top - clearedRegion.top ) * 0.15;
clearedRegion.right += ( selectedRegion.right - clearedRegion.right ) * 0.15;
clearedRegion.bottom += ( selectedRegion.bottom - clearedRegion.bottom ) * 0.15;
}
}
// Cut out the cleared region
overlayContext.clearRect(
clearedRegion.left - window.scrollX - PADDING,
clearedRegion.top - window.scrollY - PADDING,
( clearedRegion.right - clearedRegion.left ) + ( PADDING * 2 ),
( clearedRegion.bottom - clearedRegion.top ) + ( PADDING * 2 )
);
// Fade in if there's a valid selection...
if( _hasSelection ) {
overlayAlpha += ( OPACITY - overlayAlpha ) * 0.08;
}
// ... otherwise fade out
else {
overlayAlpha = Math.max( ( overlayAlpha * 0.85 ) - 0.02, 0 );
}
// Continue so long as there is content selected or we are fading out
if( _hasSelection || overlayAlpha > 0 ) {
// Append the overlay if it isn't already in the DOM
if( !overlay.parentNode ) document.body.appendChild( overlay );
// Stage a new animation frame
cancelAnimationFrame( redrawAnimation );
redrawAnimation = requestAnimationFrame( redraw );
}
else {
document.body.removeChild( overlay );
}
}
/**
* Steps through all selected nodes and updates current region
* (bounds of selection).
*/
function updateSelection() {
// Default to negative space
selectedRegion = { left: Number.MAX_VALUE, top: Number.MAX_VALUE, right: 0, bottom: 0 };
var nodes = getSelectedNodes();
for( var i = 0, len = nodes.length; i < len; i++ ) {
var node = nodes[i];
// Select parents of text nodes that have contents
if( node.nodeName === '#text' && node.nodeValue.trim() ) {
node = node.parentNode;
}
// Fetch the screen coordinates for this element
var position = getScreenPosition( node );
var x = position.x,
y = position.y,
w = node.offsetWidth,
h = node.offsetHeight;
if( node && typeof x === 'number' && typeof w === 'number' && !node.nodeName.match( /^br$/gi ) && ( w > 0 || h > 0 ) ) {
selectedRegion.left = Math.min( selectedRegion.left, x );
selectedRegion.top = Math.min( selectedRegion.top, y );
selectedRegion.right = Math.max( selectedRegion.right, x + w );
selectedRegion.bottom = Math.max( selectedRegion.bottom, y + h );
}
}
if( hasSelection() ) {
redraw();
}
}
/**
* Checks if a region is currently selected.
*/
function hasSelection() {
return selectedRegion.left < selectedRegion.right && selectedRegion.top < selectedRegion.bottom;
}
function onMouseDown( event ) {
window.addEventListener( 'mousemove', onMouseMove, false );
window.addEventListener( 'mouseup', onMouseUp, false );
updateSelection();
}
function onMouseMove( event ) {
updateSelection();
}
function onMouseUp( event ) {
window.removeEventListener( 'mousemove', onMouseMove, false );
window.removeEventListener( 'mouseup', onMouseUp, false );
setTimeout( updateSelection, 1 );
}
function onKeyUp( event ) {
updateSelection();
}
function onWindowResize( event ) {
overlay.width = window.innerWidth;
overlay.height = window.innerHeight;
}
/**
* Helper methods for getting selected nodes, source:
* http://stackoverflow.com/questions/7781963/js-get-array-of-all-selected-nodes-in-contenteditable-div
*/
function getSelectedNodes() {
if (window.getSelection) {
var sel = window.getSelection();
if (!sel.isCollapsed) {
return getRangeSelectedNodes(sel.getRangeAt(0));
}
}
return [];
}
function getRangeSelectedNodes( range ) {
var node = range.startContainer;
var endNode = range.endContainer;
// Special case for a range that is contained within a single node
if (node == endNode) {
if( node.nodeName === '#text' ) {
return [node.parentNode];
}
return [node];
}
// Iterate nodes until we hit the end container
var rangeNodes = [];
while (node && node != endNode) {
rangeNodes.push( node = nextNode(node) );
}
// Add partially selected nodes at the start of the range
node = range.startContainer;
while (node && node != range.commonAncestorContainer) {
rangeNodes.unshift(node);
node = node.parentNode;
}    
return rangeNodes;
}
function nextNode(node) {
if (node.hasChildNodes()) {
return node.firstChild;
} else {
while (node && !node.nextSibling) {
node = node.parentNode;
}
if (!node) {
return null;
}
return node.nextSibling;
}
}
/**
* Gets the x/y screen position of the target node, source:
* http://www.quirksmode.org/js/findpos.html
*/
function getScreenPosition( node ) {
var x = 0,
y = 0;
if ( node.offsetParent ) {
do {
x += node.offsetLeft;
y += node.offsetTop;
} while ( node = node.offsetParent );
}
return { x: x, y: y };
}
/**
* rAF polyfill.
*/
(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame =
  window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
  timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
initialize();
})();
</pre>
</pre>
{{user:CzechOut/Sig}}{{User:CzechOut/TimeFormat}} 12:26: Tue 13 Nov 2012</span>
{{user:CzechOut/Sig}}{{User:CzechOut/TimeFormat}} 12:26: Tue 13 Nov 2012</span>

Revision as of 12:51, 13 November 2012

IndexTech notes → Cool optional tool ready for your use
Spoilers are strongly policed here.
If this thread's title doesn't specify it's spoilery, don't bring any up.

I've included the CSS for you to be able to use a new tool called Fokus. With Fokus enabled through User:Your name/wikia.js, you'll be able to double click on a bit of text, and it will be highlighted for easier reading. I've not made it the default condition, because some people might not want the feature.

If you'd like to try it, just cut and paste the entirety of the following into User:Your name/wikia.js:

/*!
 * Fokus 0.3
 * http://lab.hakim.se/fokus
 */
(function(){

  // Padding around the selection
  var PADDING = 5;

  // Opacity of the overlay
  var OPACITY = 0.60;

	// The opaque overlay canvas
	var overlay,
		overlayContext,
		overlayAlpha = 0,

		// Reference to the redraw animation so it can be cancelled 
		redrawAnimation,

		// Currently selected region
		selectedRegion = { left: 0, top: 0, right: 0, bottom: 0 },

		// Currently cleared region
		clearedRegion = { left: 0, top: 0, right: 0, bottom: 0 };

	// choo choo!
	function initialize() {

		// Only initialize if the client is capable
		if( capable() ) {

			overlay = document.createElement( 'canvas' );
			overlayContext = overlay.getContext( '2d' );

			// Place the canvas on top of 
			overlay.style.position = 'fixed';
			overlay.style.left = 0;
			overlay.style.top = 0;
			overlay.style.zIndex = 2147483647;
			overlay.style.pointerEvents = 'none';

			window.addEventListener( 'mousedown', onMouseDown, false );
			window.addEventListener( 'keyup', onKeyUp, false );
			window.addEventListener( 'resize', onWindowResize, false );

			// Trigger an initial resize
			onWindowResize();

		}

	}


czechout<staff />    12:26: Tue 13 Nov 2012