Skip to content

Instantly share code, notes, and snippets.

@keithcollins
Created May 29, 2014 17:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keithcollins/a0564c578b9328fcdcbb to your computer and use it in GitHub Desktop.
Save keithcollins/a0564c578b9328fcdcbb to your computer and use it in GitHub Desktop.
Interval progress bar
<style type="text/css" media="screen">
#play-progress {
width: 910px;
margin-bottom: 20px;
background-color: #28AADE;
height: 36px;
position: relative;
border-radius: 20px;
}
#play-svg {
border-radius: 20px;
}
#progress-bar {
fill:#666;
}
#play-control {
width:37px;
height:36px;
background:url("http://www.bloomberg.com/image/idAx.BJxL1Lc.png") 37px 0px;
cursor: pointer;
position: absolute;
}
#play-control.play {
background:url("http://www.bloomberg.com/image/idAx.BJxL1Lc.png") 37px 0px;
}
#play-control.play:hover {
background:url("http://www.bloomberg.com/image/idAx.BJxL1Lc.png") 0px 0px;
}
#play-control.pause {
background:url("http://www.bloomberg.com/image/idAx.BJxL1Lc.png") 37px -36px;
}
#play-control.pause:hover {
background:url("http://www.bloomberg.com/image/idAx.BJxL1Lc.png") 0px -36px;
}
#play-control.replay {
background:url("http://www.bloomberg.com/image/idAx.BJxL1Lc.png") 37px -72px;
}
#play-control.replay:hover {
background:url("http://www.bloomberg.com/image/idAx.BJxL1Lc.png") 0px -72px;
}
#scrubber {
width:873px;
height:36px;
position:absolute;
top:0;
left:37px;
}
#display-data {
font-family: "arial","helvetica";
font-size: 60px;
color:#666;
}
</style>
<div id="play-progress">
<div id="play-control" class="play"></div>
<div id="scrubber"></div>
</div>
<div id="display-data">Hi</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script type="text/javascript">
// This uses window.setInterval() to loop through an array and update a progress bar accordingly.
// The idea is to make a data interactive work like a video. Sort of.
(function(){
// generate some data
var data = [];
var str = "abcdefghijklmnopqrstuvwxyz"
str.split("").forEach(function(d,i){
data.push({"index": i,"letter": d,});
});
// init some global vars
var data_index = 0;
var progress_width = 910;
var speed = 650;
var animation;
// add the progress bar svg
var progress = d3.select("#play-progress").append("svg:svg")
.attr("id","play-svg")
.attr("width", progress_width)
.attr("height", 36);
// append a rect, which will move to the right as the animation plays
// this creates the progress bar effect
progress.append("rect")
.attr("id","progress-bar")
.attr("width", progress_width)
.attr("height", 36)
.attr("x",0)
.attr("y",0);
// append line and text for mouseover
progress.append("line")
.attr("id","mouseline")
.attr("x1",0)
.attr("x2",0)
.attr("y1",0)
.attr("y2",36)
.style("stroke-width","2px")
.style("fill","#fff")
.style("opacity",0);
progress.append("text")
.attr("id","mousetext")
.attr("x",0)
.attr("y",15)
.style("fill","#fff")
.style("opacity",0);
// mouseover
$('#scrubber')
.on("mousemove",function(e) {
// figure out x position of mouse
var offset = $(this).offset();
var xpos = e.clientX - offset.left + 36;
// what percent across the rect is the mouse?
// multiply that by the length of the data to get the index
var scrub_index = Math.ceil(xpos/progress_width*data.length);
d3.select("#mouseline")
.style("opacity",1)
.attr("x1",xpos)
.attr("x2",xpos);
d3.select("#mousetext")
.style("opacity",1)
.attr("x",xpos+5)
.text(data[scrub_index].letter);
})
.on("mouseout",function(e) {
d3.select("#mouseline").style("opacity",0);
d3.select("#mousetext").style("opacity",0);
})
// on click do the same thing but update the data index with it
// then restart the animation from the selected index
.on("click",function(e) {
var offset = $(this).offset();
var xpos = e.clientX - offset.left + 36;
$("#play-control").removeClass().addClass("pause");
clearInterval(animation);
data_index = Math.ceil(xpos/progress_width*data.length);
animation = setInterval(function(){ play() }, speed);
});
// simple play, pause, replay stuff
d3.select("#play-control").on("click",function() {
current_class = $(this).attr("class");
if (current_class == "play") {
$(this).removeClass("play").addClass("pause");
animation = setInterval(function(){ play() }, speed);
} else if (current_class == "pause") {
$(this).removeClass("pause").addClass("play");
clearInterval(animation);
} else if (current_class == "replay") {
$(this).removeClass("replay").addClass("pause");
clearInterval(animation);
data_index = 0;
animation = setInterval(function(){ play() }, speed);
}
});
// this is the play function that is executed on each interval until the interval is cleared
// the speed variable at the top dictates how frequent the intervals are
function play() {
// update what is being displayed
d3.select("#display-data").html(data[data_index].letter);
// move the progress bar to the right
var progress_xpos = data_index/data.length*progress_width;
d3.select("#progress-bar").attr("x",progress_xpos);
// stop at end
if (data_index == data.length-1) {
$("#play-control").removeClass().addClass("replay");
d3.select("#progress-bar").attr("x",progress_width);
clearInterval(animation);
}
data_index = data_index + 1;
}
})()
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment