I'm trying to combine the functionality of two buttons into one. This is a program that enables/disables a text or image magnifier. If I enable the zoomer than I want both the text and image to magnify if they are hovered on and vice versa with disable.
How should I edit the function/code to reflect one button that controls the magnification of both image and text?
This is the function I believe is controlling the button and zooming:
$("button").click(function() {
var state = $(this).text(); // enable or disable
$(".zoom:eq(" + $(this).attr('data-id') + ")").anythingZoomer(state);
$(this).text((state === "disable") ? "enable" : "disable");
return false;
});
The full project is below
;
(function(factory) {
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = factory(require('jquery'));
} else {
factory(jQuery);
}
}(function($) {
"use strict";
$.anythingZoomer = function(el, options) {
var n, o, t, base = this;
base.$wrap = $(el);
base.wrap = el;
// Add a reverse reference to the DOM object
base.$wrap.data('zoomer', base);
base.version = '2.2.6';
base.init = function() {
base.options = o = $.extend({}, $.anythingZoomer.defaultOptions, options);
// default class names
n = $.anythingZoomer.classNames;
// true when small element is showing, false when large is visible
base.state = true;
base.enabled = true;
base.hovered = false;
base.$wrap.addClass(n.wrap).wrapInner('<span class="' + n.wrapInner + '"/>');
base.$inner = base.$wrap.find('.' + n.wrapInner);
base.$small = base.$wrap.find('.' + o.smallArea);
base.$large = base.$wrap.find('.' + o.largeArea);
base.update();
// Add classes after getting size
base.$large.addClass(n.large);
base.$small.addClass(n.small);
base.$inner
.bind('mouseenter' + n.namespace, function() {
if (!base.enabled) {
return;
}
base.saved = base.enabled;
base.hovered = true;
if (o.delay) {
clearTimeout(base.delay);
base.enabled = false;
base.delay = setTimeout(function() {
base.enabled = base.saved;
base.position.type = 'mousemove';
base.$inner.trigger(base.position);
base.reveal();
}, o.delay);
} else {
base.reveal();
}
})
.bind('mouseleave' + n.namespace, function() {
base.hovered = false;
if (!base.enabled) {
return;
}
if (o.delay) {
clearTimeout(base.delay);
base.enabled = base.saved;
}
if (base.state && base.enabled) {
// delay hiding to prevent flash if user hovers over it again
// i.e. moving from a link to the image
base.timer = setTimeout(function() {
if (base.$zoom.hasClass(n.windowed)) {
base.hideZoom(true);
}
}, 200);
}
})
.bind('mousemove' + n.namespace, function(e) {
if (!base.enabled) {
return;
}
base.position = e;
if (!base.hovered) {
return;
}
if (base.state && base.enabled) {
clearTimeout(base.timer);
// get current offsets in case page positioning has changed
// Double demo: expanded text demo will offset image demo zoom window
var off = base.$small.offset();
base.zoomAt(e.pageX - off.left, e.pageY - off.top, null, true);
}
})
.bind(o.switchEvent + (o.switchEvent !== '' ? n.namespace : ''), function() {
if (!base.enabled) {
return;
}
// toggle visible image
if (base.state) {
base.showLarge();
} else {
base.showSmall();
}
});
base.showSmall();
// add events
$.each('initialized zoom unzoom'.split(' '), function(i, f) {
if ($.isFunction(o[f])) {
base.$wrap.bind(f, o[f]);
}
});
base.initialized = true;
base.$wrap.trigger('initialized', base);
};
base.reveal = function() {
base.enabled = base.saved;
if (base.state && base.enabled) {
base.$zoom.stop(true, true).fadeIn(o.speed);
if (o.overlay) {
base.$overlay.addClass(n.overlay);
}
base.$smInner.addClass(n.hovered);
base.$wrap.trigger('zoom', base);
}
};
base.update = function() {
// make sure the large image is hidden
if (base.initialized) {
base.showSmall();
}
base.$smInner = (base.$small.find('.' + n.smallInner).length) ?
base.$small.find('.' + n.smallInner) :
base.$small.wrapInner('<span class="' + n.smallInner + '"/>').find('.' + n.smallInner);
base.$small.find('.' + n.overly).remove();
if (o.clone) {
t = base.$smInner.clone()
.removeAttr('id')
.removeClass(n.smallInner)
.addClass(n.largeInner);
if (base.$large.length) {
// large area exists, just add content
base.$large.html(t.html());
} else {
// no large area, so add it
t.wrap('<div class="' + o.largeArea + '">');
base.$small.after(t.parent());
// set base.$large again in case small area was cloned
base.$large = base.$wrap.find('.' + o.largeArea);
}
}
base.$lgInner = (base.$large.find('.' + n.largeInner).length) ?
base.$large.find('.' + n.largeInner) :
base.$large.wrapInner('<span class="' + n.largeInner + '"/>').find('.' + n.largeInner);
if (!base.$wrap.find('.' + n.zoom).length) {
base.$large.wrap('<div class="' + n.zoom + '"/>');
base.$zoom = base.$wrap.find('.' + n.zoom);
}
if (o.edit && !base.edit) {
base.edit = $('<span class="' + n.edit + '"></span>').appendTo(base.$zoom);
}
// wrap inner content with a span to get a more accurate width
// get height from either the inner content itself or the children of the inner content since span will need
// a "display:block" to get an accurate height, but adding that messes up the width
base.$zoom.show();
base.largeDim = [base.$lgInner.children().width(), Math.max(base.$lgInner.height(), base.$lgInner.children().height())];
base.zoomDim = base.last = [base.$zoom.width(), base.$zoom.height()];
base.$zoom.hide();
base.smallDim = [base.$smInner.children().width(), base.$small.height()];
base.$overlay = $('<div class="' + n.overly + '" style="position:absolute;left:0;top:0;" />').prependTo(base.$small);
base.ratio = [
base.largeDim[0] / (base.smallDim[0] || 1),
base.largeDim[1] / (base.smallDim[1] || 1)
];
base.$inner.add(base.$overlay).css({
width: base.smallDim[0],
height: base.smallDim[1]
});
};
// Show small image - Setup
base.showSmall = function() {
base.state = true;
base.$small.show();
base.$zoom
.removeClass(n.expanded)
.addClass(n.windowed + ' ' + n.zoom)
.css({
width: base.zoomDim[0],
height: base.zoomDim[1]
});
base.$inner.css({
width: base.smallDim[0],
height: base.smallDim[1]
});
};
// Switch small and large on double click
base.showLarge = function() {
base.state = false;
base.$small.hide();
base.$zoom
.stop(true, true)
.fadeIn(o.speed)
.addClass(n.expanded)
.removeClass(n.windowed + ' ' + n.zoom)
.css({
height: 'auto',
width: 'auto'
});
base.$inner.css({
width: base.largeDim[0],
height: base.largeDim[1]
});
base.$large.css({
left: 0,
top: 0,
width: base.largeDim[0],
height: base.largeDim[1]
});
};
// x,y coords -> George Washington in image demo
// base.setTarget( 82, 50, [200,200] );
// 'selector', [xOffset, yOffset], [zoomW, zoomH] -> Aug 26 in calendar demo
// base.setTarget( '.day[rel=2009-08-26]', [0, 0], [200, 200] );
base.setTarget = function(tar, sec, sz) {
var t, x = 0,
y = 0;
clearTimeout(base.timer);
if (!base.$zoom.hasClass(n.windowed)) {
base.showSmall();
}
// x, y coords
if (!isNaN(tar) && !isNaN(sec)) {
x = parseInt(tar, 10);
y = parseInt(sec, 10);
} else if (typeof(tar) === 'string' && $(tar).length) {
// '.selector', [xOffSet, yOffSet]
t = $(tar);
x = t.position().left + t.width() / 2 + (sec ? sec[0] || 0 : 0);
y = t.position().top + t.height() / 2 + (sec ? sec[1] || 0 : 0);
}
base.zoomAt(x, y, sz);
// add overlay
if (o.overlay) {
base.$overlay.addClass(n.overlay);
}
// hovered, but not really
base.$smInner.addClass(n.hovered);
// zoom window triggered
base.$wrap.trigger('zoom', base);
};
// x, y, [zoomX, zoomY] - zoomX, zoomY are the dimensions of the zoom window
base.zoomAt = function(x, y, sz, internal) {
var sx = (sz ? sz[0] || 0 : 0) || base.last[0],
sy = (sz ? sz[1] || sz[0] || 0 : 0) || base.last[1],
sx2 = sx / 2,
sy2 = sy / 2,
ex = o.edge || (o.edge === 0 ? 0 : sx2 * 0.66), // 2/3 of zoom window
ey = o.edge || (o.edge === 0 ? 0 : sy2 * 0.66), // allows edge to be zero
m = parseInt(base.$inner.css('margin-left'), 10) || base.$inner.position().left || 0;
// save new zoom size
base.last = [sx, sy];
// save x, y for external access
base.current = [x, y];
// show coordinates
if (o.edit) {
base.edit.html(Math.round(x) + ', ' + Math.round(y));
}
if ((x < -ex) || (x > base.smallDim[0] + ex) || (y < -ey) || (y > base.smallDim[1] + ey)) {
base.hideZoom(internal);
return;
} else {
// Sometimes the mouseenter event is delayed
base.$zoom.stop(true, true).fadeIn(o.speed);
}
// center zoom under the cursor
base.$zoom.css({
left: x - sx2 + m,
top: y - sy2,
width: sx,
height: sy
});
// match locations of small element to the large
base.$large.css({
left: -(x - o.offsetX - sx2 / 2) * base.ratio[0],
top: -(y - o.offsetY - sy2 / 2) * base.ratio[1]
});
};
base.hideZoom = function(internal) {
if (internal && base.$smInner.hasClass(n.hovered)) {
base.$wrap.trigger('unzoom', base);
}
base.last = base.zoomDim;
base.$zoom.stop(true, true).fadeOut(o.speed);
base.$overlay.removeClass(n.overlay);
base.$smInner.removeClass(n.hovered);
base.lastKey = null;
};
base.setEnabled = function(enable) {
base.enabled = enable;
if (enable) {
var off = base.$small.offset();
base.zoomAt(base.position.pageX - off.left, base.position.pageY - off.top, null, true);
} else {
base.showSmall();
base.hideZoom();
base.hovered = false;
}
};
// Initialize zoomer
base.init();
};
// class names used by anythingZoomer
$.anythingZoomer.classNames = {
namespace: '.anythingZoomer', // event namespace
wrap: 'az-wrap',
wrapInner: 'az-wrap-inner',
large: 'az-large',
largeInner: 'az-large-inner',
small: 'az-small',
smallInner: 'az-small-inner',
overlay: 'az-overlay', // toggled class name
overly: 'az-overly', // overlay unstyled class
hovered: 'az-hovered',
zoom: 'az-zoom',
windowed: 'az-windowed', // zoom window active
expanded: 'az-expanded', // zoom window inactive (large is showing)
edit: 'az-coords', // coordinate window
scrollzoom: 'az-scrollzoom'
};
$.anythingZoomer.defaultOptions = {
// content areas
smallArea: 'small', // class of small content area; the element with this class name must be inside of the wrapper
largeArea: 'large', // class of large content area; this class must exist inside of the wrapper. When the clone option is true, it will add this automatically
clone: false, // Make a clone of the small content area, use css to modify the style
// appearance
overlay: false, // set to true to apply overlay class "az-overlay"; false to not apply it
speed: 100, // fade animation speed (in milliseconds)
edge: 30, // How far outside the wrapped edges the mouse can go; previously called "expansionSize"
offsetX: 0, // adjust the horizontal position of the large content inside the zoom window as desired
offsetY: 0, // adjust the vertical position of the large content inside the zoom window as desired
// functionality
switchEvent: 'dblclick', // event that allows toggling between small and large elements - default is double click
delay: 0, // time to delay before revealing the zoom window.
// edit mode
edit: false // add x,y coordinates into zoom window to make it easier to find coordinates
};
$.fn.anythingZoomer = function(options, second, sx, sy) {
return this.each(function() {
var anyZoom = $(this).data('zoomer');
// initialize the zoomer but prevent multiple initializations
if (/object|undefined/.test(typeof options)) {
if (anyZoom) {
anyZoom.update();
} else {
(new $.anythingZoomer(this, options));
}
} else if (anyZoom && (typeof options === 'string' || (!isNaN(options) && !isNaN(second)))) {
if (/(en|dis)able/.test(options)) {
anyZoom.setEnabled(options === 'enable');
} else {
anyZoom.setTarget(options, second, sx, sy);
}
}
});
};
$.fn.getAnythingZoomer = function() {
return this.data('zoomer');
};
return $.anythingzoomer;
}));
/* AnythingZoomer */
.az-wrap,
.az-small,
.az-large {
position: relative;
}
.az-wrap-inner {
display: block;
margin: 0 auto;
/* center small & large content */
}
/* This wraps the large image and hides it */
.az-zoom {
background: #fff;
border: #333 1px solid;
position: absolute;
top: 0;
left: 0;
width: 150px;
height: 150px;
overflow: hidden;
z-index: 100;
display: none;
-moz-box-shadow: inset 0px 0px 4px #000;
-webkit-box-shadow: inset 0px 0px 4px #000;
box-shadow: inset 0px 0px 4px #000;
}
/* Class applied to az-mover when large image is windowed */
.az-windowed {
overflow: hidden;
position: absolute;
}
/* Class applied to az-mover when large image is fully shown */
.az-expanded {
height: auto;
width: auto;
position: static;
overflow: visible;
}
/* overlay small area */
.az-overlay {
background-color: #000;
opacity: 0.3;
filter: alpha(opacity=30);
z-index: 10;
}
/* edit mode coordinate styling */
.az-coords {
display: none;
/* hidden when expanded */
}
.az-zoom .az-coords {
display: block;
position: absolute;
top: 0;
right: 0;
background: #000;
background: rgba(0, 0, 0, 0.5);
color: #fff;
}
/* ZOOM CONTAINER */
.zoom {
display: block;
margin: 0 auto;
}
.large {
background: white;
}
/* FOR TEXT DEMO */
.small p {
font-size: 16px;
width: 700px
}
.large p {
font-size: 32px;
width: 1400px;
}
/* FOR IMAGE DEMO */
.small img {
width: 250px;
}
.large img {
width: 500px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Image and Text Magnifier</title>
<!-- anythingZoomer required -->
<link rel="stylesheet" href="css/anythingzoomer.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="js/jquery.anythingzoomer.js"></script>
<script>
$(function() {
// clone the text
$(".zoom:first").anythingZoomer({
clone: true
});
$(".zoom:last").anythingZoomer();
$("button").click(function() {
var state = $(this).text(); // enable or disable
$(".zoom:eq(" + $(this).attr('data-id') + ")").anythingZoomer(state);
$(this).text((state === "disable") ? "enable" : "disable");
return false;
});
});
</script>
</head>
<body id="double">
<div id="main-content">
<p>Double click within the section to toggle between the large and small versions.</p>
<p><strong>Text Demo <button data-id="0">disable</button></strong></p>
<div class="zoom">
<div class="small">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae
est. Mauris placerat eleifend leo.</p>
</div>
<!-- the clone option will automatically make a div.large if it doesn't exist -->
</div>
<br>
<p><strong>Image Demo <button data-id="1">disable</button></strong></p>
<div class="zoom second">
<div class="small">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Dean_Franklin_-_06.04.03_Mount_Rushmore_Monument_%28by-sa%29-3_new.jpg/1200px-Dean_Franklin_-_06.04.03_Mount_Rushmore_Monument_%28by-sa%29-3_new.jpg" alt="small rushmore">
</div>
<div class="large">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Dean_Franklin_-_06.04.03_Mount_Rushmore_Monument_%28by-sa%29-3_new.jpg/1200px-Dean_Franklin_-_06.04.03_Mount_Rushmore_Monument_%28by-sa%29-3_new.jpg" alt="big rushmore">
</div>
</div>
</div>
</body>
</html>
This works! Just loop through each of the elements using .each and then add the scroll zoomer function to it.when the button is pressed, loop through the elements again and apply the toggle functionality.
;
(function(factory) {
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof module === 'object' && typeof module.exports === 'object') {
module.exports = factory(require('jquery'));
} else {
factory(jQuery);
}
}(function($) {
"use strict";
$.anythingZoomer = function(el, options) {
var n, o, t, base = this;
base.$wrap = $(el);
base.wrap = el;
// Add a reverse reference to the DOM object
base.$wrap.data('zoomer', base);
base.version = '2.2.6';
base.init = function() {
base.options = o = $.extend({}, $.anythingZoomer.defaultOptions, options);
// default class names
n = $.anythingZoomer.classNames;
// true when small element is showing, false when large is visible
base.state = true;
base.enabled = true;
base.hovered = false;
base.$wrap.addClass(n.wrap).wrapInner('<span class="' + n.wrapInner + '"/>');
base.$inner = base.$wrap.find('.' + n.wrapInner);
base.$small = base.$wrap.find('.' + o.smallArea);
base.$large = base.$wrap.find('.' + o.largeArea);
base.update();
// Add classes after getting size
base.$large.addClass(n.large);
base.$small.addClass(n.small);
base.$inner
.bind('mouseenter' + n.namespace, function() {
if (!base.enabled) {
return;
}
base.saved = base.enabled;
base.hovered = true;
if (o.delay) {
clearTimeout(base.delay);
base.enabled = false;
base.delay = setTimeout(function() {
base.enabled = base.saved;
base.position.type = 'mousemove';
base.$inner.trigger(base.position);
base.reveal();
}, o.delay);
} else {
base.reveal();
}
})
.bind('mouseleave' + n.namespace, function() {
base.hovered = false;
if (!base.enabled) {
return;
}
if (o.delay) {
clearTimeout(base.delay);
base.enabled = base.saved;
}
if (base.state && base.enabled) {
// delay hiding to prevent flash if user hovers over it again
// i.e. moving from a link to the image
base.timer = setTimeout(function() {
if (base.$zoom.hasClass(n.windowed)) {
base.hideZoom(true);
}
}, 200);
}
})
.bind('mousemove' + n.namespace, function(e) {
if (!base.enabled) {
return;
}
base.position = e;
if (!base.hovered) {
return;
}
if (base.state && base.enabled) {
clearTimeout(base.timer);
// get current offsets in case page positioning has changed
// Double demo: expanded text demo will offset image demo zoom window
var off = base.$small.offset();
base.zoomAt(e.pageX - off.left, e.pageY - off.top, null, true);
}
})
.bind(o.switchEvent + (o.switchEvent !== '' ? n.namespace : ''), function() {
if (!base.enabled) {
return;
}
// toggle visible image
if (base.state) {
base.showLarge();
} else {
base.showSmall();
}
});
base.showSmall();
// add events
$.each('initialized zoom unzoom'.split(' '), function(i, f) {
if ($.isFunction(o[f])) {
base.$wrap.bind(f, o[f]);
}
});
base.initialized = true;
base.$wrap.trigger('initialized', base);
};
base.reveal = function() {
base.enabled = base.saved;
if (base.state && base.enabled) {
base.$zoom.stop(true, true).fadeIn(o.speed);
if (o.overlay) {
base.$overlay.addClass(n.overlay);
}
base.$smInner.addClass(n.hovered);
base.$wrap.trigger('zoom', base);
}
};
base.update = function() {
// make sure the large image is hidden
if (base.initialized) {
base.showSmall();
}
base.$smInner = (base.$small.find('.' + n.smallInner).length) ?
base.$small.find('.' + n.smallInner) :
base.$small.wrapInner('<span class="' + n.smallInner + '"/>').find('.' + n.smallInner);
base.$small.find('.' + n.overly).remove();
if (o.clone) {
t = base.$smInner.clone()
.removeAttr('id')
.removeClass(n.smallInner)
.addClass(n.largeInner);
if (base.$large.length) {
// large area exists, just add content
base.$large.html(t.html());
} else {
// no large area, so add it
t.wrap('<div class="' + o.largeArea + '">');
base.$small.after(t.parent());
// set base.$large again in case small area was cloned
base.$large = base.$wrap.find('.' + o.largeArea);
}
}
base.$lgInner = (base.$large.find('.' + n.largeInner).length) ?
base.$large.find('.' + n.largeInner) :
base.$large.wrapInner('<span class="' + n.largeInner + '"/>').find('.' + n.largeInner);
if (!base.$wrap.find('.' + n.zoom).length) {
base.$large.wrap('<div class="' + n.zoom + '"/>');
base.$zoom = base.$wrap.find('.' + n.zoom);
}
if (o.edit && !base.edit) {
base.edit = $('<span class="' + n.edit + '"></span>').appendTo(base.$zoom);
}
// wrap inner content with a span to get a more accurate width
// get height from either the inner content itself or the children of the inner content since span will need
// a "display:block" to get an accurate height, but adding that messes up the width
base.$zoom.show();
base.largeDim = [base.$lgInner.children().width(), Math.max(base.$lgInner.height(), base.$lgInner.children().height())];
base.zoomDim = base.last = [base.$zoom.width(), base.$zoom.height()];
base.$zoom.hide();
base.smallDim = [base.$smInner.children().width(), base.$small.height()];
base.$overlay = $('<div class="' + n.overly + '" style="position:absolute;left:0;top:0;" />').prependTo(base.$small);
base.ratio = [
base.largeDim[0] / (base.smallDim[0] || 1),
base.largeDim[1] / (base.smallDim[1] || 1)
];
base.$inner.add(base.$overlay).css({
width: base.smallDim[0],
height: base.smallDim[1]
});
};
// Show small image - Setup
base.showSmall = function() {
base.state = true;
base.$small.show();
base.$zoom
.removeClass(n.expanded)
.addClass(n.windowed + ' ' + n.zoom)
.css({
width: base.zoomDim[0],
height: base.zoomDim[1]
});
base.$inner.css({
width: base.smallDim[0],
height: base.smallDim[1]
});
};
// Switch small and large on double click
base.showLarge = function() {
base.state = false;
base.$small.hide();
base.$zoom
.stop(true, true)
.fadeIn(o.speed)
.addClass(n.expanded)
.removeClass(n.windowed + ' ' + n.zoom)
.css({
height: 'auto',
width: 'auto'
});
base.$inner.css({
width: base.largeDim[0],
height: base.largeDim[1]
});
base.$large.css({
left: 0,
top: 0,
width: base.largeDim[0],
height: base.largeDim[1]
});
};
// x,y coords -> George Washington in image demo
// base.setTarget( 82, 50, [200,200] );
// 'selector', [xOffset, yOffset], [zoomW, zoomH] -> Aug 26 in calendar demo
// base.setTarget( '.day[rel=2009-08-26]', [0, 0], [200, 200] );
base.setTarget = function(tar, sec, sz) {
var t, x = 0,
y = 0;
clearTimeout(base.timer);
if (!base.$zoom.hasClass(n.windowed)) {
base.showSmall();
}
// x, y coords
if (!isNaN(tar) && !isNaN(sec)) {
x = parseInt(tar, 10);
y = parseInt(sec, 10);
} else if (typeof(tar) === 'string' && $(tar).length) {
// '.selector', [xOffSet, yOffSet]
t = $(tar);
x = t.position().left + t.width() / 2 + (sec ? sec[0] || 0 : 0);
y = t.position().top + t.height() / 2 + (sec ? sec[1] || 0 : 0);
}
base.zoomAt(x, y, sz);
// add overlay
if (o.overlay) {
base.$overlay.addClass(n.overlay);
}
// hovered, but not really
base.$smInner.addClass(n.hovered);
// zoom window triggered
base.$wrap.trigger('zoom', base);
};
// x, y, [zoomX, zoomY] - zoomX, zoomY are the dimensions of the zoom window
base.zoomAt = function(x, y, sz, internal) {
var sx = (sz ? sz[0] || 0 : 0) || base.last[0],
sy = (sz ? sz[1] || sz[0] || 0 : 0) || base.last[1],
sx2 = sx / 2,
sy2 = sy / 2,
ex = o.edge || (o.edge === 0 ? 0 : sx2 * 0.66), // 2/3 of zoom window
ey = o.edge || (o.edge === 0 ? 0 : sy2 * 0.66), // allows edge to be zero
m = parseInt(base.$inner.css('margin-left'), 10) || base.$inner.position().left || 0;
// save new zoom size
base.last = [sx, sy];
// save x, y for external access
base.current = [x, y];
// show coordinates
if (o.edit) {
base.edit.html(Math.round(x) + ', ' + Math.round(y));
}
if ((x < -ex) || (x > base.smallDim[0] + ex) || (y < -ey) || (y > base.smallDim[1] + ey)) {
base.hideZoom(internal);
return;
} else {
// Sometimes the mouseenter event is delayed
base.$zoom.stop(true, true).fadeIn(o.speed);
}
// center zoom under the cursor
base.$zoom.css({
left: x - sx2 + m,
top: y - sy2,
width: sx,
height: sy
});
// match locations of small element to the large
base.$large.css({
left: -(x - o.offsetX - sx2 / 2) * base.ratio[0],
top: -(y - o.offsetY - sy2 / 2) * base.ratio[1]
});
};
base.hideZoom = function(internal) {
if (internal && base.$smInner.hasClass(n.hovered)) {
base.$wrap.trigger('unzoom', base);
}
base.last = base.zoomDim;
base.$zoom.stop(true, true).fadeOut(o.speed);
base.$overlay.removeClass(n.overlay);
base.$smInner.removeClass(n.hovered);
base.lastKey = null;
};
base.setEnabled = function(enable) {
base.enabled = enable;
if (enable) {
var off = base.$small.offset();
base.zoomAt(base.position.pageX - off.left, base.position.pageY - off.top, null, true);
} else {
base.showSmall();
base.hideZoom();
base.hovered = false;
}
};
// Initialize zoomer
base.init();
};
// class names used by anythingZoomer
$.anythingZoomer.classNames = {
namespace: '.anythingZoomer', // event namespace
wrap: 'az-wrap',
wrapInner: 'az-wrap-inner',
large: 'az-large',
largeInner: 'az-large-inner',
small: 'az-small',
smallInner: 'az-small-inner',
overlay: 'az-overlay', // toggled class name
overly: 'az-overly', // overlay unstyled class
hovered: 'az-hovered',
zoom: 'az-zoom',
windowed: 'az-windowed', // zoom window active
expanded: 'az-expanded', // zoom window inactive (large is showing)
edit: 'az-coords', // coordinate window
scrollzoom: 'az-scrollzoom'
};
$.anythingZoomer.defaultOptions = {
// content areas
smallArea: 'small', // class of small content area; the element with this class name must be inside of the wrapper
largeArea: 'large', // class of large content area; this class must exist inside of the wrapper. When the clone option is true, it will add this automatically
clone: false, // Make a clone of the small content area, use css to modify the style
// appearance
overlay: false, // set to true to apply overlay class "az-overlay"; false to not apply it
speed: 100, // fade animation speed (in milliseconds)
edge: 30, // How far outside the wrapped edges the mouse can go; previously called "expansionSize"
offsetX: 0, // adjust the horizontal position of the large content inside the zoom window as desired
offsetY: 0, // adjust the vertical position of the large content inside the zoom window as desired
// functionality
switchEvent: 'dblclick', // event that allows toggling between small and large elements - default is double click
delay: 0, // time to delay before revealing the zoom window.
// edit mode
edit: false // add x,y coordinates into zoom window to make it easier to find coordinates
};
$.fn.anythingZoomer = function(options, second, sx, sy) {
return this.each(function() {
var anyZoom = $(this).data('zoomer');
// initialize the zoomer but prevent multiple initializations
if (/object|undefined/.test(typeof options)) {
if (anyZoom) {
anyZoom.update();
} else {
(new $.anythingZoomer(this, options));
}
} else if (anyZoom && (typeof options === 'string' || (!isNaN(options) && !isNaN(second)))) {
if (/(en|dis)able/.test(options)) {
anyZoom.setEnabled(options === 'enable');
} else {
anyZoom.setTarget(options, second, sx, sy);
}
}
});
};
$.fn.getAnythingZoomer = function() {
return this.data('zoomer');
};
return $.anythingzoomer;
}));
/* AnythingZoomer */
.az-wrap,
.az-small,
.az-large {
position: relative;
}
.az-wrap-inner {
display: block;
margin: 0 auto;
/* center small & large content */
}
/* This wraps the large image and hides it */
.az-zoom {
background: #fff;
border: #333 1px solid;
position: absolute;
top: 0;
left: 0;
width: 150px;
height: 150px;
overflow: hidden;
z-index: 100;
display: none;
-moz-box-shadow: inset 0px 0px 4px #000;
-webkit-box-shadow: inset 0px 0px 4px #000;
box-shadow: inset 0px 0px 4px #000;
}
/* Class applied to az-mover when large image is windowed */
.az-windowed {
overflow: hidden;
position: absolute;
}
/* Class applied to az-mover when large image is fully shown */
.az-expanded {
height: auto;
width: auto;
position: static;
overflow: visible;
}
/* overlay small area */
.az-overlay {
background-color: #000;
opacity: 0.3;
filter: alpha(opacity=30);
z-index: 10;
}
/* edit mode coordinate styling */
.az-coords {
display: none;
/* hidden when expanded */
}
.az-zoom .az-coords {
display: block;
position: absolute;
top: 0;
right: 0;
background: #000;
background: rgba(0, 0, 0, 0.5);
color: #fff;
}
/* ZOOM CONTAINER */
.zoom {
display: block;
margin: 0 auto;
}
.large {
background: white;
}
/* FOR TEXT DEMO */
.small p {
font-size: 16px;
width: 700px
}
.large p {
font-size: 32px;
width: 1400px;
}
/* FOR IMAGE DEMO */
.small img {
width: 250px;
}
.large img {
width: 500px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Image and Text Magnifier</title>
<!-- anythingZoomer required -->
<link rel="stylesheet" href="css/anythingzoomer.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="js/jquery.anythingzoomer.js"></script>
<script>
$(function() {
// clone the text
$(".zoom").each(function(){
$(this).anythingZoomer({clone: true});
});
$("button").click(function() {
var state = $(this).text(); // enable or disable
$(".zoom").each(function(){
$(this).anythingZoomer(state);
});
$(this).text((state === "disable") ? "enable" : "disable");
return false;
});
});
</script>
</head>
<body id="double">
<div id="main-content">
<p>Double click within the section to toggle between the large and small versions.</p>
<p><button>disable</button></p>
<p><strong>Text Demo </strong></p>
<div class="zoom">
<div class="small">
<p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae
est. Mauris placerat eleifend leo.</p>
</div>
<!-- the clone option will automatically make a div.large if it doesn't exist -->
</div>
<br>
<p><strong>Image Demo
<div class="zoom second">
<div class="small">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Dean_Franklin_-_06.04.03_Mount_Rushmore_Monument_%28by-sa%29-3_new.jpg/1200px-Dean_Franklin_-_06.04.03_Mount_Rushmore_Monument_%28by-sa%29-3_new.jpg" alt="small rushmore">
</div>
<div class="large">
<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/f3/Dean_Franklin_-_06.04.03_Mount_Rushmore_Monument_%28by-sa%29-3_new.jpg/1200px-Dean_Franklin_-_06.04.03_Mount_Rushmore_Monument_%28by-sa%29-3_new.jpg" alt="big rushmore">
</div>
</div>
</div>
</body>
</html>
Didn't read the code but you could create the zoom using CSS
btn:hover element{
font-size:larger;
}
Related
I am currently constructing a roulette system programme ( this is more to keep me from betting than to bet! ) and am just doing the basic framework but already hit a problem with the main window '#results' not scrolling when it is filled with the results. The scroll needs to follow the latest line of content so the latest returned from the input in the modal box is always showing at the bottom. I have spent hours on lots of possible solutions to no avail.
Here is the code: ( i apologise for the length of the full script )
<!DOCTYPE html>
<html>
<body>
<div id="results">
</div>
<div id="modal">
<div id="modal-content">
<p>Select a number between 0 and 36:</p>
<div id="numberButtons"></div>
<button id="close-button" onclick="closeModal()">Close</button>
</div>
</div>
</div>
<style>
/* The modal background */
#modal {
position: fixed;
z-index: 1;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgba(0, 0, 0, 0.5);
}
/* The modal content */
#modal-content {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
background-color: #fefefe;
padding: 20px;
width: 18%;
border: 3px solid black;
}
/* The close button */
#close-button {
display: block;
margin: 0 auto;
}
#numberButtons button {
color: white;
width: 50px;
height: 50px;
font-size:30px;
font-weight:600;
}
#modal.inactive{
opacity: 0.2;
}
</style>
<script>
var bankRoll = parseFloat(prompt("Please enter your starting bankroll:"));
if(isNaN(bankRoll)){
bankRoll = parseFloat(prompt("Invalid input. Please enter a valid number for your starting bankroll:"));
}
bankRoll = bankRoll.toFixed(2);
var spinNumber=0;
var backline="";
var isDragging = false;
var currentX;
var currentY;
var initialX;
var initialY;
var xOffset = 0;
var yOffset = 0;
const modalContent = document.querySelector("#modal-content");
modalContent.addEventListener("mousedown", dragStart);
modalContent.addEventListener("mouseup", dragEnd);
modalContent.addEventListener("mousemove", drag);
function dragStart(e) {
initialX = e.clientX - xOffset;
initialY = e.clientY - yOffset;
if (e.target === modalContent) {
isDragging = true;
}
}
let inactivityTimeout;
function dragEnd(e) {
initialX = currentX;
initialY = currentY;
isDragging = false;
clearTimeout(inactivityTimeout);
inactivityTimeout = setTimeout(() => {
modal.classList.add("inactive")
}, 15000)
}
function drag(e) {
if (e.buttons === 1) {
e.preventDefault();
currentX = e.clientX - initialX;
currentY = e.clientY - initialY;
xOffset = currentX;
yOffset = currentY;
setTranslate(currentX, currentY, modalContent);
clearTimeout(inactivityTimeout);
modal.classList.remove("inactive")
}
}
function setTranslate(xPos, yPos, el) {
el.style.transform = "translate3d(" + xPos + "px, " + yPos + "px, 0)";
}
function getNumberType(number) {
if (number === 0) {
return "green";
} else if (number % 2 === 0) {
return "even";
} else {
return "odd";
}
}
function roulette(number) {
// Determine the color of the number
var color;
if (number === 0) {
color = "Green";
} else if (number === 1 || number === 3 || number === 5 || number === 7 || number === 9 || number === 12 || number === 14 || number === 16 || number === 18 || number === 19 || number === 21 || number === 23 || number === 25 || number === 27 || number === 30 || number === 32 || number === 34 || number === 36) {
color = "Red";
} else {
color = "Black";
}
// Map the color names to CSS color values
if (color === "Green") {
return "rgb(0, 128, 0)";
} else if (color === "Red") {
return "rgb(255, 0, 0)";
} else {
return "rgb(0, 0, 0)";
}
}
function backgroundline() {
if (spinNumber % 2 === 0) {
backline="#D3D3D3"
} else {
backline="#E5E4E2";
}
}
function spin(number) {
// Determine the color of the number
var color = roulette(number);
spinNumber= spinNumber+1;
bankRoll=bankRoll-10;
backgroundline();
// Display the result
var resultsDiv = document.getElementById("results");
var resultHTML = `${number}`;
resultHTML = `<div style="padding:10px 0; background: ${backline};vertical-align:middle;margin-bottom:- 20px;">
<div style="padding:5px; display: inline-block; background: yellow; color:black;vertical-align:middle; width:30px; text-align:right;">${spinNumber}</div>
<div style="margin: 0 10px; display:inline-block; width: 70px; text-align:center;vertical-align:middle">£ ${bankRoll}</div>
<div style="color: white; padding: 5px; display: inline-block; width:30px; padding-top:15px;vertical-align:middle; font-size: 25px; font-weight:600; height:30px; text-align:center; background-color: ${color}; ">${resultHTML}</div>
</div>
<br style="height:0px;"/>`;
resultsDiv.innerHTML += resultHTML;
}
// Set up the buttons
for (let i = 0; i <= 36; i++) {
let button = document.createElement("button");
button.innerHTML = i;
button.style.backgroundColor = roulette(i);
button.addEventListener("click", function() {
spin(i);
});
document.getElementById("numberButtons").appendChild(button);
}
function closeModal() {
// Get the modal element
var modal = document.getElementById("modal");
// Remove the modal element from the DOM
modal.remove();
}
</script>
</body>
</html>
I have tried lots of solutions on Stack Overflow and across the Internet further field that I thought might work but it just doesn't seem to want to do it.
after adding element in Results div you have to call this function.
add this function
window.scrollTo(0, document.body.scrollHeight)
after this line
resultsDiv.innerHTML += resultHTML;
I want to apply magnifying glass and lightbox both on an image so when a user hovers on an image the glass effect will appear and when he clicks the lightbox will appear. But in my case the lightbox stopped working when I actived the magnifying glass. So when I remove the glass CSS lightbox worked normally.
/*!
* Lightbox v2.10.0
* by Lokesh Dhakar
*
* More info:
* http://lokeshdhakar.com/projects/lightbox2/
*
* Copyright 2007, 2018 Lokesh Dhakar
* Released under the MIT license
* https://github.com/lokesh/lightbox2/blob/master/LICENSE
*
* #preserve
*/
! function(a, b) {
"function" == typeof define && define.amd ? define(["jquery"], b) : "object" == typeof exports ? module.exports = b(require("jquery")) : a.lightbox = b(a.jQuery)
}(this, function(a) {
function b(b) {
this.album = [], this.currentImageIndex = void 0, this.init(), this.options = a.extend({}, this.constructor.defaults), this.option(b)
}
return b.defaults = {
albumLabel: "Image %1 of %2",
alwaysShowNavOnTouchDevices: !1,
fadeDuration: 600,
fitImagesInViewport: !0,
imageFadeDuration: 600,
positionFromTop: 50,
resizeDuration: 700,
showImageNumberLabel: !0,
wrapAround: !1,
disableScrolling: !1,
sanitizeTitle: !1
}, b.prototype.option = function(b) {
a.extend(this.options, b)
}, b.prototype.imageCountLabel = function(a, b) {
return this.options.albumLabel.replace(/%1/g, a).replace(/%2/g, b)
}, b.prototype.init = function() {
var b = this;
a(document).ready(function() {
b.enable(), b.build()
})
}, b.prototype.enable = function() {
var b = this;
a("body").on("click", "a[rel^=lightbox], area[rel^=lightbox], a[data-lightbox], area[data-lightbox]", function(c) {
return b.start(a(c.currentTarget)), !1
})
}, b.prototype.build = function() {
if (!(a("#lightbox").length > 0)) {
var b = this;
a('<div id="lightboxOverlay" class="lightboxOverlay"></div><div id="lightbox" class="lightbox"><div class="lb-outerContainer"><div class="lb-container"><img class="lb-image" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" /><div class="lb-nav"><a class="lb-prev" href="" ></a><a class="lb-next" href="" ></a></div><div class="lb-loader"><a class="lb-cancel"></a></div></div></div><div class="lb-dataContainer"><div class="lb-data"><div class="lb-details"><span class="lb-caption"></span><span class="lb-number"></span></div><div class="lb-closeContainer"><a class="lb-close"></a></div></div></div></div>').appendTo(a("body")), this.$lightbox = a("#lightbox"), this.$overlay = a("#lightboxOverlay"), this.$outerContainer = this.$lightbox.find(".lb-outerContainer"), this.$container = this.$lightbox.find(".lb-container"), this.$image = this.$lightbox.find(".lb-image"), this.$nav = this.$lightbox.find(".lb-nav"), this.containerPadding = {
top: parseInt(this.$container.css("padding-top"), 10),
right: parseInt(this.$container.css("padding-right"), 10),
bottom: parseInt(this.$container.css("padding-bottom"), 10),
left: parseInt(this.$container.css("padding-left"), 10)
}, this.imageBorderWidth = {
top: parseInt(this.$image.css("border-top-width"), 10),
right: parseInt(this.$image.css("border-right-width"), 10),
bottom: parseInt(this.$image.css("border-bottom-width"), 10),
left: parseInt(this.$image.css("border-left-width"), 10)
}, this.$overlay.hide().on("click", function() {
return b.end(), !1
}), this.$lightbox.hide().on("click", function(c) {
return "lightbox" === a(c.target).attr("id") && b.end(), !1
}), this.$outerContainer.on("click", function(c) {
return "lightbox" === a(c.target).attr("id") && b.end(), !1
}), this.$lightbox.find(".lb-prev").on("click", function() {
return 0 === b.currentImageIndex ? b.changeImage(b.album.length - 1) : b.changeImage(b.currentImageIndex - 1), !1
}), this.$lightbox.find(".lb-next").on("click", function() {
return b.currentImageIndex === b.album.length - 1 ? b.changeImage(0) : b.changeImage(b.currentImageIndex + 1), !1
}), this.$nav.on("mousedown", function(a) {
3 === a.which && (b.$nav.css("pointer-events", "none"), b.$lightbox.one("contextmenu", function() {
setTimeout(function() {
this.$nav.css("pointer-events", "auto")
}.bind(b), 0)
}))
}), this.$lightbox.find(".lb-loader, .lb-close").on("click", function() {
return b.end(), !1
})
}
}, b.prototype.start = function(b) {
function c(a) {
d.album.push({
alt: a.attr("data-alt"),
link: a.attr("href"),
title: a.attr("data-title") || a.attr("title")
})
}
var d = this,
e = a(window);
e.on("resize", a.proxy(this.sizeOverlay, this)), a("select, object, embed").css({
visibility: "hidden"
}), this.sizeOverlay(), this.album = [];
var f, g = 0,
h = b.attr("data-lightbox");
if (h) {
f = a(b.prop("tagName") + '[data-lightbox="' + h + '"]');
for (var i = 0; i < f.length; i = ++i) c(a(f[i])), f[i] === b[0] && (g = i)
} else if ("lightbox" === b.attr("rel")) c(b);
else {
f = a(b.prop("tagName") + '[rel="' + b.attr("rel") + '"]');
for (var j = 0; j < f.length; j = ++j) c(a(f[j])), f[j] === b[0] && (g = j)
}
var k = e.scrollTop() + this.options.positionFromTop,
l = e.scrollLeft();
this.$lightbox.css({
top: k + "px",
left: l + "px"
}).fadeIn(this.options.fadeDuration), this.options.disableScrolling && a("html").addClass("lb-disable-scrolling"), this.changeImage(g)
}, b.prototype.changeImage = function(b) {
var c = this;
this.disableKeyboardNav();
var d = this.$lightbox.find(".lb-image");
this.$overlay.fadeIn(this.options.fadeDuration), a(".lb-loader").fadeIn("slow"), this.$lightbox.find(".lb-image, .lb-nav, .lb-prev, .lb-next, .lb-dataContainer, .lb-numbers, .lb-caption").hide(), this.$outerContainer.addClass("animating");
var e = new Image;
e.onload = function() {
var f, g, h, i, j, k;
d.attr({
alt: c.album[b].alt,
src: c.album[b].link
}), a(e), d.width(e.width), d.height(e.height), c.options.fitImagesInViewport && (k = a(window).width(), j = a(window).height(), i = k - c.containerPadding.left - c.containerPadding.right - c.imageBorderWidth.left - c.imageBorderWidth.right - 20, h = j - c.containerPadding.top - c.containerPadding.bottom - c.imageBorderWidth.top - c.imageBorderWidth.bottom - 120, c.options.maxWidth && c.options.maxWidth < i && (i = c.options.maxWidth), c.options.maxHeight && c.options.maxHeight < i && (h = c.options.maxHeight), (e.width > i || e.height > h) && (e.width / i > e.height / h ? (g = i, f = parseInt(e.height / (e.width / g), 10), d.width(g), d.height(f)) : (f = h, g = parseInt(e.width / (e.height / f), 10), d.width(g), d.height(f)))), c.sizeContainer(d.width(), d.height())
}, e.src = this.album[b].link, this.currentImageIndex = b
}, b.prototype.sizeOverlay = function() {
this.$overlay.width(a(document).width()).height(a(document).height())
}, b.prototype.sizeContainer = function(a, b) {
function c() {
d.$lightbox.find(".lb-dataContainer").width(g), d.$lightbox.find(".lb-prevLink").height(h), d.$lightbox.find(".lb-nextLink").height(h), d.showImage()
}
var d = this,
e = this.$outerContainer.outerWidth(),
f = this.$outerContainer.outerHeight(),
g = a + this.containerPadding.left + this.containerPadding.right + this.imageBorderWidth.left + this.imageBorderWidth.right,
h = b + this.containerPadding.top + this.containerPadding.bottom + this.imageBorderWidth.top + this.imageBorderWidth.bottom;
e !== g || f !== h ? this.$outerContainer.animate({
width: g,
height: h
}, this.options.resizeDuration, "swing", function() {
c()
}) : c()
}, b.prototype.showImage = function() {
this.$lightbox.find(".lb-loader").stop(!0).hide(), this.$lightbox.find(".lb-image").fadeIn(this.options.imageFadeDuration), this.updateNav(), this.updateDetails(), this.preloadNeighboringImages(), this.enableKeyboardNav()
}, b.prototype.updateNav = function() {
var a = !1;
try {
document.createEvent("TouchEvent"), a = !!this.options.alwaysShowNavOnTouchDevices
} catch (a) {}
this.$lightbox.find(".lb-nav").show(), this.album.length > 1 && (this.options.wrapAround ? (a && this.$lightbox.find(".lb-prev, .lb-next").css("opacity", "1"), this.$lightbox.find(".lb-prev, .lb-next").show()) : (this.currentImageIndex > 0 && (this.$lightbox.find(".lb-prev").show(), a && this.$lightbox.find(".lb-prev").css("opacity", "1")), this.currentImageIndex < this.album.length - 1 && (this.$lightbox.find(".lb-next").show(), a && this.$lightbox.find(".lb-next").css("opacity", "1"))))
}, b.prototype.updateDetails = function() {
var b = this;
if (void 0 !== this.album[this.currentImageIndex].title && "" !== this.album[this.currentImageIndex].title) {
var c = this.$lightbox.find(".lb-caption");
this.options.sanitizeTitle ? c.text(this.album[this.currentImageIndex].title) : c.html(this.album[this.currentImageIndex].title), c.fadeIn("fast").find("a").on("click", function(b) {
void 0 !== a(this).attr("target") ? window.open(a(this).attr("href"), a(this).attr("target")) : location.href = a(this).attr("href")
})
}
if (this.album.length > 1 && this.options.showImageNumberLabel) {
var d = this.imageCountLabel(this.currentImageIndex + 1, this.album.length);
this.$lightbox.find(".lb-number").text(d).fadeIn("fast")
} else this.$lightbox.find(".lb-number").hide();
this.$outerContainer.removeClass("animating"), this.$lightbox.find(".lb-dataContainer").fadeIn(this.options.resizeDuration, function() {
return b.sizeOverlay()
})
}, b.prototype.preloadNeighboringImages = function() {
if (this.album.length > this.currentImageIndex + 1) {
(new Image).src = this.album[this.currentImageIndex + 1].link
}
if (this.currentImageIndex > 0) {
(new Image).src = this.album[this.currentImageIndex - 1].link
}
}, b.prototype.enableKeyboardNav = function() {
a(document).on("keyup.keyboard", a.proxy(this.keyboardAction, this))
}, b.prototype.disableKeyboardNav = function() {
a(document).off(".keyboard")
}, b.prototype.keyboardAction = function(a) {
var b = a.keyCode,
c = String.fromCharCode(b).toLowerCase();
27 === b || c.match(/x|o|c/) ? this.end() : "p" === c || 37 === b ? 0 !== this.currentImageIndex ? this.changeImage(this.currentImageIndex - 1) : this.options.wrapAround && this.album.length > 1 && this.changeImage(this.album.length - 1) : "n" !== c && 39 !== b || (this.currentImageIndex !== this.album.length - 1 ? this.changeImage(this.currentImageIndex + 1) : this.options.wrapAround && this.album.length > 1 && this.changeImage(0))
}, b.prototype.end = function() {
this.disableKeyboardNav(), a(window).off("resize", this.sizeOverlay), this.$lightbox.fadeOut(this.options.fadeDuration), this.$overlay.fadeOut(this.options.fadeDuration), a("select, object, embed").css({
visibility: "visible"
}), this.options.disableScrolling && a("html").removeClass("lb-disable-scrolling")
}, new b
});
//# sourceMappingURL=lightbox.min.map
//magnyfing glass
$(function() {
var native_width = 0;
var native_height = 0;
var mouse = {
x: 0,
y: 0
};
var magnify;
var cur_img;
var ui = {
magniflier: $('.magniflier')
};
// Add the magnifying glass
if (ui.magniflier.length) {
var div = document.createElement('div');
div.setAttribute('class', 'glass');
ui.glass = $(div);
$('body').append(div);
}
// All the magnifying will happen on "mousemove"
var mouseMove = function(e) {
var $el = $(this);
// Container offset relative to document
var magnify_offset = cur_img.offset();
// Mouse position relative to container
// pageX/pageY - container's offsetLeft/offetTop
mouse.x = e.pageX - magnify_offset.left;
mouse.y = e.pageY - magnify_offset.top;
// The Magnifying glass should only show up when the mouse is inside
// It is important to note that attaching mouseout and then hiding
// the glass wont work cuz mouse will never be out due to the glass
// being inside the parent and having a higher z-index (positioned above)
if (
mouse.x < cur_img.width() &&
mouse.y < cur_img.height() &&
mouse.x > 0 &&
mouse.y > 0
) {
magnify(e);
} else {
ui.glass.fadeOut(100);
}
return;
};
var magnify = function(e) {
// The background position of div.glass will be
// changed according to the position
// of the mouse over the img.magniflier
//
// So we will get the ratio of the pixel
// under the mouse with respect
// to the image and use that to position the
// large image inside the magnifying glass
var rx = Math.round(mouse.x / cur_img.width() * native_width - ui.glass.width() / 2) * -1;
var ry = Math.round(mouse.y / cur_img.height() * native_height - ui.glass.height() / 2) * -1;
var bg_pos = rx + "px " + ry + "px";
// Calculate pos for magnifying glass
//
// Easy Logic: Deduct half of width/height
// from mouse pos.
// var glass_left = mouse.x - ui.glass.width() / 2;
// var glass_top = mouse.y - ui.glass.height() / 2;
var glass_left = e.pageX - ui.glass.width() / 2;
var glass_top = e.pageY - ui.glass.height() / 2;
//console.log(glass_left, glass_top, bg_pos)
// Now, if you hover on the image, you should
// see the magnifying glass in action
ui.glass.css({
left: glass_left,
top: glass_top,
backgroundPosition: bg_pos
});
return;
};
$('.magniflier').on('mousemove', function() {
ui.glass.fadeIn(200);
cur_img = $(this);
var large_img_loaded = cur_img.data('large-img-loaded');
var src = cur_img.data('large') || cur_img.attr('src');
// Set large-img-loaded to true
// cur_img.data('large-img-loaded', true)
if (src) {
ui.glass.css({
'background-image': 'url(' + src + ')',
'background-repeat': 'no-repeat'
});
}
// When the user hovers on the image, the script will first calculate
// the native dimensions if they don't exist. Only after the native dimensions
// are available, the script will show the zoomed version.
//if(!native_width && !native_height) {
if (!cur_img.data('native_width')) {
// This will create a new image object with the same image as that in .small
// We cannot directly get the dimensions from .small because of the
// width specified to 200px in the html. To get the actual dimensions we have
// created this image object.
var image_object = new Image();
image_object.onload = function() {
// This code is wrapped in the .load function which is important.
// width and height of the object would return 0 if accessed before
// the image gets loaded.
native_width = image_object.width;
native_height = image_object.height;
cur_img.data('native_width', native_width);
cur_img.data('native_height', native_height);
//console.log(native_width, native_height);
mouseMove.apply(this, arguments);
ui.glass.on('mousemove', mouseMove);
};
image_object.src = src;
return;
} else {
native_width = cur_img.data('native_width');
native_height = cur_img.data('native_height');
}
//}
//console.log(native_width, native_height);
mouseMove.apply(this, arguments);
ui.glass.on('mousemove', mouseMove);
});
ui.glass.on('mouseout', function() {
ui.glass.off('mousemove', mouseMove);
});
});
html.lb-disable-scrolling {
overflow: hidden;
/* Position fixed required for iOS. Just putting overflow: hidden; on the body is not enough. */
position: fixed;
height: 100vh;
width: 100vw;
}
.lightboxOverlay {
position: absolute;
top: 0;
left: 0;
z-index: 9999;
background-color: black;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);
opacity: 0.8;
display: none;
}
.lightbox {
position: absolute;
left: 0;
width: 100%;
z-index: 10000;
text-align: center;
line-height: 0;
font-weight: normal;
}
.lightbox .lb-image {
display: block;
height: auto;
max-width: inherit;
max-height: none;
border-radius: 3px;
/* Image border */
border: 4px solid white;
}
.lightbox a img {
border: none;
}
.lb-outerContainer {
position: relative;
*zoom: 1;
width: 250px;
height: 250px;
margin: 0 auto;
border-radius: 4px;
/* Background color behind image.
This is visible during transitions. */
background-color: white;
}
.lb-outerContainer:after {
content: "";
display: table;
clear: both;
}
.lb-loader {
position: absolute;
top: 43%;
left: 0;
height: 25%;
width: 100%;
text-align: center;
line-height: 0;
}
.lb-cancel {
display: block;
width: 32px;
height: 32px;
margin: 0 auto;
background: url(../assets/imgs/lightbox/loading.gif) no-repeat;
}
.lb-nav {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 10;
}
.lb-container>.nav {
left: 0;
}
.lb-nav a {
outline: none;
background-image: url('data:image/gif;base64,R0lGODlhAQABAPAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==');
}
.lb-prev,
.lb-next {
height: 100%;
cursor: pointer;
display: block;
}
.lb-nav a.lb-prev {
width: 34%;
left: 0;
float: left;
background: url(../assets/imgs/lightbox/prev.png) left 48% no-repeat;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
-webkit-transition: opacity 0.6s;
-moz-transition: opacity 0.6s;
-o-transition: opacity 0.6s;
transition: opacity 0.6s;
}
.lb-nav a.lb-prev:hover {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
.lb-nav a.lb-next {
width: 64%;
right: 0;
float: right;
background: url(../assets/imgs/lightbox/next.png) right 48% no-repeat;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=0);
opacity: 0;
-webkit-transition: opacity 0.6s;
-moz-transition: opacity 0.6s;
-o-transition: opacity 0.6s;
transition: opacity 0.6s;
}
.lb-nav a.lb-next:hover {
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
.lb-dataContainer {
margin: 0 auto;
padding-top: 5px;
*zoom: 1;
width: 100%;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
.lb-dataContainer:after {
content: "";
display: table;
clear: both;
}
.lb-data {
padding: 0 4px;
color: #ccc;
}
.lb-data .lb-details {
width: 85%;
float: left;
text-align: left;
line-height: 1.1em;
}
.lb-data .lb-caption {
font-size: 13px;
font-weight: bold;
line-height: 1em;
}
.lb-data .lb-caption a {
color: #4ae;
}
.lb-data .lb-number {
display: block;
clear: left;
padding-bottom: 1em;
font-size: 12px;
color: #999999;
}
.lb-data .lb-close {
display: block;
float: right;
width: 30px;
height: 30px;
background: url(../assets/imgs/lightbox/close.png) top right no-repeat;
text-align: right;
outline: none;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
opacity: 0.7;
-webkit-transition: opacity 0.2s;
-moz-transition: opacity 0.2s;
-o-transition: opacity 0.2s;
transition: opacity 0.2s;
}
.lb-data .lb-close:hover {
cursor: pointer;
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);
opacity: 1;
}
/* IF you remove this, lightbox will work but not the magnyfing glass */
.glass {
width: 150px;
height: 150px;
position: absolute;
border-radius: 50%;
cursor: crosshair;
/* Multiple box shadows to achieve the glass effect */
box-shadow: 0 0 0 7px rgba(255, 255, 255, 0.85), 0 0 7px 7px rgba(0, 0, 0, 0.25), inset 0 0 40px 2px rgba(0, 0, 0, 0.25);
/* hide the glass by default */
display: none;
}
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--START BOOK PREVIEW-->
<div class="book-preview px-5 py-5 container img-magnifier-container">
<div class="row">
<div class="col-lg-4 book">
<a href="https://subsolardesigns.com/odrin/demo1/wp-content/uploads/sites/8/2017/08/cover_taurus-468x700.png" data-lightbox="image-1" data-title="My caption">
<img src="https://subsolardesigns.com/odrin/demo1/wp-content/uploads/sites/8/2017/08/cover_taurus-468x700.png" alt="Book" class="img-fluid magniflier" id="book-glass" alt="Responsive image">
</a>
</div>
</div>
</div>
The issue is that you are not clicking the image, but the .glass dom node. You need to handle the click event on the .glass element and then call click on the image, in order for the lightbox plugin to do what it expects to do. Add the code below to you javascript to redirect the click event to your image tag.
ui.glass.on('click', function() {
cur_img.click();
});
I am using the lightbox jquery plugin to open a lightbox when a user clicks on a product. Often the lightbox content stretches below the fold, and at the moment the right scrollbar moves the entire page when you scroll down.
I'd like it to work like the pinterest lightbox, whereby the right scrollbar only scrolls the lightbox, and the rest of the page stays fixed. I've seen a few posts on this, but nothing seems to work for me.
Problem is I want the lightbox to scroll if the content is bigger than the viewport of the browser but not the background.
CSS:
#lightbox{ position: absolute; left: 0; width: 100%; z-index: 100; text-align: center; line-height: 0;}
#lightbox img{ width: auto; height: auto;}
#lightbox a img{ border: none; }
#outerImageContainer{ position: relative; background-color: #fff; width: 250px; height: 250px; margin: 0 auto; }
#imageContainer{ padding: 10px; }
#loading{ position: absolute; top: 40%; left: 0%; height: 25%; width: 100%; text-align: center; line-height: 0; }
#hoverNav{ position: absolute; top: 0; left: 0; height: 100%; width: 100%; z-index: 10; }
#imageContainer>#hoverNav{ left: 0;}
#hoverNav a{ outline: none;}
#prevLink, #nextLink{ width: 49%; height: 100%; background-image: url(data:image2/gif;base64,AAAA); /* Trick IE into showing hover */ display: block; }
#prevLink { left: 0; float: left;}
#nextLink { right: 0; float: right;}
#prevLink:hover, #prevLink:visited:hover { background: url(../images2/prevlabel.gif) left 15% no-repeat; }
#nextLink:hover, #nextLink:visited:hover { background: url(../images2/nextlabel.gif) right 15% no-repeat; }
#imageDataContainer{ font: 10px Verdana, Helvetica, sans-serif; background-color: #fff; margin: 0 auto; line-height: 1.4em; overflow: auto; width: 100% ; }
#imageData{ padding:0 10px; color: #666; }
#imageData #imageDetails{ width: 70%; float: left; text-align: left; }
#imageData #caption{ font-weight: bold; }
#imageData #numberDisplay{ display: block; clear: left; padding-bottom: 1.0em; }
#imageData #bottomNavClose{ width: 66px; float: right; padding-bottom: 0.7em; outline: none;}
#overlay{ position: absolute; top: 0; left: 0; z-index: 90; width: 100%; height: 500px; background-color: #000; }
JS:
// -----------------------------------------------------------------------------------
//
// Lightbox v2.04
// by Lokesh Dhakar - http://www.lokeshdhakar.com
// Last Modification: 2/9/08
//
// For more information, visit:
// http://lokeshdhakar.com/projects/lightbox2/
//
// Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
// - Free for use in both personal and commercial projects
// - Attribution requires leaving author name, author link, and the license info intact.
//
// Thanks: Scott Upton(uptonic.com), Peter-Paul Koch(quirksmode.com), and Thomas Fuchs(mir.aculo.us) for ideas, libs, and snippets.
// Artemy Tregubenko (arty.name) for cleanup and help in updating to latest ver of proto-aculous.
//
// -----------------------------------------------------------------------------------
/*
Table of Contents
-----------------
Configuration
Lightbox Class Declaration
- initialize()
- updateImageList()
- start()
- changeImage()
- resizeImageContainer()
- showImage()
- updateDetails()
- updateNav()
- enableKeyboardNav()
- disableKeyboardNav()
- keyboardAction()
- preloadNeighborImages()
- end()
Function Calls
- document.observe()
*/
// -----------------------------------------------------------------------------------
//
// Configurationl
//
LightboxOptions = Object.extend({
fileLoadingImage: 'images2/loading.gif',
fileBottomNavCloseImage: 'images2/closelabel.gif',
overlayOpacity: 0.8, // controls transparency of shadow overlay
animate: true, // toggles resizing animations
resizeSpeed: 7, // controls the speed of the image resizing animations (1=slowest and 10=fastest)
borderSize: 10, //if you adjust the padding in the CSS, you will need to update this variable
// When grouping images this is used to write: Image # of #.
// Change it for non-english localization
labelImage: "Image",
labelOf: "of"
}, window.LightboxOptions || {});
// -----------------------------------------------------------------------------------
var Lightbox = Class.create();
Lightbox.prototype = {
imageArray: [],
activeImage: undefined,
// initialize()
// Constructor runs on completion of the DOM loading. Calls updateImageList and then
// the function inserts html at the bottom of the page which is used to display the shadow
// overlay and the image container.
//
initialize: function() {
this.updateImageList();
this.keyboardAction = this.keyboardAction.bindAsEventListener(this);
if (LightboxOptions.resizeSpeed > 10) LightboxOptions.resizeSpeed = 10;
if (LightboxOptions.resizeSpeed < 1) LightboxOptions.resizeSpeed = 1;
this.resizeDuration = LightboxOptions.animate ? ((11 - LightboxOptions.resizeSpeed) * 0.15) : 0;
this.overlayDuration = LightboxOptions.animate ? 0.2 : 0; // shadow fade in/out duration
// When Lightbox starts it will resize itself from 250 by 250 to the current image dimension.
// If animations are turned off, it will be hidden as to prevent a flicker of a
// white 250 by 250 box.
var size = (LightboxOptions.animate ? 250 : 1) + 'px';
// Code inserts html at the bottom of the page that looks similar to this:
//
// <div id="overlay"></div>
// <div id="lightbox">
// <div id="outerImageContainer">
// <div id="imageContainer">
// <img id="lightboxImage">
// <div style="" id="hoverNav">
//
//
// </div>
// <div id="loading">
// <a href="#" id="loadingLink">
// <img src="images/loading.gif">
// </a>
// </div>
// </div>
// </div>
// <div id="imageDataContainer">
// <div id="imageData">
// <div id="imageDetails">
// <span id="caption"></span>
// <span id="numberDisplay"></span>
// </div>
// <div id="bottomNav">
// <a href="#" id="bottomNavClose">
// <img src="images/close.gif">
// </a>
// </div>
// </div>
// </div>
// </div>
var objBody = $$('body')[0];
objBody.appendChild(Builder.node('div',{id:'overlay'}));
objBody.appendChild(Builder.node('div',{id:'lightbox'}, [
Builder.node('div',{id:'outerImageContainer'},
Builder.node('div',{id:'imageContainer'}, [
Builder.node('img',{id:'lightboxImage'}),
Builder.node('div',{id:'hoverNav'}, [
Builder.node('a',{id:'prevLink', href: '#' }),
Builder.node('a',{id:'nextLink', href: '#' })
]),
Builder.node('div',{id:'loading'},
Builder.node('a',{id:'loadingLink', href: '#' },
Builder.node('img', {src: LightboxOptions.fileLoadingImage})
)
)
])
),
Builder.node('div', {id:'imageDataContainer'},
Builder.node('div',{id:'imageData'}, [
Builder.node('div',{id:'imageDetails'}, [
Builder.node('span',{id:'caption'}),
Builder.node('span',{id:'numberDisplay'})
]),
Builder.node('div',{id:'bottomNav'},
Builder.node('a',{id:'bottomNavClose', href: '#' },
Builder.node('img', { src: LightboxOptions.fileBottomNavCloseImage })
)
)
])
)
]));
$('overlay').hide().observe('click', (function() { this.end(); }).bind(this));
$('lightbox').hide().observe('click', (function(event) { if (event.element().id == 'lightbox') this.end(); }).bind(this));
$('outerImageContainer').setStyle({ width: size, height: size });
$('prevLink').observe('click', (function(event) { event.stop(); this.changeImage(this.activeImage - 1); }).bindAsEventListener(this));
$('nextLink').observe('click', (function(event) { event.stop(); this.changeImage(this.activeImage + 1); }).bindAsEventListener(this));
$('loadingLink').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));
$('bottomNavClose').observe('click', (function(event) { event.stop(); this.end(); }).bind(this));
var th = this;
(function(){
var ids =
'overlay lightbox outerImageContainer imageContainer lightboxImage hoverNav prevLink nextLink loading loadingLink ' +
'imageDataContainer imageData imageDetails caption numberDisplay bottomNav bottomNavClose';
$w(ids).each(function(id){ th[id] = $(id); });
}).defer();
},
//
// updateImageList()
// Loops through anchor tags looking for 'lightbox' references and applies onclick
// events to appropriate links. You can rerun after dynamically adding images w/ajax.
//
updateImageList: function() {
this.updateImageList = Prototype.emptyFunction;
document.observe('click', (function(event){
var target = event.findElement('a[rel^=lightbox]') || event.findElement('area[rel^=lightbox]');
if (target) {
event.stop();
this.start(target);
}
}).bind(this));
},
//
// start()
// Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
//
start: function(imageLink) {
$$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });
// stretch overlay to fill page and fade in
var arrayPageSize = this.getPageSize();
$('overlay').setStyle({ width: arrayPageSize[0] + 'px', height: arrayPageSize[1] + 'px' });
new Effect.Appear(this.overlay, { duration: this.overlayDuration, from: 0.0, to: LightboxOptions.overlayOpacity });
this.imageArray = [];
var imageNum = 0;
if ((imageLink.rel == 'lightbox')){
// if image is NOT part of a set, add single image to imageArray
this.imageArray.push([imageLink.href, imageLink.title]);
} else {
// if image is part of a set..
this.imageArray =
$$(imageLink.tagName + '[href][rel="' + imageLink.rel + '"]').
collect(function(anchor){ return [anchor.href, anchor.title]; }).
uniq();
while (this.imageArray[imageNum][0] != imageLink.href) { imageNum++; }
}
// calculate top and left offset for the lightbox
var arrayPageScroll = document.viewport.getScrollOffsets();
var lightboxTop = arrayPageScroll[1] + (document.viewport.getHeight() / 10);
var lightboxLeft = arrayPageScroll[0];
this.lightbox.setStyle({ top: lightboxTop + 'px', left: lightboxLeft + 'px' }).show();
this.changeImage(imageNum);
},
//
// changeImage()
// Hide most elements and preload image in preparation for resizing image container.
//
changeImage: function(imageNum) {
this.activeImage = imageNum; // update global var
// hide elements during transition
if (LightboxOptions.animate) this.loading.show();
this.lightboxImage.hide();
this.hoverNav.hide();
this.prevLink.hide();
this.nextLink.hide();
// HACK: Opera9 does not currently support scriptaculous opacity and appear fx
this.imageDataContainer.setStyle({opacity: .0001});
this.numberDisplay.hide();
var imgPreloader = new Image();
// once image is preloaded, resize image container
imgPreloader.onload = (function(){
this.lightboxImage.src = this.imageArray[this.activeImage][0];
this.resizeImageContainer(imgPreloader.width, imgPreloader.height);
}).bind(this);
imgPreloader.src = this.imageArray[this.activeImage][0];
},
//
// resizeImageContainer()
//
resizeImageContainer: function(imgWidth, imgHeight) {
// get current width and height
var widthCurrent = this.outerImageContainer.getWidth();
var heightCurrent = this.outerImageContainer.getHeight();
// get new width and height
var widthNew = (imgWidth + LightboxOptions.borderSize * 2);
var heightNew = (imgHeight + LightboxOptions.borderSize * 2);
// scalars based on change from old to new
var xScale = (widthNew / widthCurrent) * 100;
var yScale = (heightNew / heightCurrent) * 100;
// calculate size difference between new and old image, and resize if necessary
var wDiff = widthCurrent - widthNew;
var hDiff = heightCurrent - heightNew;
if (hDiff != 0) new Effect.Scale(this.outerImageContainer, yScale, {scaleX: false, duration: this.resizeDuration, queue: 'front'});
if (wDiff != 0) new Effect.Scale(this.outerImageContainer, xScale, {scaleY: false, duration: this.resizeDuration, delay: this.resizeDuration});
// if new and old image are same size and no scaling transition is necessary,
// do a quick pause to prevent image flicker.
var timeout = 0;
if ((hDiff == 0) && (wDiff == 0)){
timeout = 100;
if (Prototype.Browser.IE) timeout = 250;
}
(function(){
this.prevLink.setStyle({ height: imgHeight + 'px' });
this.nextLink.setStyle({ height: imgHeight + 'px' });
this.imageDataContainer.setStyle({ width: widthNew + 'px' });
this.showImage();
}).bind(this).delay(timeout / 1000);
},
//
// showImage()
// Display image and begin preloading neighbors.
//
showImage: function(){
this.loading.hide();
new Effect.Appear(this.lightboxImage, {
duration: this.resizeDuration,
queue: 'end',
afterFinish: (function(){ this.updateDetails(); }).bind(this)
});
this.preloadNeighborImages();
},
//
// updateDetails()
// Display caption, image number, and bottom nav.
//
updateDetails: function() {
// if caption is not null
if (this.imageArray[this.activeImage][1] != ""){
this.caption.update(this.imageArray[this.activeImage][1]).show();
}
// if image is part of set display 'Image x of x'
if (this.imageArray.length > 1){
this.numberDisplay.update( LightboxOptions.labelImage + ' ' + (this.activeImage + 1) + ' ' + LightboxOptions.labelOf + ' ' + this.imageArray.length).show();
}
new Effect.Parallel(
[
new Effect.SlideDown(this.imageDataContainer, { sync: true, duration: this.resizeDuration, from: 0.0, to: 1.0 }),
new Effect.Appear(this.imageDataContainer, { sync: true, duration: this.resizeDuration })
],
{
duration: this.resizeDuration,
afterFinish: (function() {
// update overlay size and update nav
var arrayPageSize = this.getPageSize();
this.overlay.setStyle({ height: arrayPageSize[1] + 'px' });
this.updateNav();
}).bind(this)
}
);
},
//
// updateNav()
// Display appropriate previous and next hover navigation.
//
updateNav: function() {
this.hoverNav.show();
// if not first image in set, display prev image button
if (this.activeImage > 0) this.prevLink.show();
// if not last image in set, display next image button
if (this.activeImage < (this.imageArray.length - 1)) this.nextLink.show();
this.enableKeyboardNav();
},
//
// enableKeyboardNav()
//
enableKeyboardNav: function() {
document.observe('keydown', this.keyboardAction);
},
//
// disableKeyboardNav()
//
disableKeyboardNav: function() {
document.stopObserving('keydown', this.keyboardAction);
},
//
// keyboardAction()
//
keyboardAction: function(event) {
var keycode = event.keyCode;
var escapeKey;
if (event.DOM_VK_ESCAPE) { // mozilla
escapeKey = event.DOM_VK_ESCAPE;
} else { // ie
escapeKey = 27;
}
var key = String.fromCharCode(keycode).toLowerCase();
if (key.match(/x|o|c/) || (keycode == escapeKey)){ // close lightbox
this.end();
} else if ((key == 'p') || (keycode == 37)){ // display previous image
if (this.activeImage != 0){
this.disableKeyboardNav();
this.changeImage(this.activeImage - 1);
}
} else if ((key == 'n') || (keycode == 39)){ // display next image
if (this.activeImage != (this.imageArray.length - 1)){
this.disableKeyboardNav();
this.changeImage(this.activeImage + 1);
}
}
},
//
// preloadNeighborImages()
// Preload previous and next images.
//
preloadNeighborImages: function(){
var preloadNextImage, preloadPrevImage;
if (this.imageArray.length > this.activeImage + 1){
preloadNextImage = new Image();
preloadNextImage.src = this.imageArray[this.activeImage + 1][0];
}
if (this.activeImage > 0){
preloadPrevImage = new Image();
preloadPrevImage.src = this.imageArray[this.activeImage - 1][0];
}
},
//
// end()
//
end: function() {
this.disableKeyboardNav();
this.lightbox.hide();
new Effect.Fade(this.overlay, { duration: this.overlayDuration });
$$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'visible' });
},
//
// getPageSize()
//
getPageSize: function() {
var xScroll, yScroll;
if (window.innerHeight && window.scrollMaxY) {
xScroll = window.innerWidth + window.scrollMaxX;
yScroll = window.innerHeight + window.scrollMaxY;
} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
xScroll = document.body.scrollWidth;
yScroll = document.body.scrollHeight;
} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
xScroll = document.body.offsetWidth;
yScroll = document.body.offsetHeight;
}
var windowWidth, windowHeight;
if (self.innerHeight) { // all except Explorer
if(document.documentElement.clientWidth){
windowWidth = document.documentElement.clientWidth;
} else {
windowWidth = self.innerWidth;
}
windowHeight = self.innerHeight;
} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
windowWidth = document.documentElement.clientWidth;
windowHeight = document.documentElement.clientHeight;
} else if (document.body) { // other Explorers
windowWidth = document.body.clientWidth;
windowHeight = document.body.clientHeight;
}
// for small pages with total height less then height of the viewport
if(yScroll < windowHeight){
pageHeight = windowHeight;
} else {
pageHeight = yScroll;
}
// for small pages with total width less then width of the viewport
if(xScroll < windowWidth){
pageWidth = xScroll;
} else {
pageWidth = windowWidth;
}
return [pageWidth,pageHeight];
}
}
document.observe('dom:loaded', function () { new Lightbox(); });
Here's a class that'll allow you to do just that:
class ScrollLock {
constructor () {
this.pageBody = document.querySelector('body');
this.scrollY = 0;
}
saveScrollY = (num) => {
this.scrollY = num;
}
setScrollY = (num) => {
window.scroll(0, num);
}
setScrollOffset = (vOffset) => {
this.pageBody.style.top = `-${vOffset}px`;
}
freezeBodyScroll = () => {
this.saveScrollY(window.scrollY);
this.setScrollOffset(this.scrollY);
this.pageBody.classList.add('is-fixed');
}
unfreezeBodyScroll = () => {
this.pageBody.classList.remove('is-fixed');
// Don't reset scroll position if lock hasn't occurred
if (this.scrollY === 0) return;
this.setScrollOffset(0);
this.setScrollY(this.scrollY);
this.saveScrollY(0);
}
}
Include the following style declaration:
// In your CSS
body.is-fixed {
position: fixed;
max-width: 100%;
}
Use:
const { freezeBodyScroll, unfreezeBodyScroll } = new ScrollLock();
// Call when you open your modal
freezeBodyScroll();
// Call when you close your modal
unfreezeBodyScroll();
I got a really great script found here : http://beeker.io/exit-intent-popup-script-tutorial
Here is the js (bioep.js) code :
window.bioEp = {
// Private variables
bgEl: {},
popupEl: {},
closeBtnEl: {},
shown: false,
overflowDefault: "visible",
transformDefault: "",
// Popup options
width: 400,
height: 220,
html: "",
css: "",
fonts: [],
delay: 1,
showOnDelay: false,
cookieExp: 1,
cookieManager: {
// Create a cookie
create: function(name, value, days) {
var expires = "";
if(days) {
var date = new Date();
date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
expires = "; expires=" + date.toGMTString();
}
document.cookie = name + "=" + value + expires + "; path=/";
},
// Get the value of a cookie
get: function(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(";");
for(var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == " ") c = c.substring(1, c.length);
if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
}
return null;
},
// Delete a cookie
erase: function(name) {
this.create(name, "", -1);
}
},
// Handle the bioep_shown cookie
// If present and true, return true
// If not present or false, create and return false
checkCookie: function() {
// Handle cookie reset
if(this.cookieExp <= 0) {
this.cookieManager.erase("bioep_shown");
return false;
}
// If cookie is set to true
if(this.cookieManager.get("bioep_shown") == "true")
return true;
// Otherwise, create the cookie and return false
this.cookieManager.create("bioep_shown", "true", this.cookieExp);
return false;
},
// Add font stylesheets and CSS for the popup
addCSS: function() {
// Add font stylesheets
for(var i = 0; i < this.fonts.length; i++) {
var font = document.createElement("link");
font.href = this.fonts[i];
font.type = "text/css";
font.rel = "stylesheet";
document.head.appendChild(font);
}
// Base CSS styles for the popup
var css = document.createTextNode(
"#bio_ep_bg {display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: #000; opacity: 0.3; z-index: 10001;}" +
"#bio_ep {display: none; position: fixed; width: " + this.width + "px; height: " + this.height + "px; font-family: 'Titillium Web', sans-serif; font-size: 16px; left: 50%; top: 50%; transform: translateX(-50%) translateY(-50%); -webkit-transform: translateX(-50%) translateY(-50%); -ms-transform: translateX(-50%) translateY(-50%); background-color: #fff; box-shadow: 0px 1px 4px 0 rgba(0,0,0,0.5); z-index: 10002;}" +
"#bio_ep_close {position: absolute; left: 100%; margin: -8px 0 0 -12px; width: 20px; height: 20px; color: #fff; font-size: 12px; font-weight: bold; text-align: center; border-radius: 50%; background-color: #5c5c5c; cursor: pointer;}" +
this.css
);
// Create the style element
var style = document.createElement("style");
style.type = "text/css";
style.appendChild(css);
// Insert it before other existing style
// elements so user CSS isn't overwritten
document.head.insertBefore(style, document.getElementsByTagName("style")[0]);
},
// Add the popup to the page
addPopup: function() {
// Add the background div
this.bgEl = document.createElement("div");
this.bgEl.id = "bio_ep_bg";
document.body.appendChild(this.bgEl);
// Add the popup
if(document.getElementById("bio_ep"))
this.popupEl = document.getElementById("bio_ep");
else {
this.popupEl = document.createElement("div");
this.popupEl.id = "bio_ep";
this.popupEl.innerHTML = this.html;
document.body.appendChild(this.popupEl);
}
// Add the close button
this.closeBtnEl = document.createElement("div");
this.closeBtnEl.id = "bio_ep_close";
this.closeBtnEl.appendChild(document.createTextNode("X"));
this.popupEl.insertBefore(this.closeBtnEl, this.popupEl.firstChild);
},
// Show the popup
showPopup: function() {
if(this.shown) return;
this.bgEl.style.display = "block";
this.popupEl.style.display = "block";
// Handle scaling
this.scalePopup();
// Save body overflow value and hide scrollbars
this.overflowDefault = document.body.style.overflow;
document.body.style.overflow = "hidden";
this.shown = true;
},
// Hide the popup
hidePopup: function() {
this.bgEl.style.display = "none";
this.popupEl.style.display = "none";
// Set body overflow back to default to show scrollbars
document.body.style.overflow = this.overflowDefault;
},
// Handle scaling the popup
scalePopup: function() {
var margins = { width: 40, height: 40 };
var popupSize = { width: bioEp.popupEl.offsetWidth, height: bioEp.popupEl.offsetHeight };
var windowSize = { width: window.innerWidth, height: window.innerHeight };
var newSize = { width: 0, height: 0 };
var aspectRatio = popupSize.width / popupSize.height;
// First go by width, if the popup is larger than the window, scale it
if(popupSize.width > (windowSize.width - margins.width)) {
newSize.width = windowSize.width - margins.width;
newSize.height = newSize.width / aspectRatio;
// If the height is still too big, scale again
if(newSize.height > (windowSize.height - margins.height)) {
newSize.height = windowSize.height - margins.height;
newSize.width = newSize.height * aspectRatio;
}
}
// If width is fine, check for height
if(newSize.height === 0) {
if(popupSize.height > (windowSize.height - margins.height)) {
newSize.height = windowSize.height - margins.height;
newSize.width = newSize.height * aspectRatio;
}
}
// Set the scale amount
var scaleTo = newSize.width / popupSize.width;
// If the scale ratio is 0 or is going to enlarge (over 1) set it to 1
if(scaleTo <= 0 || scaleTo > 1) scaleTo = 1;
// Save current transform style
if(this.transformDefault === "")
this.transformDefault = window.getComputedStyle(this.popupEl, null).getPropertyValue("transform");
// Apply the scale transformation
this.popupEl.style.transform = this.transformDefault + " scale(" + scaleTo + ")";
},
// Event listener initialisation for all browsers
addEvent: function (obj, event, callback) {
if(obj.addEventListener)
obj.addEventListener(event, callback, false);
else if(obj.attachEvent)
obj.attachEvent("on" + event, callback);
},
// Load event listeners for the popup
loadEvents: function() {
// Track mouseout event on document
this.addEvent(document, "mouseout", function(e) {
e = e ? e : window.event;
var from = e.relatedTarget || e.toElement;
// Reliable, works on mouse exiting window and user switching active program
if(!from || from.nodeName === "HTML")
bioEp.showPopup();
});
// Handle the popup close button
this.addEvent(this.closeBtnEl, "click", function() {
bioEp.hidePopup();
});
// Handle window resizing
this.addEvent(window, "resize", function() {
bioEp.scalePopup();
});
},
// Set user defined options for the popup
setOptions: function(opts) {
this.width = (typeof opts.width === 'undefined') ? this.width : opts.width;
this.height = (typeof opts.height === 'undefined') ? this.height : opts.height;
this.html = (typeof opts.html === 'undefined') ? this.html : opts.html;
this.css = (typeof opts.css === 'undefined') ? this.css : opts.css;
this.fonts = (typeof opts.fonts === 'undefined') ? this.fonts : opts.fonts;
this.delay = (typeof opts.delay === 'undefined') ? this.delay : opts.delay;
this.showOnDelay = (typeof opts.showOnDelay === 'undefined') ? this.showOnDelay : opts.showOnDelay;
this.cookieExp = (typeof opts.cookieExp === 'undefined') ? this.cookieExp : opts.cookieExp;
},
// Ensure the DOM has loaded
domReady: function(callback) {
(document.readyState === "interactive" || document.readyState === "complete") ? callback() : this.addEvent(document, "DOMContentLoaded", callback);
},
// Initialize
init: function(opts) {
// Handle options
if(typeof opts !== 'undefined')
this.setOptions(opts);
// Add CSS here to make sure user HTML is hidden regardless of cookie
this.addCSS();
// Once the DOM has fully loaded
this.domReady(function() {
// Handle the cookie
if(bioEp.checkCookie()) return;
// Add the popup
bioEp.addPopup();
// Load events
setTimeout(function() {
bioEp.loadEvents();
if(bioEp.showOnDelay)
bioEp.showPopup();
}, bioEp.delay * 1000);
});
}
}
And here is the HTML code:
<script type="text/javascript" src="bioep.js"></script>
<script type="text/javascript">
bioEp.init({
html: '<div id="#leaving-content">The content i want to print</div>',
css: '#leaving-content {padding: 5%;}'});
</script>
This script allow to open a pop-up when user try to leave the page. Pretty nice work. But i'm a great noob and for a personnal project i try to adapt this code to be able to run a pop-under with an another website inside an not only my own html code (like an iframe). Can you help me please ?
Thank you !
No need for such scripts if you only want it to work for the back button, here's some simple code to do the job (requires jQuery).
var popupWebsite = "http://seapip.com";
if (window.history && window.history.pushState) {
window.history.pushState('forward', null, './');
}
$(window).on('popstate', function() {
$("html").append("<iframe src="+popupWebsite +" style=\"position: fixed; top: 0; left: 0; width: 100%; height: 100%;\"></iframe>")
});
I'm trying to find a very simple and smooth, lightweight javascript or jquery marquee. I already tried silk marquee or something, but it wouldn't work with the application I was using. So the simpler and shorter, the better - and easier to debug. Does anybody know of a easy to implement javascript replacement for the marquee?
Pastebin
Code
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<script type="text/javascript">
var tWidth='300px'; // width (in pixels)
var tHeight='25px'; // height (in pixels)
var tcolour='#ffffcc'; // background colour:
var moStop=true; // pause on mouseover (true or false)
var fontfamily = 'arial,sans-serif'; // font for content
var tSpeed=3; // scroll speed (1 = slow, 5 = fast)
// enter your ticker content here (use \/ and \' in place of / and ' respectively)
var content='Are you looking for loads of useful information <a href="http:\/\/javascript.about.com\/">About Javascript<\/a>? Well now you\'ve found it.';
var cps=-tSpeed; var aw, mq; var fsz = parseInt(tHeight) - 4; function startticker(){if (document.getElementById) {var tick = '<div style="position:relative;width:'+tWidth+';height:'+tHeight+';overflow:hidden;background-color:'+tcolour+'"'; if (moStop) tick += ' onmouseover="cps=0" onmouseout="cps=-tSpeed"'; tick +='><div id="mq" style="position:absolute;right:0px;top:0px;font-family:'+fontfamily+';font-size:'+fsz+'px;white-space:nowrap;"><\/div><\/div>'; document.getElementById('ticker').innerHTML = tick; mq = document.getElementById("mq"); mq.style.right=(10+parseInt(tWidth))+"px"; mq.innerHTML='<span id="tx">'+content+'<\/span>'; aw = document.getElementById("tx").offsetWidth; lefttime=setInterval("scrollticker()",50);}} function scrollticker(){mq.style.right = (parseInt(mq.style.right)>(-10 - aw)) ?
mq.style.right = parseInt(mq.style.right)+cps+"px": parseInt(tWidth)+10+"px";} window.onload=startticker;
</script>
</head>
<body>
<div id="ticker">
this is a simple scrolling text!
</div>
</body>
</html>
hiya simple demo from recommendations in above comments: http://jsfiddle.net/FWWEn/
with pause functionality on mouseover: http://jsfiddle.net/zrW5q/
hope this helps, have a nice one, cheers!
html
<h1>Hello World!</h1>
<h2>I'll marquee twice</h2>
<h3>I go fast!</h3>
<h4>Left to right</h4>
<h5>I'll defer that question</h5>
Jquery code
(function($) {
$.fn.textWidth = function(){
var calc = '<span style="display:none">' + $(this).text() + '</span>';
$('body').append(calc);
var width = $('body').find('span:last').width();
$('body').find('span:last').remove();
return width;
};
$.fn.marquee = function(args) {
var that = $(this);
var textWidth = that.textWidth(),
offset = that.width(),
width = offset,
css = {
'text-indent' : that.css('text-indent'),
'overflow' : that.css('overflow'),
'white-space' : that.css('white-space')
},
marqueeCss = {
'text-indent' : width,
'overflow' : 'hidden',
'white-space' : 'nowrap'
},
args = $.extend(true, { count: -1, speed: 1e1, leftToRight: false }, args),
i = 0,
stop = textWidth*-1,
dfd = $.Deferred();
function go() {
if(!that.length) return dfd.reject();
if(width == stop) {
i++;
if(i == args.count) {
that.css(css);
return dfd.resolve();
}
if(args.leftToRight) {
width = textWidth*-1;
} else {
width = offset;
}
}
that.css('text-indent', width + 'px');
if(args.leftToRight) {
width++;
} else {
width--;
}
setTimeout(go, args.speed);
};
if(args.leftToRight) {
width = textWidth*-1;
width++;
stop = offset;
} else {
width--;
}
that.css(marqueeCss);
go();
return dfd.promise();
};
})(jQuery);
$('h1').marquee();
$('h2').marquee({ count: 2 });
$('h3').marquee({ speed: 5 });
$('h4').marquee({ leftToRight: true });
$('h5').marquee({ count: 1, speed: 2 }).done(function() { $('h5').css('color', '#f00'); })
I've made very simple function for marquee. See: http://jsfiddle.net/vivekw/pHNpk/2/
It pauses on mouseover & resumes on mouseleave. Speed can be varied. Easy to understand.
function marquee(a, b) {
var width = b.width();
var start_pos = a.width();
var end_pos = -width;
function scroll() {
if (b.position().left <= -width) {
b.css('left', start_pos);
scroll();
}
else {
time = (parseInt(b.position().left, 10) - end_pos) *
(10000 / (start_pos - end_pos)); // Increase or decrease speed by changing value 10000
b.animate({
'left': -width
}, time, 'linear', function() {
scroll();
});
}
}
b.css({
'width': width,
'left': start_pos
});
scroll(a, b);
b.mouseenter(function() { // Remove these lines
b.stop(); //
b.clearQueue(); // if you don't want
}); //
b.mouseleave(function() { // marquee to pause
scroll(a, b); //
}); // on mouse over
}
$(document).ready(function() {
marquee($('#display'), $('#text')); //Enter name of container element & marquee element
});
I just created a simple jQuery plugin for that. Try it ;)
https://github.com/aamirafridi/jQuery.Marquee
The following works:
http://jsfiddle.net/xAGRJ/4/
The problem with your original code was you are calling scrollticker() by passing a string to setInterval, where you should just pass the function name and treat it as a variable:
lefttime = setInterval(scrollticker, 50);
instead of
lefttime = setInterval("scrollticker()", 50);
Why write custom jQuery code for Marquee... just use a plugin for jQuery - marquee() and use it like in the example below:
First include :
<script type='text/javascript' src='//cdn.jsdelivr.net/jquery.marquee/1.3.1/jquery.marquee.min.js'></script>
and then:
//proporcional speed counter (for responsive/fluid use)
var widths = $('.marquee').width()
var duration = widths * 7;
$('.marquee').marquee({
//speed in milliseconds of the marquee
duration: duration, // for responsive/fluid use
//duration: 8000, // for fixed container
//gap in pixels between the tickers
gap: $('.marquee').width(),
//time in milliseconds before the marquee will start animating
delayBeforeStart: 0,
//'left' or 'right'
direction: 'left',
//true or false - should the marquee be duplicated to show an effect of continues flow
duplicated: true
});
If you can make it simpler and better I dare you all people :). Don't make your life more difficult than it should be. More about this plugin and its functionalities at: http://aamirafridi.com/jquery/jquery-marquee-plugin
I made my own version, based in the code presented above by #Tats_innit .
The difference is the pause function. Works a little better in that aspect.
(function ($) {
var timeVar, width=0;
$.fn.textWidth = function () {
var calc = '<span style="display:none">' + $(this).text() + '</span>';
$('body').append(calc);
var width = $('body').find('span:last').width();
$('body').find('span:last').remove();
return width;
};
$.fn.marquee = function (args) {
var that = $(this);
if (width == 0) { width = that.width(); };
var textWidth = that.textWidth(), offset = that.width(), i = 0, stop = textWidth * -1, dfd = $.Deferred(),
css = {
'text-indent': that.css('text-indent'),
'overflow': that.css('overflow'),
'white-space': that.css('white-space')
},
marqueeCss = {
'text-indent': width,
'overflow': 'hidden',
'white-space': 'nowrap'
},
args = $.extend(true, { count: -1, speed: 1e1, leftToRight: false, pause: false }, args);
function go() {
if (!that.length) return dfd.reject();
if (width <= stop) {
i++;
if (i <= args.count) {
that.css(css);
return dfd.resolve();
}
if (args.leftToRight) {
width = textWidth * -1;
} else {
width = offset;
}
}
that.css('text-indent', width + 'px');
if (args.leftToRight) {
width++;
} else {
width=width-2;
}
if (args.pause == false) { timeVar = setTimeout(function () { go() }, args.speed); };
if (args.pause == true) { clearTimeout(timeVar); };
};
if (args.leftToRight) {
width = textWidth * -1;
width++;
stop = offset;
} else {
width--;
}
that.css(marqueeCss);
timeVar = setTimeout(function () { go() }, 100);
return dfd.promise();
};
})(jQuery);
usage:
for start: $('#Text1').marquee()
pause: $('#Text1').marquee({ pause: true })
resume: $('#Text1').marquee({ pause: false })
My text marquee for more text,
and position absolute enabled
http://jsfiddle.net/zrW5q/2075/
(function($) {
$.fn.textWidth = function() {
var calc = document.createElement('span');
$(calc).text($(this).text());
$(calc).css({
position: 'absolute',
visibility: 'hidden',
height: 'auto',
width: 'auto',
'white-space': 'nowrap'
});
$('body').append(calc);
var width = $(calc).width();
$(calc).remove();
return width;
};
$.fn.marquee = function(args) {
var that = $(this);
var textWidth = that.textWidth(),
offset = that.width(),
width = offset,
css = {
'text-indent': that.css('text-indent'),
'overflow': that.css('overflow'),
'white-space': that.css('white-space')
},
marqueeCss = {
'text-indent': width,
'overflow': 'hidden',
'white-space': 'nowrap'
},
args = $.extend(true, {
count: -1,
speed: 1e1,
leftToRight: false
}, args),
i = 0,
stop = textWidth * -1,
dfd = $.Deferred();
function go() {
if (that.css('overflow') != "hidden") {
that.css('text-indent', width + 'px');
return false;
}
if (!that.length) return dfd.reject();
if (width <= stop) {
i++;
if (i == args.count) {
that.css(css);
return dfd.resolve();
}
if (args.leftToRight) {
width = textWidth * -1;
} else {
width = offset;
}
}
that.css('text-indent', width + 'px');
if (args.leftToRight) {
width++;
} else {
width--;
}
setTimeout(go, args.speed);
};
if (args.leftToRight) {
width = textWidth * -1;
width++;
stop = offset;
} else {
width--;
}
that.css(marqueeCss);
go();
return dfd.promise();
};
// $('h1').marquee();
$("h1").marquee();
$("h1").mouseover(function () {
$(this).removeAttr("style");
}).mouseout(function () {
$(this).marquee();
});
})(jQuery);
Responsive resist jQuery marquee simple plugin. Tutorial:
// start plugin
(function($){
$.fn.marque = function(options, callback){
// check callback
if(typeof callback == 'function'){
callback.call(this);
} else{
console.log("second argument (callback) is not a function");
// throw "callback must be a function"; //only if callback for some reason is required
// return this; //only if callback for some reason is required
}
//set and overwrite default functions
var defOptions = $.extend({
speedPixelsInOneSecound: 150, //speed will behave same for different screen where duration will be different for each size of the screen
select: $('.message div'),
clickSelect: '', // selector that on click will redirect user ... (optional)
clickUrl: '' //... to this url. (optional)
}, options);
//Run marque plugin
var windowWidth = $(window).width();
var textWidth = defOptions.select.outerWidth();
var duration = (windowWidth + textWidth) * 1000 / defOptions.speedPixelsInOneSecound;
var startingPosition = (windowWidth + textWidth);
var curentPosition = (windowWidth + textWidth);
var speedProportionToLocation = curentPosition / startingPosition;
defOptions.select.css({'right': -(textWidth)});
defOptions.select.show();
var animation;
function marquee(animation){
curentPosition = (windowWidth + defOptions.select.outerWidth());
speedProportionToLocation = curentPosition / startingPosition;
animation = defOptions.select.animate({'right': windowWidth+'px'}, duration * speedProportionToLocation, "linear", function(){
defOptions.select.css({'right': -(textWidth)});
});
}
var play = setInterval(marquee, 200);
//add onclick behaviour
if(defOptions.clickSelect != '' && defOptions.clickUrl != ''){
defOptions.clickSelect.click(function(){
window.location.href = defOptions.clickUrl;
});
}
return this;
};
}(jQuery));
// end plugin
Use this custom jQuery plugin as bellow:
//use example
$(window).marque({
speedPixelsInOneSecound: 150, // spped pixels/secound
select: $('.message div'), // select an object on which you want to apply marquee effects.
clickSelect: $('.message'), // select clicable object (optional)
clickUrl: 'services.php' // define redirection url (optional)
});
Marquee using CSS animations.
`<style>
.items-holder {
animation: moveSlideshow 5s linear infinite;
}
.items-holder:hover {
animation-play-state: paused;
}
#keyframes moveSlideshow {
100% {
transform: translateX(100%);
}
}
</style>`
I try use only css for it this link.
<style>
.header {
background: #212121;
overflow: hidden;
height: 65px;
position: relative;
}
.header div {
display: flex;
flex-direction: row;
align-items: center;
overflow: hidden;
height: 65px;
transform: translate(100%, 0);
}
.header div * {
font-family: "Roboto", sans-serif;
color: #fff339;
text-transform: uppercase;
text-decoration: none;
}
.header div img {
height: 60px;
margin-right: 20px;
}
.header .ticker-wrapper__container{
display: flex;
flex-direction: row;
align-items: center;
position: absolute;
top: 0;
right: 0;
animation: ticker 30s infinite linear forwards;
}
.header:hover .ticker-wrapper__container{
animation-play-state: paused;
}
.ticker-wrapper__container a{
display: flex;
margin-right: 60px;
align-items: center;
}
#keyframes ticker {
0% {
transform: translate(100%, 0);
}
50% {
transform: translate(0, 0);
}
100% {
transform: translate(-100%, 0);
}
}
</style>