Skip to content

Instantly share code, notes, and snippets.

@tonyfast
Last active August 29, 2015 14:15
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 tonyfast/f2adb4aa6f0736d7bf00 to your computer and use it in GitHub Desktop.
Save tonyfast/f2adb4aa6f0736d7bf00 to your computer and use it in GitHub Desktop.
d3 + riotjs + structured data = affix behavior
- heading: Dog
body: >
alksdhflkajsdhf
- heading: Sean
body: >
Lorem ipsum dolor sit amet, ex sed paulo putent, cu sit integre epicurei petentium. Vel ea quem malis causae. Qui no odio prima definiebas. Quando vidisse feugiat vel eu, cum et dicit splendide, ea rebum eirmod est. Ne adhuc atqui definitionem quo, eum ceteros rationibus eu. Solet regione has cu, mea id alia posidonium.
Aeque soleat legimus ei sed, eos ut everti gubergren vituperatoribus. Ex veri sonet omnes pri. Cu mucius splendide ius. Ea sea soleat mnesarchum. Simul maiorum accumsan his et, ullum liber delicata eum an. Ad duo essent aliquid similique.
- heading: Freddie
body: >
Ferri tractatos suavitate cum ex, veri tritani dolorum ius id. Ut nullam deleniti nam, ea has dicit noster. Dicta percipitur efficiendi no est. Usu ex pericula mnesarchum.
Ne nobis affert pri, has ex partiendo maiestatis. Vix iudico nullam eruditi et, prima temporibus voluptatibus usu ut. An dolore essent mandamus eam, in scripta feugiat his, est ut ludus vivendo scaevola. Te veri fuisset sed. Eam ne everti maiorum, aeque insolens antiopam no vis, ut sonet iudico liberavisse cum.
Ad cum errem regione accusata. Ea pri graeco cetero. Pri at putent tritani aperiri, errem gubergren pri te. Ut his omnis primis labores. Partem legere complectitur mea at.
- heading: Tony
body: >
Augue maiorum fabellas sed cu. Vide solum graeco nam ea. Sea alia periculis interesset cu. Ea stet atqui choro quo. Sea patrioque vituperata cu. Te per homero saperet molestie, esse expetenda ex mea, ei dignissim tincidunt democritum vix.
Cibo liber aeque ne eum. Noster impetus bonorum ea vis, eum debitis deserunt democritum ut. Consetetur persequeris eos ex, est aperiri oportere incorrupte te. Ex est aliquip iracundia, amet sint voluptatibus eos te. In sale nostro usu, ne sed virtute luptatum.
- heading: Lee
body: >
Quo dolor civibus consectetuer ex, eos et facilisis dissentias. Iuvaret quaestio at eam, ea dolores phaedrum nam. An aliquam instructior nec. Per no cibo appellantur voluptatibus. Aliquid theophrastus nec ei, affert quidam conceptam te nam.
No malis iusto periculis vim, eos et inermis indoctum sententiae. Id cum novum habemus splendide. Ad platonem suscipiantur sea, meliore mnesarchum sea in. Ut qui tale explicari reformidans, ei nam maiorum argumentum. Vivendo moderatius disputando no eum, ea detraxit complectitur sed. Vix et eros justo tantas. Erant constituto ne ius.
- heading: Dirty
body: >
Dicam petentium ius in. Movet eruditi ex duo, veri ferri assueverit vis no, an dolorem percipitur comprehensam eam. Eu eam paulo congue dignissim. Mel in dictas iuvaret forensibus, his cu graece cetero. Tota porro expetenda te eos, fuisset scaevola assueverit usu no, amet justo omnesque eu vel.
<script src="//cdn.jsdelivr.net/g/d3js,riot@2.0(riot.min.js+compiler.min.js),coffeescript">
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/3.2.6/js-yaml.min.js"></script>
<div class="progress-svg"></div>
<div class="progress"></div>
<script type="text/coffeescript">
#{load data}
d3.text 'affix.yaml', (data) ->
data = jsyaml.load data
w = 600
#{populate page content}
#{ data is the index of the yaml content }
d3.select 'body'
.style 'margin', '100px'
.style 'width', w+'px'
.append 'div'
.classed 'affix-parent', true
.selectAll 'div.affix'
.style 'margin', '100px'
.style 'z-index',10
.data d3.range( data.length )
.call (s) ->
s.enter()
.append 'div'
.classed 'affix', true
.each (i) ->
riot.mountTo this, 'snippet', data[i]
#{ extent of div }
#{ div offset to compute scroll position }
#{ ordinal scale for the progress positions }
affixoffsets = d3.select '.affix-parent'
.selectAll('.affix')[0] #{What is the coffeescript?}
.map (s) ->
#{offset is unnecessary with clamping}
s.offsetTop
d3scrollscale = d3.scale.linear()
.domain affixoffsets
.range d3.range( affixoffsets.length )
.clamp true
scrollscale = ( v ) ->
Math.floor( d3scrollscale( v ) )
prog = d3.select('.progress')
snippet = prog
.style 'position', 'fixed'
.style 'left', '0px'
.style 'top', '0px'
.style 'display', 'flex'
.style 'height', '50px'
.style 'width', w+'px'
.style 'padding', '0px'
.style 'z-index', 0
.style 'align-items', 'stretch'
.style 'justify-content', 'space-between'
.style 'border-width', '1px'
.style 'border-style', 'solid'
.selectAll '.snippet'
toffset = 100;
snippet
.data affixoffsets
.enter()
.append 'button'
.classed 'snippet', true
.style 'background-color', 'white'
.style 'opacity', .1
.style 'border-width', '1px'
.style 'border-style', 'solid'
.style 'order', (offset) ->
#{ the order can scale with the offset }
#{ default to one}
1
.style 'flex-grow', 1
.style 'float','left'
.style 'font-color','white'
.style 'font-size','22px'
.text (i) ->
scrollscale(i)
.call (s) ->
#{ click listener }
s.on 'click', (p) ->
console.log 'a'
scrollTo 0, p - toffset #{offset}
colors = d3.scale.category20()
#{ scroll listener }
d3.select document
.on 'scroll', () ->
#{ svg listener }
d3.select 'line.dial'
.attr 'x1', ()->
svgscrollscale( window.scrollY )
.attr 'x2', ()->
svgscrollscale( window.scrollY )
#{ flexbox listener }
prog.selectAll('.snippet')
.each (i) ->
i = scrollscale(i)
if i == scrollscale( window.scrollY + toffset )
d3.select this
.style 'background-color', colors(i)
.style 'opacity', .9
.style 'color','black'
else
d3.select this
.style 'background-color', 'white'
.style 'opacity', .1
svgscrollscale = d3.scale.linear()
.domain d3.extent( affixoffsets )
.range [0,w]
.clamp true
snippet = d3.select '.progress-svg'
.style 'position', 'fixed'
.style 'left', '0px'
.style 'top', '0px'
.append 'svg'
.attr 'width', w
.attr 'height', 100
.call (s)->
s.selectAll '.anchor'
.data affixoffsets
.enter()
.append 'circle'
.style 'opacity', .6
.attr 'cx', (d)->
svgscrollscale( d )
.attr 'cy', 50
.attr 'r', 30
.attr 'fill', (d,i)->
colors i
.call (s)->
s.selectAll '.dial'
.data( [window.scrollY] )
.call (s) ->
s.enter()
.append 'line'
.classed 'dial', true
.attr 'x1', 50
.attr 'x2', 50
.attr 'y2', 10
.attr 'y1', 90
.attr 'stroke-width', 2
.attr 'stroke', 'black';
</script>
<script type="riot/tag">
<snippet>
<div class="heading"><h1>{this.opts.heading}</h1></div>
<div class="context" style="font-size:40px;">{this.opts.body}</div>
</snippet>
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment