Last active
December 14, 2016 10:38
-
-
Save danharr/8b91ffad6b59baa61870 to your computer and use it in GitHub Desktop.
Before vs After Slider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*, | |
*:before, | |
*:after { | |
-moz-box-sizing: border-box; | |
-webkit-box-sizing: border-box; | |
box-sizing: border-box; } | |
html, | |
body { | |
font-size: 100%; } | |
body { | |
background: white; | |
color: #222222; | |
padding: 0; | |
margin: 0; | |
font-family: "Helvetica Neue", "Helvetica", Helvetica, Arial, sans-serif; | |
font-weight: normal; | |
font-style: normal; | |
line-height: 1; | |
position: relative; | |
cursor: default; } | |
a:hover { | |
cursor: pointer; } | |
a:focus { | |
outline: none; } | |
img, | |
object, | |
embed { | |
max-width: 100%; | |
height: auto; } | |
object, | |
embed { | |
height: 100%; } | |
img { | |
-ms-interpolation-mode: bicubic; } | |
#map_canvas img, | |
#map_canvas embed, | |
#map_canvas object, | |
.map_canvas img, | |
.map_canvas embed, | |
.map_canvas object { | |
max-width: none !important; } | |
.left { | |
float: left !important; } | |
.right { | |
float: right !important; } | |
.text-left { | |
text-align: left !important; } | |
.text-right { | |
text-align: right !important; } | |
.text-center { | |
text-align: center !important; } | |
.text-justify { | |
text-align: justify !important; } | |
.hide { | |
display: none; } | |
.antialiased { | |
-webkit-font-smoothing: antialiased; } | |
img { | |
display: inline-block; | |
vertical-align: middle; } | |
textarea { | |
height: auto; | |
min-height: 50px; } | |
select { | |
width: 100%; } | |
/* Grid HTML Classes */ | |
.row { | |
width: 100%; | |
margin-left: auto; | |
margin-right: auto; | |
margin-top: 0; | |
margin-bottom: 0; | |
max-width: 62.5em; | |
*zoom: 1; } | |
.row:before, .row:after { | |
content: " "; | |
display: table; } | |
.row:after { | |
clear: both; } | |
.row.collapse .column, | |
.row.collapse .columns { | |
position: relative; | |
padding-left: 0; | |
padding-right: 0; | |
float: left; } | |
.row .row { | |
width: auto; | |
margin-left: -0.9375em; | |
margin-right: -0.9375em; | |
margin-top: 0; | |
margin-bottom: 0; | |
max-width: none; | |
*zoom: 1; } | |
.row .row:before, .row .row:after { | |
content: " "; | |
display: table; } | |
.row .row:after { | |
clear: both; } | |
.row .row.collapse { | |
width: auto; | |
margin: 0; | |
max-width: none; | |
*zoom: 1; } | |
.row .row.collapse:before, .row .row.collapse:after { | |
content: " "; | |
display: table; } | |
.row .row.collapse:after { | |
clear: both; } | |
.column, | |
.columns { | |
position: relative; | |
padding-left: 0.9375em; | |
padding-right: 0.9375em; | |
width: 100%; | |
float: left; } | |
@media only screen { | |
.column, | |
.columns { | |
position: relative; | |
padding-left: 0.9375em; | |
padding-right: 0.9375em; | |
float: left; } | |
.small-1 { | |
position: relative; | |
width: 8.33333%; } | |
.small-2 { | |
position: relative; | |
width: 16.66667%; } | |
.small-3 { | |
position: relative; | |
width: 25%; } | |
.small-4 { | |
position: relative; | |
width: 33.33333%; } | |
.small-5 { | |
position: relative; | |
width: 41.66667%; } | |
.small-6 { | |
position: relative; | |
width: 50%; } | |
.small-7 { | |
position: relative; | |
width: 58.33333%; } | |
.small-8 { | |
position: relative; | |
width: 66.66667%; } | |
.small-9 { | |
position: relative; | |
width: 75%; } | |
.small-10 { | |
position: relative; | |
width: 83.33333%; } | |
.small-11 { | |
position: relative; | |
width: 91.66667%; } | |
.small-12 { | |
position: relative; | |
width: 100%; } | |
.small-offset-0 { | |
position: relative; | |
margin-left: 0%; } | |
.small-offset-1 { | |
position: relative; | |
margin-left: 8.33333%; } | |
.small-offset-2 { | |
position: relative; | |
margin-left: 16.66667%; } | |
.small-offset-3 { | |
position: relative; | |
margin-left: 25%; } | |
.small-offset-4 { | |
position: relative; | |
margin-left: 33.33333%; } | |
.small-offset-5 { | |
position: relative; | |
margin-left: 41.66667%; } | |
.small-offset-6 { | |
position: relative; | |
margin-left: 50%; } | |
.small-offset-7 { | |
position: relative; | |
margin-left: 58.33333%; } | |
.small-offset-8 { | |
position: relative; | |
margin-left: 66.66667%; } | |
.small-offset-9 { | |
position: relative; | |
margin-left: 75%; } | |
.small-offset-10 { | |
position: relative; | |
margin-left: 83.33333%; } | |
[class*="column"] + [class*="column"]:last-child { | |
float: right; } | |
[class*="column"] + [class*="column"].end { | |
float: left; } | |
.column.small-centered, | |
.columns.small-centered { | |
position: relative; | |
margin-left: auto; | |
margin-right: auto; | |
float: none !important; } } | |
/* Styles for screens that are atleast 768px; */ | |
@media only screen and (min-width: 768px) { | |
.large-1 { | |
position: relative; | |
width: 8.33333%; } | |
.large-2 { | |
position: relative; | |
width: 16.66667%; } | |
.large-3 { | |
position: relative; | |
width: 25%; } | |
.large-4 { | |
position: relative; | |
width: 33.33333%; } | |
.large-5 { | |
position: relative; | |
width: 41.66667%; } | |
.large-6 { | |
position: relative; | |
width: 50%; } | |
.large-7 { | |
position: relative; | |
width: 58.33333%; } | |
.large-8 { | |
position: relative; | |
width: 66.66667%; } | |
.large-9 { | |
position: relative; | |
width: 75%; } | |
.large-10 { | |
position: relative; | |
width: 83.33333%; } | |
.large-11 { | |
position: relative; | |
width: 91.66667%; } | |
.large-12 { | |
position: relative; | |
width: 100%; } | |
.row .large-offset-0 { | |
position: relative; | |
margin-left: 0%; } | |
.row .large-offset-1 { | |
position: relative; | |
margin-left: 8.33333%; } | |
.row .large-offset-2 { | |
position: relative; | |
margin-left: 16.66667%; } | |
.row .large-offset-3 { | |
position: relative; | |
margin-left: 25%; } | |
.row .large-offset-4 { | |
position: relative; | |
margin-left: 33.33333%; } | |
.row .large-offset-5 { | |
position: relative; | |
margin-left: 41.66667%; } | |
.row .large-offset-6 { | |
position: relative; | |
margin-left: 50%; } | |
.row .large-offset-7 { | |
position: relative; | |
margin-left: 58.33333%; } | |
.row .large-offset-8 { | |
position: relative; | |
margin-left: 66.66667%; } | |
.row .large-offset-9 { | |
position: relative; | |
margin-left: 75%; } | |
.row .large-offset-10 { | |
position: relative; | |
margin-left: 83.33333%; } | |
.row .large-offset-11 { | |
position: relative; | |
margin-left: 91.66667%; } | |
.push-1 { | |
position: relative; | |
left: 8.33333%; | |
right: auto; } | |
.pull-1 { | |
position: relative; | |
right: 8.33333%; | |
left: auto; } | |
.push-2 { | |
position: relative; | |
left: 16.66667%; | |
right: auto; } | |
.pull-2 { | |
position: relative; | |
right: 16.66667%; | |
left: auto; } | |
.push-3 { | |
position: relative; | |
left: 25%; | |
right: auto; } | |
.pull-3 { | |
position: relative; | |
right: 25%; | |
left: auto; } | |
.push-4 { | |
position: relative; | |
left: 33.33333%; | |
right: auto; } | |
.pull-4 { | |
position: relative; | |
right: 33.33333%; | |
left: auto; } | |
.push-5 { | |
position: relative; | |
left: 41.66667%; | |
right: auto; } | |
.pull-5 { | |
position: relative; | |
right: 41.66667%; | |
left: auto; } | |
.push-6 { | |
position: relative; | |
left: 50%; | |
right: auto; } | |
.pull-6 { | |
position: relative; | |
right: 50%; | |
left: auto; } | |
.push-7 { | |
position: relative; | |
left: 58.33333%; | |
right: auto; } | |
.pull-7 { | |
position: relative; | |
right: 58.33333%; | |
left: auto; } | |
.push-8 { | |
position: relative; | |
left: 66.66667%; | |
right: auto; } | |
.pull-8 { | |
position: relative; | |
right: 66.66667%; | |
left: auto; } | |
.push-9 { | |
position: relative; | |
left: 75%; | |
right: auto; } | |
.pull-9 { | |
position: relative; | |
right: 75%; | |
left: auto; } | |
.push-10 { | |
position: relative; | |
left: 83.33333%; | |
right: auto; } | |
.pull-10 { | |
position: relative; | |
right: 83.33333%; | |
left: auto; } | |
.push-11 { | |
position: relative; | |
left: 91.66667%; | |
right: auto; } | |
.pull-11 { | |
position: relative; | |
right: 91.66667%; | |
left: auto; } | |
.column.large-centered, | |
.columns.large-centered { | |
position: relative; | |
margin-left: auto; | |
margin-right: auto; | |
float: none !important; } | |
.column.large-uncentered, | |
.columns.large-uncentered { | |
margin-left: 0; | |
margin-right: 0; | |
float: left !important; } | |
.column.large-uncentered.opposite, | |
.columns.large-uncentered.opposite { | |
float: right !important; } } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<title>twentytwenty plugin demo</title> | |
<link href="foundation.css" rel="stylesheet" type="text/css" /> | |
<link href="twentytwenty.css" rel="stylesheet" type="text/css" /> | |
<style type="text/css"> | |
h3 { | |
font-family: ChevinLight; | |
font-size: 60px; | |
} | |
.twentytwenty-container img { | |
height:500px; | |
width:800px; | |
} | |
.icons { | |
width:70px; | |
float:left; | |
} | |
.ff { | |
height :100px;} | |
</style> | |
</head> | |
<body> | |
<!--[if IE 6]> | |
<div id="nytg-error"> | |
<p>This interactive graphic requires a browser with SVG support, such as <a href="http://www.google.com/chrome">Chrome</a>, <a href="http://www.mozilla.org/en-US/firefox/">Firefox</a>, <a href="http://www.apple.com/safari/download/">Safari</a> or the latest <a href="http://windows.microsoft.com/en-US/internet-explorer/products/ie/home">Internet Explorer 9</a>. </p> | |
<img src="https://koding.com/hello/img/oldbrowser.gif" width="670" alt="Error"> | |
<div id="nytg-chartFrame" style="display:none;"> | |
<![endif]--> | |
<!--[if IE 7]> | |
<div id="nytg-error"> | |
<p>This interactive graphic requires a browser with SVG support, such as <a href="http://www.google.com/chrome">Chrome</a>, <a href="http://www.mozilla.org/en-US/firefox/">Firefox</a>, <a href="http://www.apple.com/safari/download/">Safari</a> or the latest <a href="http://windows.microsoft.com/en-US/internet-explorer/products/ie/home">Internet Explorer 9</a>. </p> | |
<img src="https://koding.com/hello/img/oldbrowser.gif" width="670" alt="Error"> | |
<div id="nytg-chartFrame" style="display:none;"> | |
<![endif]--> | |
<!--[if IE 8]> | |
<div id="nytg-error"> | |
<p>This interactive graphic requires a browser with SVG support, such as <a href="http://www.google.com/chrome">Chrome</a>, <a href="http://www.mozilla.org/en-US/firefox/">Firefox</a>, <a href="http://www.apple.com/safari/download/">Safari</a> or the latest <a href="http://windows.microsoft.com/en-US/internet-explorer/products/ie/home">Internet Explorer 9</a>. </p> | |
<img src="https://koding.com/hello/img/oldbrowser.gif" width="670" alt="Error"> | |
<div id="nytg-chartFrame" style="display:none;"> | |
<![endif]--> | |
<div class="row" style="margin-top: 2em;"> | |
<div class="large-8 columns"> | |
<h3>Social <img class="icons" src="http://www.tips-for-excel.com/dataviz/blue.goose_.icon_.jpg"></h3> | |
<p >Limit the time spent eating alone at desks</p> | |
</div> | |
<div class="large-12 columns"> | |
<div class="twentytwenty-container"> | |
<img src="http://www.bbc.co.uk/news/special/2015/newsspec_10857/bbc_news_logo.png" /> | |
<img src="http://www.bbc.co.uk/news/special/2015/newsspec_10857/bbc_news_logo.png" /> | |
</div> | |
</div> | |
</div> | |
<div class="row" style="margin-top: 2em;"> | |
<p >Gather together for Coffee Breaks</p> | |
<div class="large-12 columns"> | |
<div class="twentytwenty-container"> | |
<img src="http://www.tips-for-excel.com/dataviz/20141203_143804.jpg" /> | |
<img src="http://www.tips-for-excel.com/dataviz/20141203_152601.jpg" /> | |
</div> | |
</div> | |
</div> | |
<div class="row" style="margin-top: 2em;"> | |
<div class="large-8 columns"> | |
<h3>Community <img class="icons" src="http://www.tips-for-excel.com/dataviz/icon.png"></h3> | |
<p >Research ideas as a team rather than in silos</p> | |
</div> | |
<div class="large-16 columns"> | |
<div class="twentytwenty-container"> | |
<img src="http://www.tips-for-excel.com/dataviz/research2.png" /> | |
<img src="http://www.tips-for-excel.com/dataviz/research1.png" /> | |
</div> | |
</div> | |
</div> | |
<div class="row" style="margin-top: 2em;"> | |
<div class="large-8 columns"> | |
<p >Celebrate each other's achievements</p> | |
</div> | |
<div class="large-16 columns"> | |
<div class="twentytwenty-container"> | |
<img src="http://www.tips-for-excel.com/dataviz/20141203_144429.jpg" /> | |
<img src="http://www.tips-for-excel.com/dataviz/comp.jpg" /> | |
</div> | |
</div> | |
</div> | |
<div class="row" style="margin-top: 2em;"> | |
<div class="large-12 columns"> | |
<p >People are aware of other people's work but not in any great detail</p> | |
</div> | |
<div class="large-16 columns"> | |
<div class="twentytwenty-container"> | |
<img src="http://www.tips-for-excel.com/dataviz/a1.png" /> | |
<img src="http://www.tips-for-excel.com/dataviz/b1.png" /> | |
</div> | |
</div> | |
</div> | |
<div class="row" style="margin-top: 2em;"> | |
<div class="large-12 columns"> | |
<p >We don’t know what others are doing, hence don’t always recognise the connections, interdependencies between each others’ work | |
</p> | |
</div> | |
<div class="large-16 columns"> | |
<div class="twentytwenty-container"> | |
<img src="http://www.tips-for-excel.com/dataviz/link2.png" /> | |
<img src="http://www.tips-for-excel.com/dataviz/link1.png" /> | |
</div> | |
</div> | |
</div> | |
<div class="ff"></div> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> | |
<script src="jquery.event.move.js"></script> | |
<script src="jquery.twentytwenty.js"></script> | |
<script> | |
$(window).load(function(){ | |
$(".twentytwenty-container[data-orientation!='vertical']").twentytwenty({default_offset_pct: 0.08}); | |
}); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// jquery.event.move | |
// | |
// 1.3.6 | |
// | |
// Stephen Band | |
// | |
// Triggers 'movestart', 'move' and 'moveend' events after | |
// mousemoves following a mousedown cross a distance threshold, | |
// similar to the native 'dragstart', 'drag' and 'dragend' events. | |
// Move events are throttled to animation frames. Move event objects | |
// have the properties: | |
// | |
// pageX: | |
// pageY: Page coordinates of pointer. | |
// startX: | |
// startY: Page coordinates of pointer at movestart. | |
// distX: | |
// distY: Distance the pointer has moved since movestart. | |
// deltaX: | |
// deltaY: Distance the finger has moved since last event. | |
// velocityX: | |
// velocityY: Average velocity over last few events. | |
(function (module) { | |
if (typeof define === 'function' && define.amd) { | |
// AMD. Register as an anonymous module. | |
define(['jquery'], module); | |
} else { | |
// Browser globals | |
module(jQuery); | |
} | |
})(function(jQuery, undefined){ | |
var // Number of pixels a pressed pointer travels before movestart | |
// event is fired. | |
threshold = 6, | |
add = jQuery.event.add, | |
remove = jQuery.event.remove, | |
// Just sugar, so we can have arguments in the same order as | |
// add and remove. | |
trigger = function(node, type, data) { | |
jQuery.event.trigger(type, data, node); | |
}, | |
// Shim for requestAnimationFrame, falling back to timer. See: | |
// see http://paulirish.com/2011/requestanimationframe-for-smart-animating/ | |
requestFrame = (function(){ | |
return ( | |
window.requestAnimationFrame || | |
window.webkitRequestAnimationFrame || | |
window.mozRequestAnimationFrame || | |
window.oRequestAnimationFrame || | |
window.msRequestAnimationFrame || | |
function(fn, element){ | |
return window.setTimeout(function(){ | |
fn(); | |
}, 25); | |
} | |
); | |
})(), | |
ignoreTags = { | |
textarea: true, | |
input: true, | |
select: true, | |
button: true | |
}, | |
mouseevents = { | |
move: 'mousemove', | |
cancel: 'mouseup dragstart', | |
end: 'mouseup' | |
}, | |
touchevents = { | |
move: 'touchmove', | |
cancel: 'touchend', | |
end: 'touchend' | |
}; | |
// Constructors | |
function Timer(fn){ | |
var callback = fn, | |
active = false, | |
running = false; | |
function trigger(time) { | |
if (active){ | |
callback(); | |
requestFrame(trigger); | |
running = true; | |
active = false; | |
} | |
else { | |
running = false; | |
} | |
} | |
this.kick = function(fn) { | |
active = true; | |
if (!running) { trigger(); } | |
}; | |
this.end = function(fn) { | |
var cb = callback; | |
if (!fn) { return; } | |
// If the timer is not running, simply call the end callback. | |
if (!running) { | |
fn(); | |
} | |
// If the timer is running, and has been kicked lately, then | |
// queue up the current callback and the end callback, otherwise | |
// just the end callback. | |
else { | |
callback = active ? | |
function(){ cb(); fn(); } : | |
fn ; | |
active = true; | |
} | |
}; | |
} | |
// Functions | |
function returnTrue() { | |
return true; | |
} | |
function returnFalse() { | |
return false; | |
} | |
function preventDefault(e) { | |
e.preventDefault(); | |
} | |
function preventIgnoreTags(e) { | |
// Don't prevent interaction with form elements. | |
if (ignoreTags[ e.target.tagName.toLowerCase() ]) { return; } | |
e.preventDefault(); | |
} | |
function isLeftButton(e) { | |
// Ignore mousedowns on any button other than the left (or primary) | |
// mouse button, or when a modifier key is pressed. | |
return (e.which === 1 && !e.ctrlKey && !e.altKey); | |
} | |
function identifiedTouch(touchList, id) { | |
var i, l; | |
if (touchList.identifiedTouch) { | |
return touchList.identifiedTouch(id); | |
} | |
// touchList.identifiedTouch() does not exist in | |
// webkit yet… we must do the search ourselves... | |
i = -1; | |
l = touchList.length; | |
while (++i < l) { | |
if (touchList[i].identifier === id) { | |
return touchList[i]; | |
} | |
} | |
} | |
function changedTouch(e, event) { | |
var touch = identifiedTouch(e.changedTouches, event.identifier); | |
// This isn't the touch you're looking for. | |
if (!touch) { return; } | |
// Chrome Android (at least) includes touches that have not | |
// changed in e.changedTouches. That's a bit annoying. Check | |
// that this touch has changed. | |
if (touch.pageX === event.pageX && touch.pageY === event.pageY) { return; } | |
return touch; | |
} | |
// Handlers that decide when the first movestart is triggered | |
function mousedown(e){ | |
var data; | |
if (!isLeftButton(e)) { return; } | |
data = { | |
target: e.target, | |
startX: e.pageX, | |
startY: e.pageY, | |
timeStamp: e.timeStamp | |
}; | |
add(document, mouseevents.move, mousemove, data); | |
add(document, mouseevents.cancel, mouseend, data); | |
} | |
function mousemove(e){ | |
var data = e.data; | |
checkThreshold(e, data, e, removeMouse); | |
} | |
function mouseend(e) { | |
removeMouse(); | |
} | |
function removeMouse() { | |
remove(document, mouseevents.move, mousemove); | |
remove(document, mouseevents.cancel, mouseend); | |
} | |
function touchstart(e) { | |
var touch, template; | |
// Don't get in the way of interaction with form elements. | |
if (ignoreTags[ e.target.tagName.toLowerCase() ]) { return; } | |
touch = e.changedTouches[0]; | |
// iOS live updates the touch objects whereas Android gives us copies. | |
// That means we can't trust the touchstart object to stay the same, | |
// so we must copy the data. This object acts as a template for | |
// movestart, move and moveend event objects. | |
template = { | |
target: touch.target, | |
startX: touch.pageX, | |
startY: touch.pageY, | |
timeStamp: e.timeStamp, | |
identifier: touch.identifier | |
}; | |
// Use the touch identifier as a namespace, so that we can later | |
// remove handlers pertaining only to this touch. | |
add(document, touchevents.move + '.' + touch.identifier, touchmove, template); | |
add(document, touchevents.cancel + '.' + touch.identifier, touchend, template); | |
} | |
function touchmove(e){ | |
var data = e.data, | |
touch = changedTouch(e, data); | |
if (!touch) { return; } | |
checkThreshold(e, data, touch, removeTouch); | |
} | |
function touchend(e) { | |
var template = e.data, | |
touch = identifiedTouch(e.changedTouches, template.identifier); | |
if (!touch) { return; } | |
removeTouch(template.identifier); | |
} | |
function removeTouch(identifier) { | |
remove(document, '.' + identifier, touchmove); | |
remove(document, '.' + identifier, touchend); | |
} | |
// Logic for deciding when to trigger a movestart. | |
function checkThreshold(e, template, touch, fn) { | |
var distX = touch.pageX - template.startX, | |
distY = touch.pageY - template.startY; | |
// Do nothing if the threshold has not been crossed. | |
if ((distX * distX) + (distY * distY) < (threshold * threshold)) { return; } | |
triggerStart(e, template, touch, distX, distY, fn); | |
} | |
function handled() { | |
// this._handled should return false once, and after return true. | |
this._handled = returnTrue; | |
return false; | |
} | |
function flagAsHandled(e) { | |
e._handled(); | |
} | |
function triggerStart(e, template, touch, distX, distY, fn) { | |
var node = template.target, | |
touches, time; | |
touches = e.targetTouches; | |
time = e.timeStamp - template.timeStamp; | |
// Create a movestart object with some special properties that | |
// are passed only to the movestart handlers. | |
template.type = 'movestart'; | |
template.distX = distX; | |
template.distY = distY; | |
template.deltaX = distX; | |
template.deltaY = distY; | |
template.pageX = touch.pageX; | |
template.pageY = touch.pageY; | |
template.velocityX = distX / time; | |
template.velocityY = distY / time; | |
template.targetTouches = touches; | |
template.finger = touches ? | |
touches.length : | |
1 ; | |
// The _handled method is fired to tell the default movestart | |
// handler that one of the move events is bound. | |
template._handled = handled; | |
// Pass the touchmove event so it can be prevented if or when | |
// movestart is handled. | |
template._preventTouchmoveDefault = function() { | |
e.preventDefault(); | |
}; | |
// Trigger the movestart event. | |
trigger(template.target, template); | |
// Unbind handlers that tracked the touch or mouse up till now. | |
fn(template.identifier); | |
} | |
// Handlers that control what happens following a movestart | |
function activeMousemove(e) { | |
var timer = e.data.timer; | |
e.data.touch = e; | |
e.data.timeStamp = e.timeStamp; | |
timer.kick(); | |
} | |
function activeMouseend(e) { | |
var event = e.data.event, | |
timer = e.data.timer; | |
removeActiveMouse(); | |
endEvent(event, timer, function() { | |
// Unbind the click suppressor, waiting until after mouseup | |
// has been handled. | |
setTimeout(function(){ | |
remove(event.target, 'click', returnFalse); | |
}, 0); | |
}); | |
} | |
function removeActiveMouse(event) { | |
remove(document, mouseevents.move, activeMousemove); | |
remove(document, mouseevents.end, activeMouseend); | |
} | |
function activeTouchmove(e) { | |
var event = e.data.event, | |
timer = e.data.timer, | |
touch = changedTouch(e, event); | |
if (!touch) { return; } | |
// Stop the interface from gesturing | |
e.preventDefault(); | |
event.targetTouches = e.targetTouches; | |
e.data.touch = touch; | |
e.data.timeStamp = e.timeStamp; | |
timer.kick(); | |
} | |
function activeTouchend(e) { | |
var event = e.data.event, | |
timer = e.data.timer, | |
touch = identifiedTouch(e.changedTouches, event.identifier); | |
// This isn't the touch you're looking for. | |
if (!touch) { return; } | |
removeActiveTouch(event); | |
endEvent(event, timer); | |
} | |
function removeActiveTouch(event) { | |
remove(document, '.' + event.identifier, activeTouchmove); | |
remove(document, '.' + event.identifier, activeTouchend); | |
} | |
// Logic for triggering move and moveend events | |
function updateEvent(event, touch, timeStamp, timer) { | |
var time = timeStamp - event.timeStamp; | |
event.type = 'move'; | |
event.distX = touch.pageX - event.startX; | |
event.distY = touch.pageY - event.startY; | |
event.deltaX = touch.pageX - event.pageX; | |
event.deltaY = touch.pageY - event.pageY; | |
// Average the velocity of the last few events using a decay | |
// curve to even out spurious jumps in values. | |
event.velocityX = 0.3 * event.velocityX + 0.7 * event.deltaX / time; | |
event.velocityY = 0.3 * event.velocityY + 0.7 * event.deltaY / time; | |
event.pageX = touch.pageX; | |
event.pageY = touch.pageY; | |
} | |
function endEvent(event, timer, fn) { | |
timer.end(function(){ | |
event.type = 'moveend'; | |
trigger(event.target, event); | |
return fn && fn(); | |
}); | |
} | |
// jQuery special event definition | |
function setup(data, namespaces, eventHandle) { | |
// Stop the node from being dragged | |
//add(this, 'dragstart.move drag.move', preventDefault); | |
// Prevent text selection and touch interface scrolling | |
//add(this, 'mousedown.move', preventIgnoreTags); | |
// Tell movestart default handler that we've handled this | |
add(this, 'movestart.move', flagAsHandled); | |
// Don't bind to the DOM. For speed. | |
return true; | |
} | |
function teardown(namespaces) { | |
remove(this, 'dragstart drag', preventDefault); | |
remove(this, 'mousedown touchstart', preventIgnoreTags); | |
remove(this, 'movestart', flagAsHandled); | |
// Don't bind to the DOM. For speed. | |
return true; | |
} | |
function addMethod(handleObj) { | |
// We're not interested in preventing defaults for handlers that | |
// come from internal move or moveend bindings | |
if (handleObj.namespace === "move" || handleObj.namespace === "moveend") { | |
return; | |
} | |
// Stop the node from being dragged | |
add(this, 'dragstart.' + handleObj.guid + ' drag.' + handleObj.guid, preventDefault, undefined, handleObj.selector); | |
// Prevent text selection and touch interface scrolling | |
add(this, 'mousedown.' + handleObj.guid, preventIgnoreTags, undefined, handleObj.selector); | |
} | |
function removeMethod(handleObj) { | |
if (handleObj.namespace === "move" || handleObj.namespace === "moveend") { | |
return; | |
} | |
remove(this, 'dragstart.' + handleObj.guid + ' drag.' + handleObj.guid); | |
remove(this, 'mousedown.' + handleObj.guid); | |
} | |
jQuery.event.special.movestart = { | |
setup: setup, | |
teardown: teardown, | |
add: addMethod, | |
remove: removeMethod, | |
_default: function(e) { | |
var event, data; | |
// If no move events were bound to any ancestors of this | |
// target, high tail it out of here. | |
if (!e._handled()) { return; } | |
function update(time) { | |
updateEvent(event, data.touch, data.timeStamp); | |
trigger(e.target, event); | |
} | |
event = { | |
target: e.target, | |
startX: e.startX, | |
startY: e.startY, | |
pageX: e.pageX, | |
pageY: e.pageY, | |
distX: e.distX, | |
distY: e.distY, | |
deltaX: e.deltaX, | |
deltaY: e.deltaY, | |
velocityX: e.velocityX, | |
velocityY: e.velocityY, | |
timeStamp: e.timeStamp, | |
identifier: e.identifier, | |
targetTouches: e.targetTouches, | |
finger: e.finger | |
}; | |
data = { | |
event: event, | |
timer: new Timer(update), | |
touch: undefined, | |
timeStamp: undefined | |
}; | |
if (e.identifier === undefined) { | |
// We're dealing with a mouse | |
// Stop clicks from propagating during a move | |
add(e.target, 'click', returnFalse); | |
add(document, mouseevents.move, activeMousemove, data); | |
add(document, mouseevents.end, activeMouseend, data); | |
} | |
else { | |
// We're dealing with a touch. Stop touchmove doing | |
// anything defaulty. | |
e._preventTouchmoveDefault(); | |
add(document, touchevents.move + '.' + e.identifier, activeTouchmove, data); | |
add(document, touchevents.end + '.' + e.identifier, activeTouchend, data); | |
} | |
} | |
}; | |
jQuery.event.special.move = { | |
setup: function() { | |
// Bind a noop to movestart. Why? It's the movestart | |
// setup that decides whether other move events are fired. | |
add(this, 'movestart.move', jQuery.noop); | |
}, | |
teardown: function() { | |
remove(this, 'movestart.move', jQuery.noop); | |
} | |
}; | |
jQuery.event.special.moveend = { | |
setup: function() { | |
// Bind a noop to movestart. Why? It's the movestart | |
// setup that decides whether other move events are fired. | |
add(this, 'movestart.moveend', jQuery.noop); | |
}, | |
teardown: function() { | |
remove(this, 'movestart.moveend', jQuery.noop); | |
} | |
}; | |
add(document, 'mousedown.move', mousedown); | |
add(document, 'touchstart.move', touchstart); | |
// Make jQuery copy touch event properties over to the jQuery event | |
// object, if they are not already listed. But only do the ones we | |
// really need. IE7/8 do not have Array#indexOf(), but nor do they | |
// have touch events, so let's assume we can ignore them. | |
if (typeof Array.prototype.indexOf === 'function') { | |
(function(jQuery, undefined){ | |
var props = ["changedTouches", "targetTouches"], | |
l = props.length; | |
while (l--) { | |
if (jQuery.event.props.indexOf(props[l]) === -1) { | |
jQuery.event.props.push(props[l]); | |
} | |
} | |
})(jQuery); | |
}; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function($){ | |
$.fn.twentytwenty = function(options) { | |
var options = $.extend({default_offset_pct: 0.5, orientation: 'horizontal'}, options); | |
return this.each(function() { | |
var sliderPct = options.default_offset_pct; | |
var container = $(this); | |
var sliderOrientation = options.orientation; | |
var beforeDirection = (sliderOrientation === 'vertical') ? 'down' : 'left'; | |
var afterDirection = (sliderOrientation === 'vertical') ? 'up' : 'right'; | |
container.wrap("<div class='twentytwenty-wrapper twentytwenty-" + sliderOrientation + "'></div>"); | |
container.append("<div class='twentytwenty-overlay'></div>"); | |
var beforeImg = container.find("img:first"); | |
var afterImg = container.find("img:last"); | |
container.append("<div class='twentytwenty-handle'></div>"); | |
var slider = container.find(".twentytwenty-handle"); | |
slider.append("<span class='twentytwenty-" + beforeDirection + "-arrow'></span>"); | |
slider.append("<span class='twentytwenty-" + afterDirection + "-arrow'></span>"); | |
container.addClass("twentytwenty-container"); | |
beforeImg.addClass("twentytwenty-before"); | |
afterImg.addClass("twentytwenty-after"); | |
var overlay = container.find(".twentytwenty-overlay"); | |
overlay.append("<div class='twentytwenty-before-label'></div>"); | |
overlay.append("<div class='twentytwenty-after-label'></div>"); | |
var calcOffset = function(dimensionPct) { | |
var w = beforeImg.width(); | |
var h = beforeImg.height(); | |
return { | |
w: w+"px", | |
h: h+"px", | |
cw: (dimensionPct*w)+"px", | |
ch: (dimensionPct*h)+"px" | |
}; | |
}; | |
var adjustContainer = function(offset) { | |
if (sliderOrientation === 'vertical') { | |
beforeImg.css("clip", "rect(0,"+offset.w+","+offset.ch+",0)"); | |
} | |
else { | |
beforeImg.css("clip", "rect(0,"+offset.cw+","+offset.h+",0)"); | |
} | |
container.css("height", offset.h); | |
}; | |
var adjustSlider = function(pct) { | |
var offset = calcOffset(pct); | |
slider.css((sliderOrientation==="vertical") ? "top" : "left", (sliderOrientation==="vertical") ? offset.ch : offset.cw); | |
adjustContainer(offset); | |
} | |
$(window).on("resize.twentytwenty", function(e) { | |
adjustSlider(sliderPct); | |
}); | |
var offsetX = 0; | |
var imgWidth = 0; | |
slider.on("movestart", function(e) { | |
if (((e.distX > e.distY && e.distX < -e.distY) || (e.distX < e.distY && e.distX > -e.distY)) && sliderOrientation !== 'vertical') { | |
e.preventDefault(); | |
} | |
else if (((e.distX < e.distY && e.distX < -e.distY) || (e.distX > e.distY && e.distX > -e.distY)) && sliderOrientation === 'vertical') { | |
e.preventDefault(); | |
} | |
container.addClass("active"); | |
offsetX = container.offset().left; | |
offsetY = container.offset().top; | |
imgWidth = beforeImg.width(); | |
imgHeight = beforeImg.height(); | |
}); | |
slider.on("moveend", function(e) { | |
container.removeClass("active"); | |
}); | |
slider.on("move", function(e) { | |
if (container.hasClass("active")) { | |
sliderPct = (sliderOrientation === 'vertical') ? (e.pageY-offsetY)/imgHeight : (e.pageX-offsetX)/imgWidth; | |
if (sliderPct < 0) { | |
sliderPct = 0; | |
} | |
if (sliderPct > 1) { | |
sliderPct = 1; | |
} | |
adjustSlider(sliderPct); | |
} | |
}); | |
container.find("img").on("mousedown", function(event) { | |
event.preventDefault(); | |
}); | |
$(window).trigger("resize.twentytwenty"); | |
}); | |
}; | |
})(jQuery); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.twentytwenty-horizontal .twentytwenty-handle:before, .twentytwenty-horizontal .twentytwenty-handle:after, .twentytwenty-vertical .twentytwenty-handle:before, .twentytwenty-vertical .twentytwenty-handle:after { | |
content: " "; | |
display: block; | |
background: white; | |
position: absolute; | |
z-index: 30; | |
-webkit-box-shadow: 0px 0px 12px rgba(51, 51, 51, 0.5); | |
-moz-box-shadow: 0px 0px 12px rgba(51, 51, 51, 0.5); | |
box-shadow: 0px 0px 12px rgba(51, 51, 51, 0.5); } | |
.twentytwenty-horizontal .twentytwenty-handle:before, .twentytwenty-horizontal .twentytwenty-handle:after { | |
width: 3px; | |
height: 9999px; | |
left: 50%; | |
margin-left: -1.5px; } | |
.twentytwenty-vertical .twentytwenty-handle:before, .twentytwenty-vertical .twentytwenty-handle:after { | |
width: 9999px; | |
height: 3px; | |
top: 50%; | |
margin-top: -1.5px; } | |
.twentytwenty-before-label, .twentytwenty-after-label, .twentytwenty-overlay { | |
position: absolute; | |
top: 0; | |
width: 100%; | |
height: 100%; } | |
.twentytwenty-before-label, .twentytwenty-after-label, .twentytwenty-overlay { | |
-webkit-transition-duration: 0.5s; | |
-moz-transition-duration: 0.5s; | |
transition-duration: 0.5s; } | |
.twentytwenty-before-label, .twentytwenty-after-label { | |
-webkit-transition-property: opacity; | |
-moz-transition-property: opacity; | |
transition-property: opacity; } | |
.twentytwenty-before-label:before, .twentytwenty-after-label:before { | |
color: white; | |
font-size: 13px; | |
letter-spacing: 0.1em; } | |
.twentytwenty-before-label:before, .twentytwenty-after-label:before { | |
position: absolute; | |
background: rgba(255, 255, 255, 0.2); | |
line-height: 38px; | |
padding: 0 20px; | |
-webkit-border-radius: 2px; | |
-moz-border-radius: 2px; | |
border-radius: 2px; } | |
.twentytwenty-horizontal .twentytwenty-before-label:before, .twentytwenty-horizontal .twentytwenty-after-label:before { | |
top: 50%; | |
margin-top: -19px; } | |
.twentytwenty-vertical .twentytwenty-before-label:before, .twentytwenty-vertical .twentytwenty-after-label:before { | |
left: 50%; | |
margin-left: -45px; | |
text-align: center; | |
width: 90px; } | |
.twentytwenty-left-arrow, .twentytwenty-right-arrow, .twentytwenty-up-arrow, .twentytwenty-down-arrow { | |
width: 0; | |
height: 0; | |
border: 6px inset transparent; | |
position: absolute; } | |
.twentytwenty-left-arrow, .twentytwenty-right-arrow { | |
top: 50%; | |
margin-top: -6px; } | |
.twentytwenty-up-arrow, .twentytwenty-down-arrow { | |
left: 50%; | |
margin-left: -6px; } | |
.twentytwenty-container { | |
-webkit-box-sizing: content-box; | |
-moz-box-sizing: content-box; | |
box-sizing: content-box; | |
z-index: 0; | |
overflow: hidden; | |
position: relative; | |
-webkit-user-select: none; | |
-moz-user-select: none; } | |
.twentytwenty-container img { | |
max-width: 100%; | |
position: absolute; | |
top: 0; | |
display: block; } | |
.twentytwenty-container.active .twentytwenty-overlay, .twentytwenty-container.active :hover.twentytwenty-overlay { | |
background: rgba(0, 0, 0, 0); } | |
.twentytwenty-container.active .twentytwenty-overlay .twentytwenty-before-label, | |
.twentytwenty-container.active .twentytwenty-overlay .twentytwenty-after-label, .twentytwenty-container.active :hover.twentytwenty-overlay .twentytwenty-before-label, | |
.twentytwenty-container.active :hover.twentytwenty-overlay .twentytwenty-after-label { | |
opacity: 0; } | |
.twentytwenty-container * { | |
-webkit-box-sizing: content-box; | |
-moz-box-sizing: content-box; | |
box-sizing: content-box; } | |
.twentytwenty-before-label { | |
opacity: 0; } | |
.twentytwenty-before-label:before { | |
content: "Before"; } | |
.twentytwenty-after-label { | |
opacity: 0; } | |
.twentytwenty-after-label:before { | |
content: "After"; } | |
.twentytwenty-horizontal .twentytwenty-before-label:before { | |
left: 10px; } | |
.twentytwenty-horizontal .twentytwenty-after-label:before { | |
right: 10px; } | |
.twentytwenty-vertical .twentytwenty-before-label:before { | |
top: 10px; } | |
.twentytwenty-vertical .twentytwenty-after-label:before { | |
bottom: 10px; } | |
.twentytwenty-overlay { | |
-webkit-transition-property: background; | |
-moz-transition-property: background; | |
transition-property: background; | |
background: rgba(0, 0, 0, 0); | |
z-index: 25; } | |
.twentytwenty-overlay:hover { | |
background: rgba(0, 0, 0, 0.5); } | |
.twentytwenty-overlay:hover .twentytwenty-after-label { | |
opacity: 1; } | |
.twentytwenty-overlay:hover .twentytwenty-before-label { | |
opacity: 1; } | |
.twentytwenty-before { | |
z-index: 20; } | |
.twentytwenty-after { | |
z-index: 10; } | |
.twentytwenty-handle { | |
height: 38px; | |
width: 38px; | |
position: absolute; | |
left: 50%; | |
top: 50%; | |
margin-left: -22px; | |
margin-top: -22px; | |
border: 3px solid white; | |
-webkit-border-radius: 1000px; | |
-moz-border-radius: 1000px; | |
border-radius: 1000px; | |
-webkit-box-shadow: 0px 0px 12px rgba(51, 51, 51, 0.5); | |
-moz-box-shadow: 0px 0px 12px rgba(51, 51, 51, 0.5); | |
box-shadow: 0px 0px 12px rgba(51, 51, 51, 0.5); | |
z-index: 40; | |
cursor: pointer; } | |
.twentytwenty-horizontal .twentytwenty-handle:before { | |
bottom: 50%; | |
margin-bottom: 22px; | |
-webkit-box-shadow: 0 3px 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); | |
-moz-box-shadow: 0 3px 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); | |
box-shadow: 0 3px 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); } | |
.twentytwenty-horizontal .twentytwenty-handle:after { | |
top: 50%; | |
margin-top: 22px; | |
-webkit-box-shadow: 0 -3px 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); | |
-moz-box-shadow: 0 -3px 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); | |
box-shadow: 0 -3px 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); } | |
.twentytwenty-vertical .twentytwenty-handle:before { | |
left: 50%; | |
margin-left: 22px; | |
-webkit-box-shadow: 3px 0 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); | |
-moz-box-shadow: 3px 0 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); | |
box-shadow: 3px 0 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); } | |
.twentytwenty-vertical .twentytwenty-handle:after { | |
right: 50%; | |
margin-right: 22px; | |
-webkit-box-shadow: -3px 0 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); | |
-moz-box-shadow: -3px 0 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); | |
box-shadow: -3px 0 0 white, 0px 0px 12px rgba(51, 51, 51, 0.5); } | |
.twentytwenty-left-arrow { | |
border-right: 6px solid white; | |
left: 50%; | |
margin-left: -17px; } | |
.twentytwenty-right-arrow { | |
border-left: 6px solid white; | |
right: 50%; | |
margin-right: -17px; } | |
.twentytwenty-up-arrow { | |
border-bottom: 6px solid white; | |
top: 50%; | |
margin-top: -17px; } | |
.twentytwenty-down-arrow { | |
border-top: 6px solid white; | |
bottom: 50%; | |
margin-bottom: -17px; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment