var versions = [ "The quick brown fox jumped over the lazy dog.", "The fox jumped over the dog.", "The vulpine jumped over the canine.", "The cow jumped over the moon.", "The moon blows up in the most recent Neal Stephenson novel.", "The most recent Neal Stephenson novel is pretty good but pretty long.", "The most recent Neal Stephenson novel is pretty good but pretty long. It has a lot of detail about space colonies.", "The most recent Neal Stephenson novel is pretty good but pretty long. It has probably too much detail about space colonies.", "The most recent Neal Stephenson novel is pretty good but pretty long. It has probably too much detail about space colonies, but that’s par for the course with his novels.", "The most recent Neal Stephenson novel, Seveneves, is pretty good but pretty long. It has probably too much detail about space colonies, but that’s par for the course with his novels.", "The most recent Neal Stephenson novel, Seveneves (a palindrome, which might be a little too clever), is pretty good but pretty long. It has probably too much detail about space colonies, but that’s par for the course with his novels.", "The most recent Neal Stephenson novel, Seveneves (a palindrome, which might be a little too clever--but does make sense in context), is pretty good but pretty long. It has probably too much detail about space colonies, but that’s par for the course with his novels.", "The most recent Neal Stephenson novel is pretty good.", "The most recent Neal Stephenson novel is not a fast read but doesn’t jump around.", "The most recent Neal Stephenson novel is not a fast read but doesn’t jump over the moon, that’s for sure.", "Neal Stephenson’s novel doesn’t jump over the moon, that’s for sure.", "The cow jumped over the moon, that’s for sure.", "The fox jumped over the moon, that’s for sure.", "The quick fox jumped over the moon.", "The quick brown fox jumped over the lazy moon.", "The quick brown fox jumped over the lazy dog." ] var versions = [ // 'The goal of version control software is to track changes to code, correlated with individuals who made the changes. There may be thousands, even hundreds of thousands of such changes in a source-code repository. Some changes are large, with many thousands of lines of code added, while some are just cleaning up idle spaces or fixing typos. So over time teams build up a massive database of code changes that functions as a kind of undo. You can restore an older state, even if that involves changing thousands of files, in case there is a bug. You can see who introduced the bug.', // 'In my opinion, version control is very beautiful. It is frankly one of the most beautiful thing about programming. It\'s not like “track changes” in Microsoft Word. That is a shameful monstrosity that can make even a powerful computer stutter. Version control is software about working, and it is a tool for understanding how ideas evolve over time, how mistakes are made and fixed. It is a record of the imperfect nature of human effort that is simultaneously an expression of the human desire towards excellence and understanding.', 'In my opinion, version control is one of the most beautiful things about programming. It\'s not like “track changes” in Microsoft Word. That is a shameful monstrosity that can make even a powerful computer stutter. Version control is software about working, and it is a tool for understanding how ideas evolve over time, how mistakes are made and fixed. It is a record of the imperfect nature of human effort that is simultaneously an expression of the human desire towards excellence and understanding.', 'In my opinion, version control is one of the most beautiful things about programming. It\'s not like “track changes” in Microsoft Word. That is a shameful monstrosity that can make even a powerful computer stutter. Version control is software about working, and it is a tool for understanding how ideas evolve over time, how mistakes are made and fixed.', 'In my opinion, version control is one of the most beautiful things about programming. It’s one of code culture’s gifts to the world. Version control is not like “track changes” in Microsoft Word. That is a shameful monstrosity that can make even a powerful computer stutter, something only a lawyer could love. No, version control is something different---', 'In my opinion, version control is one of the most beautiful things about programming. It’s one of code culture’s gifts to the world. Version control is not like “track changes” in Microsoft Word. That’s a shameful monstrosity that can make even a powerful computer stutter, something only a lawyer could love. No, version control is something different ...', 'In my opinion, version control is one of the most beautiful things about programming. It’s one of code culture’s gifts to the world. Version control isn\'t like “track changes” in Microsoft Word. That’s a shameful monstrosity that can make even a powerful computer stutter, something only a lawyer could love. No, version control is something different.' ] var diffs = [] versions.forEach(function(v, i){ var p = i ? versions[i-1] : _.last(versions) diffs.push(JsDiff.diffWords(p, v)) }) var puncuation = '.-,)-,’’'.split('') var widths = {} function diffToWords(diff){ var rv = [] diff.forEach(function(obj, i){ obj.value.split('').forEach(function(chr, j, array){ var lastChar = '' var nextChar = ''; k = 1 // TODO fix spacing on evolve if (j == array.length - 1){ nextChar = diff[i + k] ? diff[i + k].value[0] : '' while(diff[i + k] && (diff[i + k].removed || diff[i + k].added)){ k++ nextChar = diff[i + k] ? diff[i + k].value[0] : '' } } if (nextChar){ lastChar = _.contains(puncuation, nextChar) ? '' : '' } rv.push({ value: chr + lastChar, added: obj.added, removed: obj.removed, width: obj.width, obj: obj }) }) }) d3.select('#width-calc').append('div') .style('width', '100000px') .style('margin-top', '10px') .dataAppend(rv, 'div').append('div') .text(ƒ('value')) .each(function(d){ if (widths[d.value]) return d.width = widths[d.value] console.log(d) d.width = this.getBoundingClientRect().width d.width = (d.value == ' ' ? 4.5 : d.width) + 'px' widths[d.value] = d.width }) return rv } var s = .5 var curValue = 0 function updateFalling(curDiffIndex, isAuto){ if (isAuto && !autoPlay) return d3.select('#curindex').text(curDiffIndex) curValue = curDiffIndex var wordDiffs = diffToWords(diffs[curDiffIndex]) sliderHandle.style("left", x(curValue) + "px") if (true || module.active){ d3.selectAll('#text-diff').html('') d3.select('#text-diff').dataAppend(wordDiffs, 'div.falling') .html(function(d){ return d.value == ' ' ? '  ' : d.value }) .style('opacity', function(d){ return d.value == ' ' ? '0' : '1' }) .style('width', function(d){ return d.added ? '0.0px' : d.width }) .style('left', function(d){ return d.added ? '-2000px' : '0px' }) .transition().duration(0).delay(500*s) .style('color', function(d){ return d.added ? 'green' : d.removed ? 'red' : '' }) .transition().duration(2000*s).delay(1000*s) .style('width', function(d){ return d.removed ? '0.0px' : d.width }) .style('left', function(d){ return d.removed ? '2000px' : '0px' }) curDiffIndex = ++curDiffIndex % diffs.length } if (autoPlay) window.setTimeout(function(){ updateFalling(curDiffIndex, true) }, 5500*s) } var width = 500; var x = d3.scale.linear() .domain([0, diffs.length - 1]) .range([0, width]) .clamp(true); var dispatch = d3.dispatch("sliderChange"); var slider = d3.select(".slider") .style("width", width + "px"); var sliderTray = slider.append("div") .attr("class", "slider-tray"); var sliderHandle = slider.append("div") .attr("class", "slider-handle"); sliderHandle.append("div") .attr("class", "slider-handle-icon") slider.call(d3.behavior.drag() .on("dragstart", function() { dispatch.sliderChange(x.invert(d3.mouse(sliderTray.node())[0])); d3.event.sourceEvent.preventDefault(); }) .on("drag", function() { dispatch.sliderChange(x.invert(d3.mouse(sliderTray.node())[0])); })); dispatch.on("sliderChange.slider", function(value) { autoPlay = false value = Math.round(value) if (value != curValue) updateFalling(value) }); d3.select('#play-button').on('click', function(){ autoPlay = !autoPlay if (autoPlay) updateFalling(curValue + 1 % diffs.length) }) var autoPlay = true updateFalling(0)