JSFiddle - React, Tailwind, and code Playground
A/B Looper (Swipe)
by tonytlwu
HTML
<div id="currentTime">00:00.000</div>
<div class="clearfix">
<div class="pull-left">
<div>A time: <span id="aTime"></span>
</div>
<div>B time: <span id="bTime"></span>
</div>
</div>
<button id="loop" class="btn btn-primary">Jump to A</button>
</div>
<div class="form-inline">
<div class="checkbox-inline">
<label>
<input type="checkbox" id="slowscroll" />Scroll slower</label>
</div>
<div class="form-control-static">Play speed:</div>
<div class="radio-inline">
<label>
<input type="radio" value="0.5" name="speed" />× 0.5</label>
</div>
<div class="radio-inline">
<label>
<input type="radio" value="0.75" name="speed" />× 0.75</label>
</div>
<div class="radio-inline">
<label>
<input type="radio" value="1" name="speed" checked />× 1</label>
</div>
<div class="radio-inline">
<label>
<input type="radio" value="2" name="speed" />× 2</label>
</div>
</div>
<div id="aTimeSetter" class="waveScroller"><span class="img"></span>
</div>
<audio id="player" controls="" autobuffer="">
<!--<source src="http://traffic.libsyn.com/timferriss/final-timferrissshow-TF-5-morning-rituals___128kbps_REVISED.mp3">-->
<!--<source src="https://ec-media.sndcdn.com/6IXULTM2cJUy.128.mp3?f10880d39085a94a0418a7ef69b03d522cd6dfee9399eeb9a522059e69f0ba3a703f669b3c0f9d3e21f988a5db0ef9dd888459ba7b274bc2d0eac70adc9c5fd45bb8d37c1b">-->
<source src="https://ia600409.us.archive.org/26/items/TheWinstons-AmenBrother/B_The_Winstons_-_Amen_Brother.mp3">
</audio>
<div id="bTimeSetter" class="waveScroller"><span class="img"></span>
</div>
CSS
html {
width: 100%;
height: 100%;
}
body {
margin: 0;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.waveScroller {
width: 100%;
height: 174px;
overflow: hidden;
position: relative;
margin-bottom: 10px;
}
.waveScroller:after {
content:'';
display: block;
width: 1px;
height: 100%;
background: red;
position: absolute;
top: 0;
left: 50%;
}
.waveScroller .img {
display: block;
width: 2280px;
height: 174px;
background: url(https://s3.amazonaws.com/f.cl.ly/items/0F242622092Z1145103b/Screenshot%202015-09-19%2018.53.30.png) no-repeat center center;
position: absolute;
top: 0;
}
#aTimeSetter .img {
left: 50%;
}
#bTimeSetter .img {
right: 50%;
}
#player {
width: 100%;
}
#currentTime {
float: right;
font-family: monospace;
}
#aTime, #bTime {
font-family: monospace;
}
#loop {
margin-left: 10px;
margin-top: 2px;
}
</style> <meta name="viewport" content="width=device-width, initial-scale=1"> <style>
JavaScript
var aTimeDebug = document.getElementById('aTime');
var bTimeDebug = document.getElementById('bTime');
var currentTimeDebug = document.getElementById('currentTime');
if (typeof localStorage.getItem('aTime') === null || typeof localStorage.getItem('aTime') === 'object' || localStorage.getItem('aTime') === 'NaN') localStorage.setItem('aTime', '0');
if (typeof localStorage.getItem('bTime') === null || typeof localStorage.getItem('bTime') === 'object' || localStorage.getItem('bTime') === 'NaN') localStorage.setItem('bTime', '1');
var aTime = parseFloat(localStorage.getItem('aTime'));
var bTime = parseFloat(localStorage.getItem('bTime'));
var player = document.getElementById('player');
var counter = document.getElementById('counterDiv');
var slowscroll = false;
var slowscrollfactor = 0.1;
player.playbackRate = parseFloat($('[name="speed"]:checked').val());
$('[name="speed"]').on('change', function () {
player.playbackRate = parseFloat($('[name="speed"]:checked').val());
});
var relativeToAbsTime = function (relTime) {
var sec = (relTime * player.duration) % 60;
sec = sec.toFixed(3);
var min = Math.floor(relTime * player.duration / 60);
if (sec < 10) {
sec = '0' + sec;
}
if (min < 10) {
min = '0' + min;
}
return min + ':' + sec;
};
var isTouch = is_touch_device();
function is_touch_device() {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
var scrolling = false;
var maxWidth = 2280;
var aPos = 0;
var bPos = 1;
var aStartPos, bStartPos;
var startX;
aTimeDebug.innerHTML = relativeToAbsTime(aTime);
aPos = -aTime * maxWidth;
document.querySelector('#aTimeSetter .img').style.transform = 'translate3d(' + aPos + 'px,0px,0px)';
bTimeDebug.innerHTML = relativeToAbsTime(bTime);
bPos = (1 - bTime) * maxWidth;
document.querySelector('#bTimeSetter .img').style.transform = 'translate3d(' + bPos + 'px,0px,0px)';
var touchStartHandler = function...