Skip to content

Instantly share code, notes, and snippets.

@dimsemenov
Created October 27, 2017 21:08
Show Gist options
  • Save dimsemenov/81278bc32ecab8fb1f799d97fa4c16c1 to your computer and use it in GitHub Desktop.
Save dimsemenov/81278bc32ecab8fb1f799d97fa4c16c1 to your computer and use it in GitHub Desktop.
Before/After image viewer, will probably create a separate repo for it some day... (c)
img {
margin: 0;
padding: 0;
display: block;
}
.ba-viewer {
overflow: hidden;
position: relative;
width: 100%;
max-width: 400px;
height: auto;
margin: 0 auto;
touch-action: pan-y pinch-zoom;
cursor: ew-resize;
}
.ba-viewer__before-img {
width: 100%;
position: absolute;
}
.ba-viewer__after-img {
width: 100%;
}
.ba-viewer__after-container {
position: absolute;
position: relative;
width: 100%;
overflow: hidden;
}
.ba-viewer__divider {
color: #FFF;
position: absolute;
left: 0;
top: 0;
width: 2px;
margin-left: -1px;
height: 100%;
background: currentColor;
will-change: transform;
}
.ba-viewer__divider:before,
.ba-viewer__divider:after {
content: '';
position: absolute;
left: 0;
top: 50%;
border: 10px solid transparent;
border-top-width: 6px;
border-bottom-width: 6px;
}
.ba-viewer__divider:before {
border-right-color: currentColor;
left: -25px
}
.ba-viewer__divider:after {
border-left-color: currentColor;
left: 7px
}
<div class="ba-viewer">
<img draggable="false" class="ba-viewer__before-img" src="https://dummyimage.com/400x300/000/fff.png&text=image+1" />
<div class="ba-viewer__after-container">
<img draggable="false" class="ba-viewer__after-img" src="https://dummyimage.com/400x300/000/fff.png&text=image+2" />
</div>
<div class="ba-viewer__divider"></div>
</div>
(function(window) {
'use strict';
var toggleEvent = function(el, name, fn, unbind) {
var methodName = (unbind ? 'remove' : 'add') + 'EventListener';
el[methodName](name, fn, false);
};
var setTransformX = function(el, x) {
el.style.transform = 'translateX(' + (x )+ 'px)';
};
window.BeforeAfterViewer = function () {
var self = this;
var viewer;
var rect;
var container;
var afterImage;
var divider;
var isPointerDown;
var isMouse;
self.init = function (viewerEl, pos = 0.5) {
viewer = viewerEl;
container = viewer.querySelector('.ba-viewer__after-container');
afterImage = viewer.querySelector('.ba-viewer__after-img');
divider = viewer.querySelector('.ba-viewer__divider');
self.position = pos;
toggleEvents();
self.resize();
};
self.setPosition = function (pos /* 0 - 1 */) {
if(pos < 0) {
pos = 0;
} else if(pos > 1) {
pos = 1;
}
var x = rect.width * pos;
setTransformX(afterImage, -x);
setTransformX(container, x);
setTransformX(divider, x);
};
self.resize = function() {
rect = viewer.getBoundingClientRect();
self.setPosition(self.position);
};
function onPointerUpdate(pointerPageX) {
self.setPosition( (pointerPageX - rect.left) / rect.width);
}
function toggleEvents(remove) {
toggleEvent(window, 'resize', self.resize, remove);
toggleEvent(viewer, 'mousedown', pointerDown, remove);
toggleEvent(viewer, 'touchstart', pointerDown, remove);
if(remove) {
toggleMoveUpCancelEvents(isMouse, true);
}
}
function toggleMoveUpCancelEvents(isMouse, remove) {
if(isMouse) {
toggleEvent(window, 'mousemove', pointerMove, remove);
toggleEvent(window, 'mouseup', pointerUp, remove);
} else {
toggleEvent(window, 'touchmove', pointerMove, remove);
toggleEvent(window, 'touchend', pointerUp, remove);
toggleEvent(window, 'touchcancel', pointerUp, remove);
}
}
function pointerDown(e) {
if(isPointerDown) {
return;
}
isPointerDown = true;
isMouse = e.type.indexOf('mouse') > -1;
if(isMouse && e.button > 0) {
// drag only via left mouse button
return;
}
onPointerUpdate(isMouse ? e.pageX : e.touches[0].pageX);
toggleMoveUpCancelEvents(isMouse);
}
function pointerMove(e) {
onPointerUpdate(isMouse ? e.pageX : e.touches[0].pageX);
}
function pointerUp(e) {
isPointerDown = false;
toggleMoveUpCancelEvents(isMouse, true);
}
};
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment