Changeset - f24d4b331f15
[Not reviewed]
default
0 3 0
Drew Perttula - 9 years ago 2016-06-04 23:17:50
drewp@bigasterisk.com
zoom keys, with animation. timeline duration tracks ascoltami
Ignore-this: 70d99195ff0ce2da1c7d050304e1a006
3 files changed with 55 insertions and 10 deletions:
0 comments (0 inline, 0 general)
light9/web/light9-music.coffee
Show inline comments
 
@@ -21,15 +21,14 @@ Polymer
 
    @$.getTime.addEventListener 'error', (e) =>
 
      req = @$.getTime.lastRequest
 
      @status = "✘"
 
      @statusTitle = "GET "+req.url+ " -> " + req.status + " " + req.statusText
 
      setTimeout(@poll.bind(@), 2000)
 
    @poll()
 
    setInterval(@estimateTimeLoop.bind(@), 50)
 
    setInterval(@estimateTimeLoop.bind(@), 30)
 
    
 

	
 
  estimateTimeLoop: ->
 
    if @playing
 
      @t = @remoteT + (Date.now() - @remoteAsOfMs) / 1000
 
    else
 
      @t = @remoteT
 
    
light9/web/timeline-elements.html
Show inline comments
 
@@ -30,13 +30,17 @@
 
         position: absolute;
 
         left: 0; top: 0; right: 0; bottom: 0;
 
     }
 
    </style>
 
    <div>
 
      <rdfdb-synced-graph graph="{{graph}}"></rdfdb-synced-graph>
 
      <light9-music id="music" song="{{song}}" t="{{songTime}}" playing="{{songPlaying}}"></light9-music>
 
      <light9-music id="music"
 
                    song="{{song}}"
 
                    t="{{songTime}}"
 
                    playing="{{songPlaying}}"
 
                    duration="{{songDuration}}"></light9-music>
 
      timeline editor: song [{{song}}] <button>unlink</button>
 
      <label><input type="checkbox"> follow player song choice</label>
 
    </div>
 
    <div>[[debug]]</div>
 
    <!--
 
         Old zoom menu:
light9/web/timeline.coffee
Show inline comments
 
@@ -6,32 +6,37 @@ Polymer
 
  properties:
 
    viewState: { type: Object }
 
    debug: {type: String}
 
    graph: {type: Object, notify: true}
 
    song: {type: String, notify: true}
 
    songTime: {type: Number, notify: true, observer: '_onSongTime'}
 
    songDuration: {type: Number, notify: true, observer: '_onSongDuration'}
 
    songPlaying: {type: Boolean, notify: true}
 
  width: ko.observable(1)
 
  listeners:
 
    'iron-resize': '_onIronResize'
 
  _onIronResize: ->
 
    @width(@offsetWidth)
 
  _onSongTime: (t) ->
 
    @viewState.cursor.t(t) if @viewState
 
    @viewState.cursor.t(t)
 
  _onSongDuration: (d) ->
 
    @viewState.zoomSpec.duration(d)
 

	
 
  attached: ->
 
    @dia = @$.dia
 
  ready: ->
 
    @viewState =
 
      zoomSpec:
 
        duration: ko.observable(190)
 
        t1: ko.observable(102)
 
        t2: ko.observable(161)
 
        duration: ko.observable(100)
 
        t1: ko.observable(0) # need validation to stay in bounds and not go too close
 
        t2: ko.observable(100)
 
      cursor:
 
        t: ko.observable(105)
 
        t: ko.observable(20)
 
      mouse:
 
        pos: ko.observable($V([0,0]))
 
    
 
  attached: ->
 
    @dia = @$.dia
 

	
 
    ko.computed =>
 
      @debug = ko.toJSON(@viewState)
 

	
 
    ko.computed =>
 
      @fullZoomX = d3.scaleLinear().domain([0, @viewState.zoomSpec.duration()]).range([0, @width()])
 
@@ -63,17 +68,54 @@ Polymer
 
          ev = ev.touches[0]
 

	
 
        @root = @getBoundingClientRect()
 
        @viewState.mouse.pos($V([ev.pageX - @root.left, ev.pageY - @root.top]))
 

	
 
        @$.dia.setMouse(@viewState.mouse.pos())
 

	
 
  animatedZoom: (newT1, newT2, secs) ->
 
    fps = 30
 
    oldT1 = @viewState.zoomSpec.t1()
 
    oldT2 = @viewState.zoomSpec.t2()
 
    lastTime = 0
 
    for step in [0..secs * fps]
 
      frac = step / (secs * fps)
 
      do (frac) =>
 
        gotoStep = =>
 
          @viewState.zoomSpec.t1((1 - frac) * oldT1 + frac * newT1)
 
          @viewState.zoomSpec.t2((1 - frac) * oldT2 + frac * newT2)
 
          console.log('to', frac, @viewState.zoomSpec.t1(), @viewState.zoomSpec.t2())
 
        delay = frac * secs * 1000
 
        setTimeout(gotoStep, delay)
 
        lastTime = delay
 
    setTimeout(=>
 
        @viewState.zoomSpec.t1(newT1)
 
        @viewState.zoomSpec.t2(newT2)
 
      , lastTime + 10)
 
      
 
    
 
  bindKeys: ->
 
    
 
    shortcut.add "Ctrl+P", (ev) =>
 
      @$.music.seekPlayOrPause(@zoomInX.invert(@viewState.mouse.pos().e(1)))
 

	
 
    zoomAnimSec = .2
 
    shortcut.add "Ctrl+Escape", =>
 
      @animatedZoom(0, @viewState.zoomSpec.duration(), zoomAnimSec)
 
    shortcut.add "Shift+Escape", =>
 
      @animatedZoom(@songTime - 2, @viewState.zoomSpec.duration(), zoomAnimSec)
 
    shortcut.add "Escape", =>
 
      zs = @viewState.zoomSpec
 
      visSeconds = zs.t2() - zs.t1()
 
      margin = visSeconds * .4
 
      # buggy: really needs t1/t2 to limit their ranges
 
      if @songTime < zs.t1() or @songTime > zs.t2() - visSeconds * .6
 
        newCenter = @songTime + margin
 
        @animatedZoom(newCenter - visSeconds / 2,
 
                      newCenter + visSeconds / 2, zoomAnimSec)
 

	
 
  persistDemo: ->
 
    ctx = @graph.Uri('http://example.com/')
 
    adjs = []
 
    for n in [0..7]
 
      subj = @graph.Uri(':demoResource'+n)
 
      adjs.push(new AdjustableFloatObject({
0 comments (0 inline, 0 general)