3 changed files with 94 additions and 367 deletions
@ -1,306 +0,0 @@ |
|||||
/* |
|
||||
--- |
|
||||
description: Fill the empty space around elements, creating a spotlight effect. |
|
||||
|
|
||||
license: GPL v3.0 |
|
||||
|
|
||||
authors: |
|
||||
- Ruud Burger |
|
||||
|
|
||||
requires: |
|
||||
- core/1.3: [Class.Extras, Element.Dimensions] |
|
||||
|
|
||||
provides: [Spotlight] |
|
||||
|
|
||||
... |
|
||||
*/ |
|
||||
|
|
||||
var Spotlight = new Class({ |
|
||||
|
|
||||
Implements: [Options], |
|
||||
|
|
||||
options: { |
|
||||
'fillClass': 'spotlight_fill', |
|
||||
'fillColor': [255,255,255], |
|
||||
'fillOpacity': 1, |
|
||||
'parent': null, |
|
||||
'inject': null, |
|
||||
'soften': 10 |
|
||||
}, |
|
||||
|
|
||||
initialize: function(elements, options){ |
|
||||
var self = this; |
|
||||
self.setOptions(options); |
|
||||
|
|
||||
self.setElements(elements); |
|
||||
self.clean(); |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
clean: function(){ |
|
||||
var self = this; |
|
||||
|
|
||||
self.range = []; self.fills = []; self.edges = []; |
|
||||
|
|
||||
self.vert = []; |
|
||||
self.vert_el = []; |
|
||||
|
|
||||
self.top = []; self.left = []; |
|
||||
self.width = []; self.height = []; |
|
||||
}, |
|
||||
|
|
||||
setElements: function(elements){ |
|
||||
this.elements = elements; |
|
||||
}, |
|
||||
|
|
||||
addElement: function(element){ |
|
||||
this.elements.include(element); |
|
||||
}, |
|
||||
|
|
||||
create: function(){ |
|
||||
var self = this; |
|
||||
|
|
||||
self.destroy(); |
|
||||
|
|
||||
var page_c = $(self.options.parent || window).getScrollSize(); |
|
||||
var soften = self.options.soften; |
|
||||
|
|
||||
// Get the top and bottom of all the elements
|
|
||||
self.elements.each(function(el, nr){ |
|
||||
var c = el.getCoordinates(); |
|
||||
|
|
||||
if(c.top > 0 && nr == 0){ |
|
||||
self.vert.append([0]); |
|
||||
self.vert_el.append([null]); |
|
||||
} |
|
||||
|
|
||||
// Top
|
|
||||
self.vert.append([c.top-soften]); |
|
||||
self.vert_el.append([el]); |
|
||||
|
|
||||
// Bottom
|
|
||||
self.vert.append([c.top+c.height+soften]); |
|
||||
self.vert_el.append([el]); |
|
||||
|
|
||||
// Add it to range, for later calculation from left to right
|
|
||||
self.range.append([{ |
|
||||
'el': el, |
|
||||
'top': c.top-soften, |
|
||||
'bottom': c.top+c.height+soften, |
|
||||
'left': c.left-soften, |
|
||||
'right': c.left+c.width+soften |
|
||||
}]) |
|
||||
|
|
||||
// Create soft edge around element
|
|
||||
self.soften(el); |
|
||||
|
|
||||
}); |
|
||||
|
|
||||
if(self.elements.length == 0){ |
|
||||
self.vert.append([0]); |
|
||||
self.vert_el.append([null]); |
|
||||
} |
|
||||
|
|
||||
// Reorder
|
|
||||
var vert = self.vert.clone().sort(self.numberSort) // Use custom sort function because apparently 100 is less then 20..
|
|
||||
vert_el_new = [], vert_new = []; |
|
||||
vert.each(function(v){ |
|
||||
var old_nr = self.vert.indexOf(v); |
|
||||
vert_el_new.append([self.vert_el[old_nr]]); |
|
||||
vert_new.append([v]); |
|
||||
|
|
||||
}); |
|
||||
self.vert = vert_new; |
|
||||
self.vert_el = vert_el_new; |
|
||||
|
|
||||
// Shorten vars
|
|
||||
var vert = self.vert, |
|
||||
vert_el = self.vert_el; |
|
||||
var t, h, l, w, left, width, |
|
||||
row_el, cursor = 0; |
|
||||
|
|
||||
// Loop over all vertical lines
|
|
||||
vert.each(function(v, nr){ |
|
||||
|
|
||||
// Use defaults if el == null (for first fillblock)
|
|
||||
var c = vert_el[nr] ? vert_el[nr].getCoordinates() : { |
|
||||
'left': 0, |
|
||||
'top': 0, |
|
||||
'width': page_c.x, |
|
||||
'height': 0 |
|
||||
}; |
|
||||
|
|
||||
// Loop till cursor gets to parent_element.width
|
|
||||
var fail_safe = 0; |
|
||||
while (cursor < page_c.x && fail_safe < 10){ |
|
||||
|
|
||||
t = vert[nr]; // Top is the same for every element in a row
|
|
||||
h = (nr == vert.length-1) ? (page_c.y - t) : vert[nr+1] - vert[nr]; // So is hight
|
|
||||
|
|
||||
// First element get special treatment
|
|
||||
if(nr == 0){ |
|
||||
l = 0; |
|
||||
w = c.width+(2*soften); |
|
||||
cursor += w; |
|
||||
} |
|
||||
else { |
|
||||
|
|
||||
row_el = self.firstFromLeft(cursor, t) // First next element
|
|
||||
left = row_el.el ? row_el.left : c.left-soften; |
|
||||
width = row_el.el ? row_el.left - cursor : c.left-soften; |
|
||||
|
|
||||
if(t == c.bottom+soften && !row_el.el) |
|
||||
width = page_c.x; |
|
||||
|
|
||||
l = cursor; |
|
||||
if(cursor < left){ |
|
||||
w = width; |
|
||||
cursor += w+(row_el.right - row_el.left); |
|
||||
} |
|
||||
else { |
|
||||
w = page_c.x-l; |
|
||||
cursor += w; |
|
||||
} |
|
||||
|
|
||||
} |
|
||||
|
|
||||
// Add it to the pile!
|
|
||||
if(h > 0 && w > 0){ |
|
||||
self.top.append([t]); self.left.append([l]); |
|
||||
self.width.append([w]); self.height.append([h]); |
|
||||
} |
|
||||
|
|
||||
fail_safe++; |
|
||||
|
|
||||
} |
|
||||
|
|
||||
cursor = 0; // New line, reset cursor position
|
|
||||
fail_safe = 0; |
|
||||
|
|
||||
}); |
|
||||
|
|
||||
// Create the fill blocks
|
|
||||
self.top.each(self.createFillItem.bind(self)); |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
createFillItem: function(top, nr){ |
|
||||
var self = this; |
|
||||
|
|
||||
var fill = new Element('div', { |
|
||||
'class': self.options.fillClass, |
|
||||
'styles': { |
|
||||
'position': 'absolute', |
|
||||
'background-color': 'rgba('+self.options.fillColor.join(',')+', '+self.options.fillOpacity+')', |
|
||||
'display': 'block', |
|
||||
'z-index': 999, |
|
||||
'top': self.top[nr], |
|
||||
'left': self.left[nr], |
|
||||
'height': self.height[nr], |
|
||||
'width': self.width[nr] |
|
||||
} |
|
||||
}).inject(self.options.inject || document.body); |
|
||||
|
|
||||
self.fills.include(fill); |
|
||||
}, |
|
||||
|
|
||||
// Find the first element after x,y coordinates
|
|
||||
firstFromLeft: function(x, y){ |
|
||||
var self = this; |
|
||||
|
|
||||
var lowest_left = null; |
|
||||
var return_data = {}; |
|
||||
|
|
||||
self.range.each(function(range){ |
|
||||
var is_within_height_range = range.top <= y && range.bottom > y, |
|
||||
is_within_width_range = range.left >= x, |
|
||||
more_left_then_previous = range.left < lowest_left || lowest_left == null; |
|
||||
|
|
||||
if(is_within_height_range && is_within_width_range && more_left_then_previous){ |
|
||||
lowest_left = range.left; |
|
||||
return_data = range; |
|
||||
} |
|
||||
}) |
|
||||
|
|
||||
return return_data |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
soften: function(el){ |
|
||||
var self = this; |
|
||||
var soften = self.options.soften; |
|
||||
|
|
||||
var c = el.getCoordinates(); |
|
||||
var from_color = 'rgba('+self.options.fillColor.join(',')+', '+self.options.fillOpacity+')'; |
|
||||
var to_color = 'rgba('+self.options.fillColor.join(',')+', 0)'; |
|
||||
|
|
||||
// Top
|
|
||||
self.createEdge({ |
|
||||
'top': c.top-soften, |
|
||||
'left': c.left-soften, |
|
||||
'width': c.width+(2*soften), |
|
||||
'background': '-webkit-gradient(linear, left top, left bottom, from('+from_color+'), to('+to_color+'))', |
|
||||
'background': '-moz-linear-gradient(top, '+from_color+', '+to_color+')' |
|
||||
}) |
|
||||
|
|
||||
// Right
|
|
||||
self.createEdge({ |
|
||||
'top': c.top-soften, |
|
||||
'left': c.right, |
|
||||
'height': c.height+(2*soften), |
|
||||
'background': '-webkit-gradient(linear, left, right, from('+from_color+'), to('+to_color+'))', |
|
||||
'background': '-moz-linear-gradient(right, '+from_color+', '+to_color+')' |
|
||||
}) |
|
||||
|
|
||||
// Bottom
|
|
||||
self.createEdge({ |
|
||||
'top': c.bottom, |
|
||||
'left': c.left-soften, |
|
||||
'width': c.width+(2*soften), |
|
||||
'background': '-webkit-gradient(linear, left bottom, left top, from('+from_color+'), to('+to_color+'))', |
|
||||
'background': '-moz-linear-gradient(bottom, '+from_color+', '+to_color+')' |
|
||||
}) |
|
||||
|
|
||||
// Left
|
|
||||
self.createEdge({ |
|
||||
'top': c.top-soften, |
|
||||
'left': c.left-soften, |
|
||||
'height': c.height+(2*soften), |
|
||||
'background': '-webkit-gradient(linear, right, left, from('+from_color+'), to('+to_color+'))', |
|
||||
'background': '-moz-linear-gradient(left, '+from_color+', '+to_color+')' |
|
||||
}) |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
createEdge: function(style){ |
|
||||
var self = this; |
|
||||
|
|
||||
var soften = self.options.soften; |
|
||||
var edge = new Element('div.edge', { |
|
||||
'styles': Object.merge({ |
|
||||
'position': 'absolute', |
|
||||
'width': soften, |
|
||||
'height': soften, |
|
||||
}, style) |
|
||||
}).inject(self.options.inject || document.body) |
|
||||
|
|
||||
self.edges.include(edge); |
|
||||
|
|
||||
}, |
|
||||
|
|
||||
destroy: function(){ |
|
||||
var self = this; |
|
||||
self.fills.each(function(fill){ |
|
||||
fill.destroy(); |
|
||||
}) |
|
||||
self.edges.each(function(edge){ |
|
||||
edge.destroy(); |
|
||||
}) |
|
||||
self.clean(); |
|
||||
}, |
|
||||
|
|
||||
numberSort: function (a, b) { |
|
||||
return a - b; |
|
||||
} |
|
||||
|
|
||||
}); |
|
@ -0,0 +1,93 @@ |
|||||
|
/* |
||||
|
--- |
||||
|
description: ScrollSpy |
||||
|
|
||||
|
authors: |
||||
|
- David Walsh (http://davidwalsh.name)
|
||||
|
|
||||
|
license: |
||||
|
- MIT-style license |
||||
|
|
||||
|
requires: |
||||
|
core/1.2.1: '*' |
||||
|
|
||||
|
provides: |
||||
|
- ScrollSpy |
||||
|
... |
||||
|
*/ |
||||
|
var ScrollSpy = new Class({ |
||||
|
|
||||
|
/* implements */ |
||||
|
Implements: [Options,Events], |
||||
|
|
||||
|
/* options */ |
||||
|
options: { |
||||
|
container: window, |
||||
|
max: 0, |
||||
|
min: 0, |
||||
|
mode: 'vertical'/*, |
||||
|
onEnter: $empty, |
||||
|
onLeave: $empty, |
||||
|
onScroll: $empty, |
||||
|
onTick: $empty |
||||
|
*/ |
||||
|
}, |
||||
|
|
||||
|
/* initialization */ |
||||
|
initialize: function(options) { |
||||
|
/* set options */ |
||||
|
this.setOptions(options); |
||||
|
this.container = document.id(this.options.container); |
||||
|
this.enters = this.leaves = 0; |
||||
|
this.inside = false; |
||||
|
|
||||
|
/* listener */ |
||||
|
var self = this; |
||||
|
this.listener = function(e) { |
||||
|
/* if it has reached the level */ |
||||
|
var position = self.container.getScroll(), |
||||
|
xy = position[self.options.mode == 'vertical' ? 'y' : 'x'], |
||||
|
min = typeOf(self.options.min) == 'function' ? self.options.min() : self.options.min, |
||||
|
max = typeOf(self.options.max) == 'function' ? self.options.max() : self.options.max; |
||||
|
|
||||
|
if(xy >= min && (max == 0 || xy <= max)) { |
||||
|
/* trigger enter event if necessary */ |
||||
|
if(!self.inside) { |
||||
|
/* record as inside */ |
||||
|
self.inside = true; |
||||
|
self.enters++; |
||||
|
/* fire enter event */ |
||||
|
self.fireEvent('enter',[position,self.enters,e]); |
||||
|
} |
||||
|
/* trigger the "tick", always */ |
||||
|
self.fireEvent('tick',[position,self.inside,self.enters,self.leaves,e]); |
||||
|
} |
||||
|
/* trigger leave */ |
||||
|
else if(self.inside){ |
||||
|
self.inside = false; |
||||
|
self.leaves++; |
||||
|
self.fireEvent('leave',[position,self.leaves,e]); |
||||
|
} |
||||
|
/* fire scroll event */ |
||||
|
self.fireEvent('scroll',[position,self.inside,self.enters,self.leaves,e]); |
||||
|
}; |
||||
|
|
||||
|
/* make it happen */ |
||||
|
this.addListener(); |
||||
|
}, |
||||
|
|
||||
|
/* starts the listener */ |
||||
|
start: function() { |
||||
|
this.container.addEvent('scroll',this.listener); |
||||
|
}, |
||||
|
|
||||
|
/* stops the listener */ |
||||
|
stop: function() { |
||||
|
this.container.removeEvent('scroll',this.listener); |
||||
|
}, |
||||
|
|
||||
|
/* legacy */ |
||||
|
addListener: function() { |
||||
|
this.start(); |
||||
|
} |
||||
|
}); |
Loading…
Reference in new issue