I have a site I am working on that uses the roundabout from fredhq.com and I would like to make it so it auto plays, I have had a look on their website and can not work out where I need to add the relevant auto play code!
Here is the jquery.roundabout.js code:
// creates a default shape to be used for pathing
jQuery.extend({
roundabout_shape: {
def: 'lazySusan',
lazySusan: function(r, a, t) {
return {
x: Math.sin(r + a),
y: (Math.sin(r + 3*Math.PI/2 + a) / 8) * t,
z: (Math.cos(r + a) + 1) / 2,
scale: (Math.sin(r + Math.PI/2 + a) / 2) + 0.5
};
}
}
});
jQuery.fn.roundabout = function() {
var options = (typeof arguments[0] != 'object') ? {} : arguments[0];
// set options and fill in defaults
options = {
bearing: (typeof options.bearing == 'undefined') ? 0.0 : jQuery.roundabout_toFloat(options.bearing % 360.0),
tilt: (typeof options.tilt == 'undefined') ? 0.0 : jQuery.roundabout_toFloat(options.tilt),
minZ: (typeof options.minZ == 'undefined') ? 100 : parseInt(options.minZ, 10),
maxZ: (typeof options.maxZ == 'undefined') ? 400 : parseInt(options.maxZ, 10),
minOpacity: (typeof options.minOpacity == 'undefined') ? 0.40 : jQuery.roundabout_toFloat(options.minOpacity),
maxOpacity: (typeof options.maxOpacity == 'undefined') ? 1.00 : jQuery.roundabout_toFloat(options.maxOpacity),
minScale: (typeof options.minScale == 'undefined') ? 0.40 : jQuery.roundabout_toFloat(options.minScale),
maxScale: (typeof options.maxScale == 'undefined') ? 1.00 : jQuery.roundabout_toFloat(options.maxScale),
duration: (typeof options.duration == 'undefined') ? 600 : parseInt(options.duration, 10),
btnNext: options.btnNext || null,
btnPrev: options.btnPrev || null,
easing: options.easing || 'swing',
clickToFocus: (options.clickToFocus !== false),
focusBearing: (typeof options.focusBearing == 'undefined') ? 0.0 : jQuery.roundabout_toFloat(options.focusBearing % 360.0),
shape: options.shape || 'lazySusan',
debug: options.debug || false,
childSelector: options.childSelector || 'li',
startingChild: (typeof options.startingChild == 'undefined') ? null : parseInt(options.startingChild, 10),
reflect: (typeof options.reflect == 'undefined' || options.reflect === false) ? false : true
};
// assign things
this.each(function(i) {
var ref = jQuery(this);
var period = jQuery.roundabout_toFloat(360.0 / ref.children(options.childSelector).length);
var startingBearing = (options.startingChild === null) ? options.bearing : options.startingChild * period;
// set starting styles
ref
.addClass('roundabout-holder')
.css('padding', 0)
.css('position', 'relative')
.css('z-index', options.minZ);
// set starting options
ref.data('roundabout', {
'bearing': startingBearing,
'tilt': options.tilt,
'minZ': options.minZ,
'maxZ': options.maxZ,
'minOpacity': options.minOpacity,
'maxOpacity': options.maxOpacity,
'minScale': options.minScale,
'maxScale': options.maxScale,
'duration': options.duration,
'easing': options.easing,
'clickToFocus': options.clickToFocus,
'focusBearing': options.focusBearing,
'animating': 0,
'childInFocus': -1,
'shape': options.shape,
'period': period,
'debug': options.debug,
'childSelector': options.childSelector,
'reflect': options.reflect
});
// bind click events
if (options.clickToFocus === true) {
ref.children(options.childSelector).each(function(i) {
jQuery(this).click(function(e) {
var degrees = (options.reflect === true) ? 360.0 - (period * i) : period * i;
degrees = jQuery.roundabout_toFloat(degrees);
if (!jQuery.roundabout_isInFocus(ref, degrees)) {
e.preventDefault();
if (ref.data('roundabout').animating === 0) {
ref.roundabout_animateAngleToFocus(degrees);
}
return false;
}
});
});
}
// bind next buttons
if (options.btnNext) {
jQuery(options.btnNext).bind('click.roundabout', function(e) {
e.preventDefault();
if (ref.data('roundabout').animating === 0) {
ref.roundabout_animateToNextChild();
}
return false;
});
}
// bind previous buttons
if (options.btnPrev) {
jQuery(options.btnPrev).bind('click.roundabout', function(e) {
e.preventDefault();
if (ref.data('roundabout').animating === 0) {
ref.roundabout_animateToPreviousChild();
}
return false;
});
}
});
// start children
this.roundabout_startChildren();
// callback once ready
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_startChildren = function() {
this.each(function(i) {
var ref = jQuery(this);
var data = ref.data('roundabout');
var children = ref.children(data.childSelector);
children.each(function(i) {
var degrees = (data.reflect === true) ? 360.0 - (data.period * i) : data.period * i;
// apply classes and css first
jQuery(this)
.addClass('roundabout-moveable-item')
.css('position', 'absolute');
// then measure
jQuery(this).data('roundabout', {
'startWidth': jQuery(this).width(),
'startHeight': jQuery(this).height(),
'startFontSize': parseInt(jQuery(this).css('font-size'), 10),
'degrees': degrees
});
});
ref.roundabout_updateChildPositions();
});
return this;
};
jQuery.fn.roundabout_setTilt = function(newTilt) {
this.each(function(i) {
jQuery(this).data('roundabout').tilt = newTilt;
jQuery(this).roundabout_updateChildPositions();
});
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_setBearing = function(newBearing) {
this.each(function(i) {
jQuery(this).data('roundabout').bearing = jQuery.roundabout_toFloat(newBearing % 360, 2);
jQuery(this).roundabout_updateChildPositions();
});
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_adjustBearing = function(delta) {
delta = jQuery.roundabout_toFloat(delta);
if (delta !== 0) {
this.each(function(i) {
jQuery(this).data('roundabout').bearing = jQuery.roundabout_getBearing(jQuery(this)) + delta;
jQuery(this).roundabout_updateChildPositions();
});
}
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_adjustTilt = function(delta) {
delta = jQuery.roundabout_toFloat(delta);
if (delta !== 0) {
this.each(function(i) {
jQuery(this).data('roundabout').tilt = jQuery.roundabout_toFloat(jQuery(this).roundabout_get('tilt') + delta);
jQuery(this).roundabout_updateChildPositions();
});
}
if (typeof arguments[1] === 'function') {
var callback = arguments[1], ref = this;
setTimeout(function() { callback(ref); }, 0);
}
return this;
};
jQuery.fn.roundabout_animateToBearing = function(bearing) {
bearing = jQuery.roundabout_toFloat(bearing);
var currentTime = new Date();
var duration = (typeof arguments[1] == 'undefined') ? null : arguments[1];
var easingType = (typeof arguments[2] == 'undefined') ? null : arguments[2];
var passedData = (typeof arguments[3] !== 'object') ? null : arguments[3];
this.each(function(i) {
var ref = jQuery(this), data = ref.data('roundabout'), timer, easingFn, newBearing;
var thisDuration = (duration === null) ? data.duration : duration;
var thisEasingType = (easingType !== null) ? easingType : data.easing || 'swing';
if (passedData === null) {
passedData = {
timerStart: currentTime,
start: jQuery.roundabout_getBearing(ref),
totalTime: thisDuration
};
}
timer = currentTime - passedData.timerStart;
if (timer < thisDuration) {
data.animating = 1;
if (typeof jQuery.easing.def == 'string') {
easingFn = jQuery.easing[thisEasingType] || jQuery.easing[jQuery.easing.def];
newBearing = easingFn(null, timer, passedData.start, bearing - passedData.start, passedData.totalTime);
} else {
newBearing = jQuery.easing[thisEasingType]((timer / passedData.totalTime), timer, passedData.start, bearing - passedData.start, passedData.totalTime);
}
ref.roundabout_setBearing(newBearing, function() { ref.roundabout_animateToBearing(bearing, thisDuration, thisEasingType, passedData); });
} else {
bearing = (bearing < 0) ? bearing + 360 : bearing % 360;
data.animating = 0;
ref.roundabout_setBearing(bearing);
}
});
return this;
};
jQuery.fn.roundabout_animateToDelta = function(delta) {
var duration = arguments[1], easing = arguments[2];
this.each(function(i) {
delta = jQuery.roundabout_getBearing(jQuery(this)) + jQuery.roundabout_toFloat(delta);
jQuery(this).roundabout_animateToBearing(delta, duration, easing);
});
return this;
};
jQuery.fn.roundabout_animateToChild = function(childPos) {
var duration = arguments[1], easing = arguments[2];
this.each(function(i) {
var ref = jQuery(this), data = ref.data('roundabout');
if (data.childInFocus !== childPos && data.animating === 0) {
var child = jQuery(ref.children(data.childSelector)[childPos]);
ref.roundabout_animateAngleToFocus(child.data('roundabout').degrees, duration, easing);
}
});
return this;
};
jQuery.fn.roundabout_animateToNearbyChild = function(passedArgs, which) {
var duration = passedArgs[0], easing = passedArgs[1];
this.each(function(i) {
var data = jQuery(this).data('roundabout');
var bearing = jQuery.roundabout_toFloat(360.0 - jQuery.roundabout_getBearing(jQuery(this)));
var period = data.period, j = 0, range;
var reflect = data.reflect;
var length = jQuery(this).children(data.childSelector).length;
bearing = (reflect === true) ? bearing % 360.0 : bearing;
if (data.animating === 0) {
// if we're not reflecting and we're moving to next or
// we are reflecting and we're moving previous
if ((reflect === false && which === 'next') || (reflect === true && which !== 'next')) {
bearing = (bearing === 0) ? 360 : bearing;
// counterclockwise
while (true && j < length) {
range = { lower: jQuery.roundabout_toFloat(period * j), upper: jQuery.roundabout_toFloat(period * (j + 1)) };
range.upper = (j == length - 1) ? 360.0 : range.upper; // adjust for javascript being bad at floats
if (bearing <= range.upper && bearing > range.lower) {
jQuery(this).roundabout_animateToDelta(bearing - range.lower, duration, easing);
break;
}
j++;
}
} else {
// clockwise
while (true) {
range = { lower: jQuery.roundabout_toFloat(period * j), upper: jQuery.roundabout_toFloat(period * (j + 1)) };
range.upper = (j == length - 1) ? 360.0 : range.upper; // adjust for javascript being bad at floats
if (bearing >= range.lower && bearing < range.upper) {
jQuery(this).roundabout_animateToDelta(bearing - range.upper, duration, easing);
break;
}
j++;
}
}
}
});
return this;
};
jQuery.fn.roundabout_animateToNextChild = function() {
return this.roundabout_animateToNearbyChild(arguments, 'next');
};
jQuery.fn.roundabout_animateToPreviousChild = function() {
return this.roundabout_animateToNearbyChild(arguments, 'previous');
};
// moves a given angle to the focus by the shortest means possible
jQuery.fn.roundabout_animateAngleToFocus = function(target) {
var duration = arguments[1], easing = arguments[2];
this.each(function(i) {
var delta = jQuery.roundabout_getBearing(jQuery(this)) - target;
delta = (Math.abs(360.0 - delta) < Math.abs(0.0 - delta)) ? 360.0 - delta : 0.0 - delta;
delta = (delta > 180) ? -(360.0 - delta) : delta;
if (delta !== 0) {
jQuery(this).roundabout_animateToDelta(delta, duration, easing);
}
});
return this;
};
jQuery.fn.roundabout_updateChildPositions = function() {
this.each(function(i) {
var ref = jQuery(this), data = ref.data('roundabout');
var inFocus = -1;
var info = {
bearing: jQuery.roundabout_getBearing(ref),
tilt: data.tilt,
stage: { width: Math.floor(ref.width() * 0.9), height: Math.floor(ref.height() * 0.9) },
animating: data.animating,
inFocus: data.childInFocus,
focusBearingRad: jQuery.roundabout_degToRad(data.focusBearing),
shape: jQuery.roundabout_shape[data.shape] || jQuery.roundabout_shape[jQuery.roundabout_shape.def]
};
info.midStage = { width: info.stage.width / 2, height: info.stage.height / 2 };
info.nudge = { width: info.midStage.width + info.stage.width * 0.05, height: info.midStage.height + info.stage.height * 0.05 };
info.zValues = { min: data.minZ, max: data.maxZ, diff: data.maxZ - data.minZ };
info.opacity = { min: data.minOpacity, max: data.maxOpacity, diff: data.maxOpacity - data.minOpacity };
info.scale = { min: data.minScale, max: data.maxScale, diff: data.maxScale - data.minScale };
// update child positions
ref.children(data.childSelector).each(function(i) {
if (jQuery.roundabout_updateChildPosition(jQuery(this), ref, info, i) && info.animating === 0) {
inFocus = i;
jQuery(this).addClass('roundabout-in-focus');
} else {
jQuery(this).removeClass('roundabout-in-focus');
}
});
// update status of who is in focus
if (inFocus !== info.inFocus) {
jQuery.roundabout_triggerEvent(ref, info.inFocus, 'blur');
if (inFocus !== -1) {
jQuery.roundabout_triggerEvent(ref, inFocus, 'focus');
}
data.childInFocus = inFocus;
}
});
return this;
};
//----------------
jQuery.roundabout_getBearing = function(el) {
return jQuery.roundabout_toFloat(el.data('roundabout').bearing) % 360;
};
jQuery.roundabout_degToRad = function(degrees) {
return (degrees % 360.0) * Math.PI / 180.0;
};
jQuery.roundabout_isInFocus = function(el, target) {
return (jQuery.roundabout_getBearing(el) % 360 === (target % 360));
};
jQuery.roundabout_triggerEvent = function(el, child, eventType) {
return (child < 0) ? this : jQuery(el.children(el.data('roundabout').childSelector)[child]).trigger(eventType);
};
jQuery.roundabout_toFloat = function(number) {
number = Math.round(parseFloat(number) * 1000) / 1000;
return parseFloat(number.toFixed(2));
};
jQuery.roundabout_updateChildPosition = function(child, container, info, childPos) {
var ref = jQuery(child), data = ref.data('roundabout'), out = [];
var rad = jQuery.roundabout_degToRad((360.0 - ref.data('roundabout').degrees) + info.bearing);
// adjust radians to be between 0 and Math.PI * 2
while (rad < 0) {
rad = rad + Math.PI * 2;
}
while (rad > Math.PI * 2) {
rad = rad - Math.PI * 2;
}
var factors = info.shape(rad, info.focusBearingRad, info.tilt); // obj with x, y, z, and scale values
// correct
factors.scale = (factors.scale > 1) ? 1 : factors.scale;
factors.adjustedScale = (info.scale.min + (info.scale.diff * factors.scale)).toFixed(4);
factors.width = (factors.adjustedScale * data.startWidth).toFixed(4);
factors.height = (factors.adjustedScale * data.startHeight).toFixed(4);
// alter item
ref
.css('left', ((factors.x * info.midStage.width + info.nudge.width) - factors.width / 2.0).toFixed(1) + 'px')
.css('top', ((factors.y * info.midStage.height + info.nudge.height) - factors.height / 2.0).toFixed(1) + 'px')
.css('width', factors.width + 'px')
.css('height', factors.height + 'px')
.css('opacity', (info.opacity.min + (info.opacity.diff * factors.scale)).toFixed(2))
.css('z-index', Math.round(info.zValues.min + (info.zValues.diff * factors.z)))
.css('font-size', (factors.adjustedScale * data.startFontSize).toFixed(2) + 'px')
.attr('current-scale', factors.adjustedScale);
if (container.data('roundabout').debug === true) {
out.push('<div style="font-weight: normal; font-size: 10px; padding: 2px; width: ' + ref.css('width') + '; background-color: #ffc;">');
out.push('<strong style="font-size: 12px; white-space: nowrap;">Child ' + childPos + '</strong><br />');
out.push('<strong>left:</strong> ' + ref.css('left') + '<br /><strong>top:</strong> ' + ref.css('top') + '<br />');
out.push('<strong>width:</strong> ' + ref.css('width') + '<br /><strong>opacity:</strong> ' + ref.css('opacity') + '<br />');
out.push('<strong>z-index:</strong> ' + ref.css('z-index') + '<br /><strong>font-size:</strong> ' + ref.css('font-size') + '<br />');
out.push('<strong>scale:</strong> ' + ref.attr('current-scale'));
out.push('</div>');
ref.html(out.join(''));
}
return jQuery.roundabout_isInFocus(container, ref.data('roundabout').degrees);
};
Many thanks in advance for any help and advice.
Phil
The source you posted doesn't seem to be the latest version of Roundabout.
I just tried with the latest version, and it works perfectly:
$(document).ready(function() {
$('ul').roundabout({
autoplay: true,
autoplayDuration: 1000,
autoplayPauseOnHover: true
});
});
See http://jsfiddle.net/SfAuF/ for an example.
Download the latest version from GitHub.
Related
I have an input field which has a data manipulation and is a decimal field. Everything works fine except when I put in more than 3 numbers it will lose the current caret and set it to the end of the field because of the field formatting.
Example:
123 works fine
1234 will result in 1’234.00 and the caret is after the last 0. How is it possible to set the caret back to its original position? (Between 4 and the .)
function thousenderSign(number) {
number = '' + number;
if (number.length > 3) {
var mod = number.length % 3;
var output = (mod > 0 ? (number.substring(0, mod)) : '');
for (i = 0; i < Math.floor(number.length / 3); i++) {
if ((mod == 0) && (i == 0)) {
output += number.substring(mod + 3 * i, mod + 3 * i + 3);
} else {
output += "'" + number.substring(mod + 3 * i, mod + 3 * i + 3); // set the sign
}
}
return (output);
} else return number;
}
ko.extenders.numeric = function(target, precision) {
var result = ko.pureComputed({
read: target,
write: function(newValue) {
var current = target();
var roundingMultiplier = Math.pow(10, precision);
var newValueAsNum = null;
if (newValue !== undefined && newValue !== 0 && newValue !== null) {
newValueAsNum = newValue.toString().replace("'", "");
// provide only int fort he function
var onlyInt = newValueAsNum.split(".");
// Remove more then 2 digits after the dot
if (onlyInt.length > 1 && onlyInt[1].length > 2) {
onlyInt[1] = onlyInt[1].toString().substring(0, 2);
}
}
var valueToWrite = (Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier) === 0 ? null : Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
// thousender sign
if (newValueAsNum !== null && newValueAsNum.length > 3) {
valueToWrite = thousenderSign(onlyInt[0]) + "." + (onlyInt.length > 1 ? onlyInt[1] : '00');
}
if (valueToWrite !== current) {
target(valueToWrite);
} else {
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
result(target());
return result;
};
function ExampleViewModel() {
self = this;
self.counterofferPremium = ko.observable().extend({
numeric: 2
});
};
var viewModel = new ExampleViewModel();
ko.applyBindings(viewModel);
<!doctype html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
</head>
<body>
<input data-bind="value: counterofferPremium, valueUpdate: 'afterkeydown'" type="text" />
</body>
</html>
The simplest thing to do is get rid of the valueUpdate setting so that the formatting happens after the user is done editing the number.
To have it work interactively, you need to add an input event handler that
Finds how many digits are behind the cursor (this happens before reformatting)
Does a setTimeout to allow the reformatting to happen
Sets the cursor position after the same number of digits
Also note that your formatter gets weird for very long numbers. You might want to replace it with a call to toLocaleString with some additional substitutions.
function thousenderSign(number) {
number = '' + number;
if (number.length > 3) {
var mod = number.length % 3;
var output = (mod > 0 ? (number.substring(0, mod)) : '');
for (i = 0; i < Math.floor(number.length / 3); i++) {
if ((mod == 0) && (i == 0)) {
output += number.substring(mod + 3 * i, mod + 3 * i + 3);
} else {
output += "'" + number.substring(mod + 3 * i, mod + 3 * i + 3); // set the sign
}
}
return (output);
} else return number;
}
ko.extenders.numeric = function(target, precision) {
var result = ko.pureComputed({
read: target,
write: function(newValue) {
var current = target();
var roundingMultiplier = Math.pow(10, precision);
var newValueAsNum = null;
if (newValue !== undefined && newValue !== 0 && newValue !== null) {
newValueAsNum = newValue.toString().replace("'", "");
// provide only int fort he function
var onlyInt = newValueAsNum.split(".");
// Remove more then 2 digits after the dot
if (onlyInt.length > 1 && onlyInt[1].length > 2) {
onlyInt[1] = onlyInt[1].toString().substring(0, 2);
}
}
var valueToWrite = (Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier) === 0 ? null : Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
// thousender sign
if (newValueAsNum !== null && newValueAsNum.length > 3) {
valueToWrite = thousenderSign(onlyInt[0]) + "." + (onlyInt.length > 1 ? onlyInt[1] : '00');
}
if (valueToWrite !== current) {
target(valueToWrite);
} else {
if (newValue !== current) {
target.notifySubscribers(valueToWrite);
}
}
}
}).extend({
notify: 'always'
});
result(target());
return result;
};
function ExampleViewModel() {
self = this;
self.counterofferPremium = ko.observable().extend({
numeric: 2
});
self.findPlace = function (data, event) {
const pos = event.target.selectionEnd;
var numbersBeforePos = event.target.value.substr(0, pos).replace(/\D/g, '').length;
setTimeout(function() {
const formattedValue = event.target.value;
const numbersNow = event.target.value.replace(/\D/g, '').length;
if (numbersNow >= numbersBeforePos) {
// find the numbersBeforePos-th number
const re = /\d/g;
var newPos;
while (numbersBeforePos--) {
newPos = 1 + re.exec(formattedValue).index;
}
event.target.setSelectionRange(newPos, newPos);
}
}, 0);
};
};
var viewModel = new ExampleViewModel();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<input data-bind="value: counterofferPremium, valueUpdate: 'afterkeydown', event: {input: findPlace}" type="text" />
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am making a star wars game with HTML, CSS and JS. It should look a little bit like this game: https://www.gog.com/game/star_wars_xwing_vs_tie_fighter
Now I want to make it like a kind of game in which you have to shoot at enemy ships. for these ships I want to use this image: http://vignette4.wikia.nocookie.net/starwars/images/0/0a/TIE_Advanced_x1_starfighter.png/revision/latest?cb=20150310124250
Now her this is my questions:
How can I make it look like the ship in this image is getting closer to you? So that it appears in the distance really small and gets closer to you and becomes bigger, so that it looks like it is flying towards you?
I tried to use z-index but that did not work.
Also pls don't mind the code for I have been working on it for a long time and it finally works the way I want it to, but if it is a hinder in any further progress feel free to tell me what I need to add/change/remove or whatsoever.
Also I have been looking around on the internet how I could possibly make something like a star wars game but for example on this site the obly thing I could find related to star wars was how to make the crawling introduction but that is not what I am looking for:)
Number.prototype.clamp = function(min, max) {
'use strict';
return Math.max(min, Math.min(this, max));
};
var url = document.location.href;
var n = parseInt((url.indexOf('n=') != -1) ? url.substring(url.indexOf('n=') + 2, ((url.substring(url.indexOf('n=') + 2, url.length)).indexOf('&') != -1) ? url.indexOf('n=') + 2 + (url.substring(url.indexOf('n=') + 2, url.length)).indexOf('&') : url.length) : 512 * 4);
var star = new Array(n);
var hyperspace = 0;
var lol = {}
lol.id = 'starfield';
lol.pr = {
w: 1,
h: 1
};
lol.zr = 256;
lol.timer = 0;
lol.spd = 1;
lol.rid = false;
lol.cvs = false;
lol.ctx = false;
lol.util = {
isboolean: function(v) {
if (typeof v === 'boolean') {
return true;
}
return false;
},
isstring: function(v) {
if (typeof v === 'string') {
return true;
}
return false;
},
isobject: function(v) {
if (typeof v === 'object') {
return true;
}
return false;
},
isfunction: function(v) {
if (typeof v === 'function') {
return true;
}
return false;
},
isempty: function(obj) {
if (window.Object.getOwnPropertyNames(obj).length === 0) {
return true;
}
return false;
},
isffx: function() {
return (/firefox/i).test(window.navigator.userAgent);
},
copy: function(v) {
return v.slice(0);
},
clone: function(v) {
return Object.create({
x: v.x,
y: v.y,
z: v.z
});
},
sign: function(v) {
v = parseFloat(Number(v).toFixed(1));
if (v === 0) {
return ' ';
}
if (v < 0) {
return '';
}
if (v > 0) {
return '+';
}
},
random: function(n) {
var i = 0,
type, start, len, rnd = '';
while (i < n) {
type = Math.round(Math.random() * 2);
if (type === 0) {
start = 48;
len = 10;
} else {
start = (Math.round(Math.random() * 2) % 2 === 0) ? 65 : 97;
len = 26;
}
rnd += String.fromCharCode(start + Math.floor(Math.random() * len));
i += 1;
}
return rnd;
},
interpolate: function(from, to, n, i) {
return from + (to - from) / n * i;
},
time: function() {
return (new Date()).getTime();
}
};
lol.i = function(id) {
return window.document.getElementById(String(id));
};
lol.el = function(el) {
return window.document.createElement(String(el));
};
lol.tn = function(txt) {
return window.document.createTextNode(String(txt));
};
function $r(parent, child) {
(document.getElementById(parent)).removeChild(document.getElementById(child));
}
function $t(name) {
return document.getElementsByTagName(name);
}
function $c(code) {
return String.fromCharCode(code);
}
function $h(value) {
return ('0' + Math.max(0, Math.min(255, Math.round(value))).toString(16)).slice(-2);
}
function _i(id, value) {
$t('div')[id].innerHTML += value;
}
function _h(value) {
return !hires ? value : Math.round(value / 2);
}
function get_screen_size() {
var w = document.documentElement.clientWidth;
var h = document.documentElement.clientHeight;
return Array(w, h);
};
lol.init = function() {
window.addEventListener('resize', lol.resize, false);
window.addEventListener('mousemove', lol.mouse.move, false);
var e = lol.util.isffx() ? 'DOMMouseScroll' : 'mousewheel';
window.addEventListener(e, lol.mouse.wheel, false);
window.addEventListener('keypress', lol.key, false);
lol.viewport();
lol.resize();
for (var i = 0; i < n; i++) {
star[i] = new Array(5);
star[i][0] = Math.random() * lol.w * 3 - lol.x * 3;
star[i][1] = Math.random() * lol.h * 3 - lol.y * 3;
star[i][2] = Math.round(Math.random() * lol.z);
star[i][3] = lol.x;
star[i][4] = lol.y;
}
lol.anim.start();
};
lol.viewport = function() {
var el = lol.el('div');
el.id = lol.id;
el.style.position = 'absolute';
window.document.body.appendChild(el);
lol.cvs = lol.el('canvas');
lol.cvs.id = lol.id + '-viewport';
lol.cvs.style.position = 'absolute';
el.appendChild(lol.cvs);
lol.ctx = lol.cvs.getContext('2d');
};
lol.resize = function() {
var w = window.innerWidth,
h = window.innerHeight,
el = lol.i(lol.id);
lol.w = (w + lol.pr.w - w % lol.pr.w) / lol.pr.w;
lol.w += lol.w % 2;
lol.h = (h + lol.pr.h - h % lol.pr.h) / lol.pr.h;
lol.h += lol.h % 2;
lol.x = Math.round(w / 2);
lol.y = Math.round(h / 2);
lol.z = (w + h) / 2;
lol.r = 1 / lol.z;
el.width = lol.w * lol.pr.w;
el.height = lol.h * lol.pr.h;
lol.cvs.width = lol.w * lol.pr.w;
lol.cvs.height = lol.h * lol.pr.h;
lol.cvs.style.backgroundColor = '#000';
lol.ctx.scale(lol.pr.w, lol.pr.h);
lol.mouse.o = {
x: lol.x,
y: lol.y
};
};
lol.anim = {
update: function() {
var c;
lol.ctx.fillStyle = 'rgba(0,0,0,0.5)';
if (hyperspace === 1) {
lol.spd = lol.spd * 1.015;
lol.zr = lol.zr * 0.99;
c = Math.round(lol.spd * 4);
lol.ctx.fillStyle = 'rgba(' + c + ',' + c + ',' + c + ',0.5)';
if (lol.spd > 64) {
lol.ctx.fillStyle = 'rgba(0,0,0,0.5)';
lol.spd = 16;
lol.zr = 256;
hyperspace = 2;
}
}
if (hyperspace === 2) {
if (lol.spd > 1) {
lol.spd *= 0.99;
} else {
lol.spd = 1;
hyperspace = 0;
}
}
lol.ctx.fillRect(0, 0, lol.w, lol.h);
for (var i = 0; i < n; i++) {
var test = true,
x2 = star[i][3],
y2 = star[i][4];
star[i][0] += lol.mouse.p.x * 0.1;
if (star[i][0] > lol.x * 3) {
star[i][0] -= lol.w * 3;
test = false;
}
if (star[i][0] < -lol.x * 3) {
star[i][0] += lol.w * 3;
test = false;
}
star[i][1] += lol.mouse.p.y * 0.1;
if (star[i][1] > lol.y * 3) {
star[i][1] -= lol.h * 3;
test = false;
}
if (star[i][1] < -lol.y * 3) {
star[i][1] += lol.h * 3;
test = false;
}
star[i][2] -= lol.spd;
if (star[i][2] > lol.z) {
star[i][2] -= lol.z;
test = false;
}
if (star[i][2] < 0) {
star[i][2] += lol.z;
test = false;
}
star[i][3] = lol.x + (star[i][0] / star[i][2]) * lol.zr;
star[i][4] = lol.y + (star[i][1] / star[i][2]) * lol.zr;
if (test) {
c = 1 - lol.r * star[i][2];
lol.ctx.fillStyle = 'rgba(255,255,255,' + c + ')';
lol.ctx.strokeStyle = 'rgba(255,255,255,' + (c / 4) + ')';
lol.ctx.lineWidth = (1 - lol.r * star[i][2]) * 1.5;
lol.ctx.beginPath();
lol.ctx.moveTo(x2, y2);
lol.ctx.lineTo(star[i][3], star[i][4]);
lol.ctx.rect(star[i][3] - 0.75, star[i][4] - 0.75, 1.5, 1.5);
lol.ctx.closePath();
lol.ctx.stroke();
lol.ctx.fill();
}
}
lol.rid = window.requestAnimationFrame(lol.anim.update);
},
start: function() {
lol.anim.update();
},
stop: function() {
window.cancelAnimationFrame(lol.rid);
lol.rid = false;
},
pause: function() {
lol.anim[lol.rid ? 'stop' : 'start']();
}
};
lol.mouse = {
p: {
x: 0,
y: 0
},
o: {
x: 0,
y: 0
},
click: false,
move: function(e) {
e = e || window.event;
lol.mouse.p.x = ((e.pageX - lol.mouse.o.x) / window.innerWidth) * 256;
lol.mouse.p.y = ((e.pageY - lol.mouse.o.y) / window.innerHeight) * 256;
e.preventDefault();
},
wheel: function(e) {
e = e || window.event;
var delta = e.wheelDelta / 120;
lol.spd -= delta * 0.1;
e.preventDefault();
}
};
lol.key = function(e) {
e = e || window.event;
console.log(e.keyCode);
switch (e.keyCode) {
case 13:
lol.anim.pause();
break;
case 32:
hyperspace = 1;
break;
}
};
lol.init();
body {
margin: 0px;
padding: 0px;
overflow: hidden;
z-index: -1
}
#footer {
text-align: center;
background-color: black;
color: white;
}
#div {
background-color: black;
text-align: center;
}
<footer id="footer">Galaxy Defender
<br>Mohan Bloxs</br>
</footer>
Hi I'm working on a site with a infinite scroll script and am trying to figure out how to add a callback for Image Lightbox:
http://osvaldas.info/image-lightbox-responsive-touch-friendly
I've managed to get the images on the second page to work with image light box and have them styled with the same variables using this:
$(function () {
$('a[data-imagelightbox="d"]').imageLightbox({
onStart: function () {
overlayOn();
},
onLoadStart: function () {
captionOff();
activityIndicatorOn();
},
onLoadEnd: function () {
captionOn();
activityIndicatorOff();
},
onEnd: function () {
captionOff();
overlayOff();
activityIndicatorOff();
}
});
});
My problem is that while the images from "page two" can be viewed within the lightbox, they are not added to the gallery/roll for the user to cycle/navigate through. When the user views an image from "page two" and attempts to cycle through they can only view images from "page one".
Anyone know what script I should be using to get the images refreshed/added after infinite scroll loads more content? Thanks in advance!!
Here is the full js for the Image Lightbox:
var cssTransitionSupport = function () {
var s = document.body || document.documentElement,
s = s.style;
if (s.WebkitTransition == '') return '-webkit-';
if (s.MozTransition == '') return '-moz-';
if (s.OTransition == '') return '-o-';
if (s.transition == '') return '';
return false;
},
isCssTransitionSupport = cssTransitionSupport() === false ? false : true,
cssTransitionTranslateX = function (element, positionX, speed) {
var options = {}, prefix = cssTransitionSupport();
options[prefix + 'transform'] = 'translateX(' + positionX + ')';
options[prefix + 'transition'] = prefix + 'transform ' + speed + 's linear';
element.css(options);
},
hasTouch = ('ontouchstart' in window),
hasPointers = window.navigator.pointerEnabled || window.navigator.msPointerEnabled,
wasTouched = function (event) {
if (hasTouch) return true;
if (!hasPointers || typeof event === 'undefined' || typeof event.pointerType === 'undefined') return false;
if (typeof event.MSPOINTER_TYPE_MOUSE !== 'undefined') {
if (event.MSPOINTER_TYPE_MOUSE != event.pointerType) return true;
} else if (event.pointerType != 'mouse') return true;
return false;
};
$.fn.imageLightbox = function (options) {
var options = $.extend({
selector: 'id="imagelightbox"',
allowedTypes: 'png|jpg|jpeg|gif',
animationSpeed: 250,
preloadNext: true,
enableKeyboard: true,
quitOnEnd: false,
quitOnImgClick: false,
quitOnDocClick: true,
onStart: false,
onEnd: false,
onLoadStart: false,
onLoadEnd: false
},
options),
targets = $([]),
target = $(),
image = $(),
imageWidth = 0,
imageHeight = 0,
swipeDiff = 0,
inProgress = false,
isTargetValid = function (element) {
return $(element).prop('tagName').toLowerCase() == 'a' && (new RegExp('\.(' + options.allowedTypes + ')$', 'i')).test($(element).attr('href'));
},
setImage = function () {
if (!image.length) return true;
var screenWidth = $(window).width() * 0.8,
screenHeight = $(window).height() * 0.9,
tmpImage = new Image();
tmpImage.src = image.attr('src');
tmpImage.onload = function () {
imageWidth = tmpImage.width;
imageHeight = tmpImage.height;
if (imageWidth > screenWidth || imageHeight > screenHeight) {
var ratio = imageWidth / imageHeight > screenWidth / screenHeight ? imageWidth / screenWidth : imageHeight / screenHeight;
imageWidth /= ratio;
imageHeight /= ratio;
}
image.css({
'width': imageWidth + 'px',
'height': imageHeight + 'px',
'top': ($(window).height() - imageHeight) / 2 + 'px',
'left': ($(window).width() - imageWidth) / 2 + 'px'
});
};
},
loadImage = function (direction) {
if (inProgress) return false;
direction = typeof direction === 'undefined' ? false : direction == 'left' ? 1 : -1;
if (image.length) {
if (direction !== false && (targets.length < 2 || (options.quitOnEnd === true && ((direction === -1 && targets.index(target) == 0) || (direction === 1 && targets.index(target) == targets.length - 1))))) {
quitLightbox();
return false;
}
var params = {
'opacity': 0
};
if (isCssTransitionSupport) cssTransitionTranslateX(image, (100 * direction) - swipeDiff + 'px', options.animationSpeed / 1000);
else params.left = parseInt(image.css('left')) + 100 * direction + 'px';
image.animate(params, options.animationSpeed, function () {
removeImage();
});
swipeDiff = 0;
}
inProgress = true;
if (options.onLoadStart !== false) options.onLoadStart();
setTimeout(function () {
image = $('<img ' + options.selector + ' />')
.attr('src', target.attr('href'))
.load(function () {
image.appendTo('body');
setImage();
var params = {
'opacity': 1
};
image.css('opacity', 0);
if (isCssTransitionSupport) {
cssTransitionTranslateX(image, -100 * direction + 'px', 0);
setTimeout(function () {
cssTransitionTranslateX(image, 0 + 'px', options.animationSpeed / 1000)
}, 50);
} else {
var imagePosLeft = parseInt(image.css('left'));
params.left = imagePosLeft + 'px';
image.css('left', imagePosLeft - 100 * direction + 'px');
}
image.animate(params, options.animationSpeed, function () {
inProgress = false;
if (options.onLoadEnd !== false) options.onLoadEnd();
});
if (options.preloadNext) {
var nextTarget = targets.eq(targets.index(target) + 1);
if (!nextTarget.length) nextTarget = targets.eq(0);
$('<img />').attr('src', nextTarget.attr('href')).load();
}
})
.error(function () {
if (options.onLoadEnd !== false) options.onLoadEnd();
})
var swipeStart = 0,
swipeEnd = 0,
imagePosLeft = 0;
image.on(hasPointers ? 'pointerup MSPointerUp' : 'click', function (e) {
e.preventDefault();
if (options.quitOnImgClick) {
quitLightbox();
return false;
}
if (wasTouched(e.originalEvent)) return true;
var posX = (e.pageX || e.originalEvent.pageX) - e.target.offsetLeft;
target = targets.eq(targets.index(target) - (imageWidth / 2 > posX ? 1 : -1));
if (!target.length) target = targets.eq(imageWidth / 2 > posX ? targets.length : 0);
loadImage(imageWidth / 2 > posX ? 'left' : 'right');
})
.on('touchstart pointerdown MSPointerDown', function (e) {
if (!wasTouched(e.originalEvent) || options.quitOnImgClick) return true;
if (isCssTransitionSupport) imagePosLeft = parseInt(image.css('left'));
swipeStart = e.originalEvent.pageX || e.originalEvent.touches[0].pageX;
})
.on('touchmove pointermove MSPointerMove', function (e) {
if (!wasTouched(e.originalEvent) || options.quitOnImgClick) return true;
e.preventDefault();
swipeEnd = e.originalEvent.pageX || e.originalEvent.touches[0].pageX;
swipeDiff = swipeStart - swipeEnd;
if (isCssTransitionSupport) cssTransitionTranslateX(image, -swipeDiff + 'px', 0);
else image.css('left', imagePosLeft - swipeDiff + 'px');
})
.on('touchend touchcancel pointerup pointercancel MSPointerUp MSPointerCancel', function (e) {
if (!wasTouched(e.originalEvent) || options.quitOnImgClick) return true;
if (Math.abs(swipeDiff) > 50) {
target = targets.eq(targets.index(target) - (swipeDiff < 0 ? 1 : -1));
if (!target.length) target = targets.eq(swipeDiff < 0 ? targets.length : 0);
loadImage(swipeDiff > 0 ? 'right' : 'left');
} else {
if (isCssTransitionSupport) cssTransitionTranslateX(image, 0 + 'px', options.animationSpeed / 1000);
else image.animate({
'left': imagePosLeft + 'px'
}, options.animationSpeed / 2);
}
});
}, options.animationSpeed + 100);
},
removeImage = function () {
if (!image.length) return false;
image.remove();
image = $();
},
quitLightbox = function () {
if (!image.length) return false;
image.animate({
'opacity': 0
}, options.animationSpeed, function () {
removeImage();
inProgress = false;
if (options.onEnd !== false) options.onEnd();
});
};
$(window).on('resize', setImage);
if (options.quitOnDocClick) {
$(document).on(hasTouch ? 'touchend' : 'click', function (e) {
if (image.length && !$(e.target).is(image)) quitLightbox();
})
}
if (options.enableKeyboard) {
$(document).on('keyup', function (e) {
if (!image.length) return true;
e.preventDefault();
if (e.keyCode == 27) quitLightbox();
if (e.keyCode == 37 || e.keyCode == 39) {
target = targets.eq(targets.index(target) - (e.keyCode == 37 ? 1 : -1));
if (!target.length) target = targets.eq(e.keyCode == 37 ? targets.length : 0);
loadImage(e.keyCode == 37 ? 'left' : 'right');
}
});
}
$(document).on('click', this.selector, function (e) {
if (!isTargetValid(this)) return true;
e.preventDefault();
if (inProgress) return false;
inProgress = false;
if (options.onStart !== false) options.onStart();
target = $(this);
loadImage();
});
this.each(function () {
if (!isTargetValid(this)) return true;
targets = targets.add($(this));
});
this.switchImageLightbox = function (index) {
var tmpTarget = targets.eq(index);
if (tmpTarget.length) {
var currentIndex = targets.index(target);
target = tmpTarget;
loadImage(index < currentIndex ? 'left' : 'right');
}
return this;
};
this.quitImageLightbox = function () {
quitLightbox();
return this;
};
return this;
};
Firstly,
$(function () {
window.lightbox = $('a[data-imagelightbox="d"]').imageLightbox();
});
At the end of your "imagelightbox.js", Add the below code.
this.quitImageLightbox = function() {
quitLightbox();
return this;
};
this.loadImages = function(images_array) {
targets = images_array;
console.log(targets);
console.log(targets.length);
return this;
};
And when you get newly loaded images
windows.lightbox.loadImages(images_array)
and it should be working...!
I'm using Dynamic Drive's Cross Browser Marquee II scroller script find here. I had some help to alter the script where the content would have a random StartIndex on page load and the random part is working great; the forum thread for that is here. The problem I'm having now is that the altered script is not producing the pause on MouseOver function. I've made a JSFiddle here and tried everything I could think of to fix it but I'm stuck. The JavaScript is as follows:
function scrollmarquee() {
if (parseInt(cross_marquee.style.top) > (actualheight * (-1) + 8)) {
cross_marquee.style.top = parseInt(cross_marquee.style.top) - copyspeed + "px";
} else {
cross_marquee.style.top = parseInt(marqueeheight) + 8 + "px";
}
}
function marqueescroll(o) {
marqueePause(o.id);
o.srt += o.ss;
if ((o.ss < 0 && o.srt > o.h) || (o.ss > 0 && o.srt < o.ph)) {
o.s.style.top = o.srt + 'px';
} else {
o.srt = o.ss < 0 ? o.ph : o.h;
o.s.style.top = o.srt + 'px';
}
o.to = setTimeout(function () {
marqueescroll(o);
}, 60);
}
function marquee(o) {
var id = o.ID,
ss = o.Speed,
i = o.StartIndex,
srt = o.AutoDelay,
p = document.getElementById(id),
s = p ? p.getElementsByTagName('DIV')[0] : null,
ary = [],
z0 = 0;
if (s) {
var clds = s.childNodes,
o = marquee[id] = {
id: id,
p: p,
h: -s.offsetHeight,
ph: p.offsetHeight,
s: s,
ss: typeof (ss) == 'number' && ss != 0 ? ss : -2,
srt: 0
}
for (; z0 < clds.length; z0++) {
if (clds[z0].nodeType == 1) {
ary.push(clds[z0]);
}
}
ary[i] ? o.srt = -ary[i].offsetTop : null;
o.s.style.position = 'absolute';
o.s.style.top = o.srt + 'px';
typeof (srt) == 'number' && srt > 1 ? marqueeAuto(id, srt) : null;
}
}
function marqueeAuto(id, ms) {
var o = marquee[id];
o ? o.to = setTimeout(function () {
marqueescroll(o);
}, ms || 200) : null;
}
function marqueePause(id) {
var o = marquee[id];
o ? clearTimeout(o.to) : null;
}
function marqueeInit() {
marquee({
ID: 'marqueecontainer', // the unique ID name of the parent DIV.(string)
AutoDelay: 2000, //(optional) the delay before starting scroll in milli seconds. (number, default = no auto scroll)
Speed: -1, //(optional) the scroll speed, < 0 = up. > 0 = down. (number, default = -2)
StartIndex: Math.floor(Math.random() * 4) //(optional) the index number of the element to start. (number, default = 0)
});
}
if (window.addEventListener) window.addEventListener("load", marqueeInit, false);
else if (window.attachEvent) window.attachEvent("onload", marqueeInit);
else if (document.getElementById);
window.onload = marqueeInit;
It's probably a real simple fix I'm just not catching. Any help would greatly be appreciated. Also, does anyone know of a way to make the scroller where there will be no blank space between the last and first items being scrolled in the list?
This has now been fixed and is completely cross browser and twitter bootstrap friendly. You can check out the new edited jsfiddle here. Fixed javascript is as follows:
function marqueescroll(o) {
marqueePause(o.id);
o.srt += o.ss;
if ((o.ss < 0 && o.srt > o.sz) || (o.ss > 0 && o.srt < (o.w ? -o.sz : o.psz))) {
o.s.style[o.m] = o.srt + 'px';
} else {
o.srt = (o.w ? 0 : o.ss < 0 ? o.psz : o.sz) + o.ss;
o.s.style[o.m] = o.srt + 'px';
}
o.to = setTimeout(function () {
marqueescroll(o);
}, 30);
}
function marquee(o) {
var id = o.ID,
m = o.Mode,
ss = o.Speed,
i = o.StartIndex,
srt = o.AutoDelay,
p = document.getElementById(id),
s = p ? p.getElementsByTagName('DIV')[0] : null,
clds = s ? s.childNodes : [],
ary = [],
sz, l, z0 = 0;
if (s && !marquee[id]) {
var m = typeof (m) == 'string' && m.charAt(0).toUpperCase() == 'H' ? ['left', 'offsetLeft', 'offsetWidth'] : ['top', 'offsetTop', 'offsetHeight'],
sz = p[m[2]],
slide = document.createElement('DIV'),
c;
slide.style.width = 'inherit',//added this for fluid bootstrap width
slide.style.position = s.style.position = 'absolute';
for (; z0 < clds.length; z0++) {
if (clds[z0].nodeType == 1) {
if (m[0] == 'left') {
clds[z0].style.position = 'absolute';
clds[z0].style.left = sz * ary.length + 'px';
clds[z0].style.top = '0px';
}
ary.push([clds[z0], clds[z0][m[1]]]);
}
}
l = ary[ary.length - 1][0];
o = marquee[id] = {
m: m[0],
id: id,
p: p,
sz: -(l[m[1]] + l[m[2]]),
psz: sz,
s: slide,
ss: typeof (ss) == 'number' && ss != 0 ? ss : -2,
w: o.Wrap !== false
}
o.s.appendChild(s);
c = s.cloneNode(true);
c.style.left = c.style.top = '0px';
c.style[m[0]] = o.sz * (ss > 0 ? 1 : -1) + 'px';
o.w ? o.s.appendChild(c) : null;
o.srt = ary[i] ? -ary[i][1] : 0;
o.s.style.position = 'absolute';
o.s.style[m[0]] = o.srt + 'px';
p.appendChild(o.s);
p.style.overflow = 'hidden';
typeof (srt) == 'number' && srt > 1 ? marqueeAuto(id, srt) : null;
}
}
function marqueeAuto(id, ms) {
var o = marquee[id];
o ? o.to = setTimeout(function () {
marqueescroll(o);
}, ms || 200) : null;
}
function marqueePause(id) {
var o = marquee[id];
o ? clearTimeout(o.to) : null;
}
function marqueeInit() {
marquee({
ID: 'marqueecontainer', // the unique ID name of the parent DIV. (string)
Mode: 'vertical', // the display type, 'vertical' or 'horizontal' (string. defalut = 'vertical')
AutoDelay: 2000, //(optional) the delay before starting scroll in milli seconds. (number, default = no auto scroll)
Speed: -2, //(optional) the scroll speed, < 0 = up. > 0 = down. (number, default = -2)
Wrap: true, //(optional) true = no gap, false = gap. (boolean, default = true)
StartIndex: Math.floor(Math.random() * 4) //(optional) the index number of the element to start. (number, default = 0)
});
}
if (window.addEventListener) window.addEventListener("load", marqueeInit, false);
else if (window.attachEvent) window.attachEvent("onload", marqueeInit);
else if (document.getElementById) window.onload = marqueeInit;
I needed to make a floating menu, I searched online and found a script here http://www.jtricks.com/javascript/navigation/floating.html
/* Script by: www.jtricks.com
* Version: 1.12 (20120823)
* Latest version: www.jtricks.com/javascript/navigation/floating.html
*
* License:
* GNU/GPL v2 or later http://www.gnu.org/licenses/gpl-2.0.html
*/
var floatingMenu =
{
hasInner: typeof(window.innerWidth) == 'number',
hasElement: typeof(document.documentElement) == 'object'
&& typeof(document.documentElement.clientWidth) == 'number'};
var floatingArray =
[
];
floatingMenu.add = function(obj, options)
{
var name;
var menu;
if (typeof(obj) === "string")
name = obj;
else
menu = obj;
if (options == undefined)
{
floatingArray.push(
{
id: name,
menu: menu,
targetLeft: 0,
targetTop: 0,
distance: .07,
snap: true,
updateParentHeight: false
});
}
else
{
floatingArray.push(
{
id: name,
menu: menu,
targetLeft: options.targetLeft,
targetRight: options.targetRight,
targetTop: options.targetTop,
targetBottom: options.targetBottom,
centerX: options.centerX,
centerY: options.centerY,
prohibitXMovement: options.prohibitXMovement,
prohibitYMovement: options.prohibitYMovement,
distance: options.distance != undefined ? options.distance : .07,
snap: options.snap,
ignoreParentDimensions: options.ignoreParentDimensions,
updateParentHeight:
options.updateParentHeight == undefined
? false
: options.updateParentHeight,
scrollContainer: options.scrollContainer,
scrollContainerId: options.scrollContainerId,
confinementArea: options.confinementArea,
confinementAreaId:
options.confinementArea != undefined
&& options.confinementArea.substring(0, 1) == '#'
? options.confinementArea.substring(1)
: undefined,
confinementAreaClassRegexp:
options.confinementArea != undefined
&& options.confinementArea.substring(0, 1) == '.'
? new RegExp("(^|\\s)" + options.confinementArea.substring(1) + "(\\s|$)")
: undefined
});
}
};
floatingMenu.findSingle = function(item)
{
if (item.id)
item.menu = document.getElementById(item.id);
if (item.scrollContainerId)
item.scrollContainer = document.getElementById(item.scrollContainerId);
};
floatingMenu.move = function (item)
{
if (!item.prohibitXMovement)
{
item.menu.style.left = item.nextX + 'px';
item.menu.style.right = '';
}
if (!item.prohibitYMovement)
{
item.menu.style.top = item.nextY + 'px';
item.menu.style.bottom = '';
}
};
floatingMenu.scrollLeft = function(item)
{
// If floating within scrollable container use it's scrollLeft
if (item.scrollContainer)
return item.scrollContainer.scrollLeft;
var w = window.top;
return this.hasInner
? w.pageXOffset
: this.hasElement
? w.document.documentElement.scrollLeft
: w.document.body.scrollLeft;
};
floatingMenu.scrollTop = function(item)
{
// If floating within scrollable container use it's scrollTop
if (item.scrollContainer)
return item.scrollContainer.scrollTop;
var w = window.top;
return this.hasInner
? w.pageYOffset
: this.hasElement
? w.document.documentElement.scrollTop
: w.document.body.scrollTop;
};
floatingMenu.windowWidth = function()
{
return this.hasElement
? document.documentElement.clientWidth
: document.body.clientWidth;
};
floatingMenu.windowHeight = function()
{
if (floatingMenu.hasElement && floatingMenu.hasInner)
{
// Handle Opera 8 problems
return document.documentElement.clientHeight > window.innerHeight
? window.innerHeight
: document.documentElement.clientHeight
}
else
{
return floatingMenu.hasElement
? document.documentElement.clientHeight
: document.body.clientHeight;
}
};
floatingMenu.documentHeight = function()
{
var innerHeight = this.hasInner
? window.innerHeight
: 0;
var body = document.body,
html = document.documentElement;
return Math.max(
body.scrollHeight,
body.offsetHeight,
html.clientHeight,
html.scrollHeight,
html.offsetHeight,
innerHeight);
};
floatingMenu.documentWidth = function()
{
var innerWidth = this.hasInner
? window.innerWidth
: 0;
var body = document.body,
html = document.documentElement;
return Math.max(
body.scrollWidth,
body.offsetWidth,
html.clientWidth,
html.scrollWidth,
html.offsetWidth,
innerWidth);
};
floatingMenu.calculateCornerX = function(item)
{
var offsetWidth = item.menu.offsetWidth;
var result = this.scrollLeft(item) - item.parentLeft;
if (item.centerX)
{
result += (this.windowWidth() - offsetWidth)/2;
}
else if (item.targetLeft == undefined)
{
result += this.windowWidth() - item.targetRight - offsetWidth;
}
else
{
result += item.targetLeft;
}
if (document.body != item.menu.parentNode
&& result + offsetWidth >= item.confinedWidthReserve)
{
result = item.confinedWidthReserve - offsetWidth;
}
if (result < 0)
result = 0;
return result;
};
floatingMenu.calculateCornerY = function(item)
{
var offsetHeight = item.menu.offsetHeight;
var result = this.scrollTop(item) - item.parentTop;
if (item.centerY)
{
result += (this.windowHeight() - offsetHeight)/2;
}
else if (item.targetTop === undefined)
{
result += this.windowHeight() - item.targetBottom - offsetHeight;
}
else
{
result += item.targetTop;
}
if (document.body != item.menu.parentNode
&& result + offsetHeight >= item.confinedHeightReserve)
{
result = item.confinedHeightReserve - offsetHeight;
}
if (result < 0)
result = 0;
return result;
};
floatingMenu.isConfinementArea = function(item, area)
{
return item.confinementAreaId != undefined
&& area.id == item.confinementAreaId
|| item.confinementAreaClassRegexp != undefined
&& area.className
&& item.confinementAreaClassRegexp.test(area.className);
};
floatingMenu.computeParent = function(item)
{
if (item.ignoreParentDimensions)
{
item.confinedHeightReserve = this.documentHeight();
item.confinedWidthReserver = this.documentWidth();
item.parentLeft = 0;
item.parentTop = 0;
return;
}
var parentNode = item.menu.parentNode;
var parentOffsets = this.offsets(parentNode, item);
item.parentLeft = parentOffsets.left;
item.parentTop = parentOffsets.top;
item.confinedWidthReserve = parentNode.clientWidth;
// We could have absolutely-positioned DIV wrapped
// inside relatively-positioned. Then parent might not
// have any height. Try to find parent that has
// and try to find whats left of its height for us.
var obj = parentNode;
var objOffsets = this.offsets(obj, item);
if (item.confinementArea == undefined)
{
while (obj.clientHeight + objOffsets.top
< item.menu.scrollHeight + parentOffsets.top
|| item.menu.parentNode == obj
&& item.updateParentHeight
&& obj.clientHeight + objOffsets.top
== item.menu.scrollHeight + parentOffsets.top)
{
obj = obj.parentNode;
objOffsets = this.offsets(obj, item);
}
}
else
{
while (obj.parentNode != undefined
&& !this.isConfinementArea(item, obj))
{
obj = obj.parentNode;
objOffsets = this.offsets(obj, item);
}
}
item.confinedHeightReserve = obj.clientHeight
- (parentOffsets.top - objOffsets.top);
};
floatingMenu.offsets = function(obj, item)
{
var result =
{
left: 0,
top: 0
};
if (obj === item.scrollContainer)
return;
while (obj.offsetParent && obj.offsetParent != item.scrollContainer)
{
result.left += obj.offsetLeft;
result.top += obj.offsetTop;
obj = obj.offsetParent;
}
if (window == window.top)
return result;
// we're IFRAMEd
var iframes = window.top.document.body.getElementsByTagName("IFRAME");
for (var i = 0; i < iframes.length; i++)
{
if (iframes[i].contentWindow != window)
continue;
obj = iframes[i];
while (obj.offsetParent)
{
result.left += obj.offsetLeft;
result.top += obj.offsetTop;
obj = obj.offsetParent;
}
}
return result;
};
floatingMenu.doFloatSingle = function(item)
{
this.findSingle(item);
if (item.updateParentHeight)
{
item.menu.parentNode.style.minHeight =
item.menu.scrollHeight + 'px';
}
var stepX, stepY;
this.computeParent(item);
var cornerX = this.calculateCornerX(item);
var stepX = (cornerX - item.nextX) * item.distance;
if (Math.abs(stepX) < .5 && item.snap
|| Math.abs(cornerX - item.nextX) <= 1)
{
stepX = cornerX - item.nextX;
}
var cornerY = this.calculateCornerY(item);
var stepY = (cornerY - item.nextY) * item.distance;
if (Math.abs(stepY) < .5 && item.snap
|| Math.abs(cornerY - item.nextY) <= 1)
{
stepY = cornerY - item.nextY;
}
if (Math.abs(stepX) > 0 ||
Math.abs(stepY) > 0)
{
item.nextX += stepX;
item.nextY += stepY;
this.move(item);
}
};
floatingMenu.fixTargets = function()
{
};
floatingMenu.fixTarget = function(item)
{
};
floatingMenu.doFloat = function()
{
this.fixTargets();
for (var i=0; i < floatingArray.length; i++)
{
this.fixTarget(floatingArray[i]);
this.doFloatSingle(floatingArray[i]);
}
setTimeout('floatingMenu.doFloat()', 20);
};
floatingMenu.insertEvent = function(element, event, handler)
{
// W3C
if (element.addEventListener != undefined)
{
element.addEventListener(event, handler, false);
return;
}
var listener = 'on' + event;
// MS
if (element.attachEvent != undefined)
{
element.attachEvent(listener, handler);
return;
}
// Fallback
var oldHandler = element[listener];
element[listener] = function (e)
{
e = (e) ? e : window.event;
var result = handler(e);
return (oldHandler != undefined)
&& (oldHandler(e) == true)
&& (result == true);
};
};
floatingMenu.init = function()
{
floatingMenu.fixTargets();
for (var i=0; i < floatingArray.length; i++)
{
floatingMenu.initSingleMenu(floatingArray[i]);
}
setTimeout('floatingMenu.doFloat()', 100);
};
// Some browsers init scrollbars only after
// full document load.
floatingMenu.initSingleMenu = function(item)
{
this.findSingle(item);
this.computeParent(item);
this.fixTarget(item);
item.nextX = this.calculateCornerX(item);
item.nextY = this.calculateCornerY(item);
this.move(item);
};
floatingMenu.insertEvent(window, 'load', floatingMenu.init);
// Register ourselves as jQuery plugin if jQuery is present
if (typeof(jQuery) !== 'undefined')
{
(function ($)
{
$.fn.addFloating = function(options)
{
return this.each(function()
{
floatingMenu.add(this, options);
});
};
}) (jQuery);
}
The script requires the menu to have #floatdiv id. I made my div, #floatdiv, and added the following line of javascript to the head to make the action start working:
<script type="text/javascript">
floatingMenu.add('floatdiv',
{
targetLeft: 250,
targetTop: 290,
snap: true
});
</script>
the #floatdiv css is here,
#floatdiv{
height:45px;
width:830px;
z-index:2;
}
The script is working fine. When I scroll down, the menu float as specified. But I dun wanna the menu to float all the way with scrolling. I need the float of the menu to fire only when I enter specific divs not all the way with scrolling.. Any clues?
is this what look like?
html
<div id="header">HEADER</div>
<div id="content">
<div id="left">LEFT</div>
<div id="right">RIGHT</div>
</div>
<div id="footer">FOOTER</div>
js
$(function() {
var $sidebar = $("#right"),
$window = $(window),
rightOffset = $sidebar.offset(),
rightDelta = $("#footer").offset().top - $("#header").offset().top - $("#header").outerHeight() - $("#right").outerHeight(),
topPadding = 15;
$window.scroll(function() {
$sidebar.stop().animate({
marginTop: Math.max(Math.min($window.scrollTop() - rightOffset.top + topPadding, rightDelta), 0)
});
});
});
working demo
hope this help you
I wrote the script listed in the question.
The script is very versatile and can make div float within a specific area (e.g. another container div). Here are the instructions:
http://www.jtricks.com/javascript/navigation/floating/confined_demo.html