"Brand zoom"
Bootstrap 3.1.0 Snippet by mrnois

<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script> <script src="//code.jquery.com/jquery-1.11.1.min.js"></script> <!------ Include the above in your HEAD tag ----------> <!doctype html> <html> <head> <title>Zoom</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> </head> <body> <nav class="navbar navbar-default" role="navigation"> <div class="container-fluid"> <!-- Brand and toggle get grouped for better mobile display --> <div class="navbar-header "> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a class="navbar-brand zoom" href="#">Brand</a> </div> <!-- Collect the nav links, forms, and other content for toggling --> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link</a></li> <li><a href="#">Link</a></li> <li><a href="#">Link</a></li> <li><a href="#">Link</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> <script> Array.prototype.forEach.call(document.querySelectorAll('p'), function (p, i) { p.style.marginLeft = i * 6 + '%' }) Zoomerang .config({ maxHeight: 400, maxWidth: 400, bgColor: '#000', bgOpacity: .85, onOpen: openCallback, onClose: closeCallback }) .listen('.zoom') function openCallback (el) { console.log('zoomed in on: ') console.log(el) } function closeCallback (el) { console.log('zoomed out on: ') console.log(el) } </script> </body> </html>
.zoom { cursor: pointer; }
/* * zoomerang.js - http://yyx990803.github.io/zoomerang/ */ (function () { // regex var percentageRE = /^([\d\.]+)%$/ // elements var overlay = document.createElement('div'), wrapper = document.createElement('div'), target, parent, placeholder // state var shown = false, lock = false, originalStyles // options var options = { transitionDuration: '.4s', transitionTimingFunction: 'cubic-bezier(.4,0,0,1)', bgColor: '#fff', bgOpacity: 1, maxWidth: 300, maxHeight: 300, onOpen: null, onClose: null } // compatibility stuff var trans = sniffTransition(), transitionProp = trans.transition, transformProp = trans.transform, transformCssProp = transformProp.replace(/(.*)Transform/, '-$1-transform'), transEndEvent = trans.transEnd setStyle(overlay, { position: 'fixed', display: 'none', zIndex: 99998, top: 0, left: 0, right: 0, bottom: 0, opacity: 0, backgroundColor: options.bgColor, transition: 'opacity ' + options.transitionDuration + ' ' + options.transitionTimingFunction }) setStyle(wrapper, { position: 'fixed', zIndex: 99999, top: '50%', left: '50%', width: 0, height: 0 }) // helpers ---------------------------------------------------------------- function setStyle (el, styles, remember) { checkTrans(styles) var s = el.style, original = {} for (var key in styles) { if (remember) { original[key] = s[key] || '' } s[key] = styles[key] } return original } function sniffTransition () { var ret = {}, trans = ['webkitTransition', 'transition', 'mozTransition'], tform = ['webkitTransform', 'transform', 'mozTransform'], end = { 'transition' : 'transitionend', 'mozTransition' : 'transitionend', 'webkitTransition' : 'webkitTransitionEnd' } trans.some(function (prop) { if (overlay.style[prop] !== undefined) { ret.transition = prop ret.transEnd = end[prop] return true } }) tform.some(function (prop) { if (overlay.style[prop] !== undefined) { ret.transform = prop return true } }) return ret } function checkTrans (styles) { if (styles.transition) { styles[transitionProp] = styles.transition } if (styles.transform) { styles[transformProp] = styles.transform } } var stylesToCopy = [ 'position', 'display', 'float', 'top', 'left', 'right', 'bottom', 'marginBottom', 'marginLeft', 'marginRight', 'marginTop', 'font', 'lineHeight', 'verticalAlign' ] function copy (el, box) { var styles = getComputedStyle(el), ph = document.createElement('div'), i = stylesToCopy.length, key while (i--) { key = stylesToCopy[i] ph.style[key] = styles[key] } setStyle(ph, { visibility: 'hidden', width: box.width + 'px', height: box.height + 'px', display: styles.display === 'inline' ? 'inline-block' : styles.display }) if (options.deepCopy) { ph.innerHTML = el.innerHTML } else { ph.textContent = el.textContent } return ph } var api = { config: function (opts) { if (!opts) return options for (var key in opts) { options[key] = opts[key] } setStyle(overlay, { backgroundColor: options.bgColor, transition: 'opacity ' + options.transitionDuration + ' ' + options.transitionTimingFunction }) return this }, open: function (el, cb) { if (shown || lock) return target = typeof el === 'string' ? document.querySelector(el) : el shown = true lock = true parent = target.parentNode var p = target.getBoundingClientRect(), scale = Math.min(options.maxWidth / p.width, options.maxHeight / p.height), dx = p.left - (window.innerWidth - p.width) / 2, dy = p.top - (window.innerHeight - p.height) / 2 placeholder = copy(target, p) originalStyles = setStyle(target, { position: 'absolute', top: 0, left: 0, right: '', bottom: '', whiteSpace: 'nowrap', marginTop: -p.height / 2 + 'px', marginLeft: -p.width / 2 + 'px', transform: 'translate(' + dx + 'px, ' + dy + 'px)', transition: '' }, true) // deal with % width and height var wPctMatch = target.style.width.match(percentageRE), hPctMatch = target.style.height.match(percentageRE) if (wPctMatch || hPctMatch) { var wPct = wPctMatch ? +wPctMatch[1] / 100 : 1, hPct = hPctMatch ? +hPctMatch[1] / 100 : 1 setStyle(wrapper, { width: ~~(p.width / wPct) + 'px', height: ~~(p.height / hPct) + 'px' }) } // insert overlay & placeholder parent.appendChild(overlay) parent.appendChild(wrapper) parent.insertBefore(placeholder, target) wrapper.appendChild(target) overlay.style.display = 'block' // force layout var force = target.offsetHeight // trigger transition overlay.style.opacity = options.bgOpacity setStyle(target, { transition: transformCssProp + ' ' + options.transitionDuration + ' ' + options.transitionTimingFunction, transform: 'scale(' + scale + ')' }) target.addEventListener(transEndEvent, function onEnd () { target.removeEventListener(transEndEvent, onEnd) lock = false cb = cb || options.onOpen if (cb) cb(target) }) return this }, close: function (cb) { if (!shown || lock) return lock = true var p = placeholder.getBoundingClientRect(), dx = p.left - (window.innerWidth - p.width) / 2, dy = p.top - (window.innerHeight - p.height) / 2 overlay.style.opacity = 0 setStyle(target, { transform: 'translate(' + dx + 'px, ' + dy + 'px)' }) target.addEventListener(transEndEvent, function onEnd () { target.removeEventListener(transEndEvent, onEnd) setStyle(target, originalStyles) parent.insertBefore(target, placeholder) parent.removeChild(placeholder) parent.removeChild(overlay) parent.removeChild(wrapper) overlay.style.display = 'none' placeholder = null shown = false lock = false cb = typeof cb === 'function' ? cb : options.onClose if (cb) cb(target) }) return this }, listen: function listen (el) { if (typeof el === 'string') { var els = document.querySelectorAll(el), i = els.length while (i--) { listen(els[i]) } return } el.addEventListener('click', function (e) { e.stopPropagation() if (shown) { api.close() } else { api.open(el) } }) return this } } overlay.addEventListener('click', api.close) wrapper.addEventListener('click', api.close) // umd expose if (typeof exports == "object") { module.exports = api } else if (typeof define == "function" && define.amd) { define(function(){ return api }) } else { this.Zoomerang = api } })();

Related: See More


Questions / Comments: