-
-
Save zziuni/1350931 to your computer and use it in GitHub Desktop.
The minimap provides you with a new way to visualize your site.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** pQuery! LOL **/ | |
Object.extend($, Prototype); | |
Object.extend($, Object); | |
/** | |
* Returns window dimensions and scroll positions | |
* @author Firejune<[email protected]> | |
* @license MIT | |
*/ | |
Object.extend(Position, { | |
getPageSize: function() { | |
var doc = window.scrollMaxX ? | |
{w: window.innerWidth + window.scrollMaxX, h: window.innerHeight + window.scrollMaxY} : | |
{w: document.body.scrollWidth, h: document.body.scrollHeight}; | |
var win = self.innerHeight ? | |
{w: self.innerWidth, h: self.innerHeight} : // IE | |
document.documentElement && document.documentElement.clientHeight ? | |
{w: document.documentElement.clientWidth, h: document.documentElement.clientHeight} : {w: 0, h: 0}; | |
// for small pages with total size less then size of the viewport | |
doc = {w: Math.max(win.w, doc.w), h: Math.max(win.h, doc.h)}; | |
return { page: { width: doc.w, height: doc.h }, window: { width: win.w, height: win.h } }; | |
}, | |
scrollX: function() { | |
return (window.scrollX || window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0); | |
}, | |
scrollY: function() { | |
return (window.scrollY || window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0); | |
} | |
}); | |
/** | |
* Position based scrollTo effect | |
* @author Firejune<[email protected]> | |
* @license MIT | |
*/ | |
Effect.Scroll = Class.create(Effect.Base, { | |
initialize: function(top, left) { | |
var args = $A(arguments) | |
, options = typeof args.last() == "object" ? args.last() : {}; | |
this.scroll = { | |
left: left || 0 | |
, top: top | |
}; | |
this.start(options); | |
}, | |
setup: function() { | |
this.scrollX = Position.scrollX(); | |
this.scrollY = Position.scrollY(); | |
var getSize = Position.getPageSize(); | |
var max = getSize.page.height - getSize.window.height; | |
if (this.options.offset) this.scrollY += this.options.offset; | |
if (this.options.offset) this.scrollY += this.options.offset; | |
this.delta = { | |
x: (this.scroll.left > max ? max : this.scroll.left) - this.scrollX | |
, y: (this.scroll.top > max ? max : this.scroll.top) - this.scrollY | |
} | |
}, | |
update: function(position) { | |
scrollTo( | |
(this.scrollX + position * this.delta.x).round() | |
, (this.scrollY + position * this.delta.y).round()); | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* minimap 0.1 (http://firejune.com/1704) | |
* based on fracs (http://larsjung.de/fracs) | |
* | |
* provided under the terms of the MIT License | |
* | |
* requires: | |
* - prototype.js prototype 1.6.0+ (http://www.prototypejs.org) | |
* - scriptaculous 1.8.0+ (http://script.aculo.us) | |
* - extensions.js (http://firejune.com) | |
*/ | |
var Minimap = (function(doc, win) { | |
/* | |
* Options. | |
*/ | |
var $options = { | |
crop: false | |
, invert: false | |
, width: 100 | |
, height: 400 | |
, duration: 0.2 | |
, focusWidth: 0.5 | |
, focusHeight: 0.5 | |
, transition: Effect.Transitions.flicker | |
, styles: [ | |
{selector: 'header,footer,section,article', fillStyle: 'rgb(230,230,230)'} | |
, {selector: 'h1', fillStyle: 'rgb(240,140,060)'} | |
, {selector: 'h2', fillStyle: 'rgb(200,100,100)'} | |
, {selector: 'h3', fillStyle: 'rgb(100,200,100)'} | |
, {selector: 'h4', fillStyle: 'rgb(100,100,200)'} | |
] | |
, viewport: {fillStyle: 'rgba(228,77,38,0.3)'} | |
, drag: {fillStyle: 'rgba(228,77,38,0.6)'} | |
} | |
, $canvas | |
, $context | |
, $drag; | |
/* | |
* Class. | |
*/ | |
return function(options) { | |
$options = $.extend($options, options); | |
$canvas = new Element('canvas', { | |
id: 'outline' | |
, width: $options.width | |
, height: $options.height | |
}); | |
if (!($canvas instanceof HTMLElement) | |
|| $canvas.nodeName.toLowerCase() !== 'canvas') | |
return console.error('Your browser does not support Canvas'); | |
doc.body.insert($canvas); | |
this.draw = draw; | |
this.scroll = scroll; | |
$context = $canvas.getContext('2d'); | |
$canvas.setStyle('cursor: pointer').observe('mousedown', function(event) { | |
event.stop(); | |
$drag = true; | |
$canvas.setStyle('cursor: crosshair'); | |
doc.body.setStyle('cursor: crosshair'); | |
Event.observe(win, 'mousemove', scroll); | |
}); | |
Event.observe(win, 'mouseup', function(event) { | |
event.stop(); | |
$canvas.setStyle('cursor: pointer'); | |
doc.body.setStyle('cursor: auto'); | |
Event.stopObserving(win, 'mousemove', scroll); | |
$drag = false; | |
draw(); | |
event.element() == $canvas && scroll(event); | |
}); | |
$canvas.onselectstart = function() { | |
return false; | |
}; | |
Event.observe(win, 'load', draw); | |
Event.observe(win, 'resize', draw); | |
Event.observe(win, 'scroll', draw); | |
draw(); | |
console.info('Initialized minimap.'); | |
}; | |
/* | |
* Core. | |
*/ | |
function scroll(event) { | |
var r = rect($canvas) | |
, x = event.clientX - r.left | |
, y = event.clientY - r.top; | |
scrollTo( | |
x / draw.scale - draw.win.width * $options.focusWidth | |
, y / draw.scale - draw.win.height * $options.focusHeight | |
, event.type == 'mousemove' ? 0 : $options.duration); | |
} | |
function scrollTo(left, top, duration) { | |
scroll.ani && scroll.ani.state == 'running' && scroll.ani.cancel(); | |
scroll.ani = new Effect.Scroll(top, left, { | |
fps: 100 | |
, duration: duration | |
, transition: $options.transition | |
}); | |
} | |
function draw() { | |
var vp = viewport() | |
, scaleX = $options.width / vp.doc.width | |
, scaleY = $options.height / vp.doc.height; | |
if ($options.crop) { | |
$canvas.width = vp.doc.width * draw.scale; | |
$canvas.height = vp.doc.height * draw.scale; | |
} | |
$context.clearRect(0, 0, $canvas.width, $canvas.height); | |
$context.scale(draw.scale, draw.scale); | |
$.extend(draw, { | |
scale: scaleX < scaleY ? scaleX : scaleY | |
, doc: vp.doc | |
, win: vp.win | |
}); | |
applyStyles($context); | |
drawViewport(); | |
$context.scale(1 / draw.scale, 1 / draw.scale); | |
} | |
function applyStyles(context) { | |
for (idx in $options.styles) { | |
var style = $.extend({ | |
strokeWidth: 'auto' | |
, strokeStyle: 'auto' | |
, fillStyle: 'auto' | |
}, $options.styles[idx]); | |
$$(style.selector).each(function(el) { | |
el.visible() && drawElement( | |
context | |
, el | |
, style.strokeWidth | |
, style.strokeStyle | |
, style.fillStyle); | |
}); | |
} | |
} | |
function drawElement(context, element, strokeWidth, strokeStyle, fillStyle) { | |
var position = rect(element); | |
strokeWidth = strokeWidth == 'auto' ? | |
parseInt(element.getStyle('border-width')) || '' : strokeWidth; | |
strokeStyle = strokeStyle == 'auto' ? | |
element.getStyle('border-color') : strokeStyle; | |
fillStyle = fillStyle == 'auto' ? | |
element.getStyle('background-color') : fillStyle; | |
drawRect(context, position, strokeWidth, strokeStyle, fillStyle); | |
} | |
function drawViewport() { | |
if ($drag === true && $options.drag !== undefined) { | |
var storkeWidth = $options.drag.storkeWidth; | |
var strokeStyle = $options.drag.strokeStyle; | |
var fillStyle = $options.drag.fillStyle; | |
} else { | |
var storkeWidth = $options.viewport.storkeWidth; | |
var strokeStyle = $options.viewport.strokeStyle; | |
var fillStyle = $options.viewport.fillStyle; | |
} | |
drawRect( | |
$context | |
, draw.win | |
, storkeWidth | |
, strokeStyle | |
, fillStyle | |
, $options.invert); | |
} | |
function drawRect(context, rect, lineWidth, strokeStyle, fillStyle, invert) { | |
invert = invert || false; | |
lineWidth = lineWidth > 0.2 / draw.scale ? lineWidth : 0.2 / draw.scale; | |
if (invert === false) { | |
context.beginPath(); | |
context.rect(rect.left, rect.top, rect.width, rect.height); | |
context.fillStyle = fillStyle; | |
context.fill(); | |
context.lineWidth = lineWidth; | |
context.strokeStyle = strokeStyle; | |
context.stroke(); | |
} else { | |
context.beginPath(); | |
context.rect(0, 0, draw.doc.width, rect.top); | |
context.rect(0, rect.top, rect.left, rect.height); | |
context.rect(rect.right, rect.top, draw.doc.right - rect.right, rect.height); | |
context.rect(0, rect.bottom, draw.doc.width, draw.doc.bottom - rect.bottom); | |
context.fillStyle = fillStyle; | |
context.fill(); | |
context.beginPath(); | |
context.rect(rect.left, rect.top, rect.width, rect.height); | |
context.lineWidth = lineWidth; | |
context.strokeStyle = strokeStyle; | |
context.stroke(); | |
} | |
} | |
function viewport() { | |
var size = Position.getPageSize() | |
, left = Position.scrollX() | |
, top = Position.scrollY(); | |
return { | |
win: new Rect(left, top, size.window.width, size.window.height) | |
, doc: new Rect(0, 0, size.page.width, size.page.height) | |
}; | |
} | |
function rect(element) { | |
var dimensions = element.getDimensions() | |
, offset = element.cumulativeOffset(); | |
return new Rect(offset.left, offset.top, dimensions.width, dimensions.height); | |
} | |
function Rect(left, top, width, height) { | |
this.left = left.round(); | |
this.top = top.round(); | |
this.width = width.round(); | |
this.height = height.round(); | |
this.right = this.left + this.width; | |
this.bottom = this.top + this.height; | |
} | |
})(document, window); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment