changeset 1339:f24d4b331f15

zoom keys, with animation. timeline duration tracks ascoltami Ignore-this: 70d99195ff0ce2da1c7d050304e1a006
author Drew Perttula <drewp@bigasterisk.com>
date Sat, 04 Jun 2016 23:17:50 +0000
parents 5ba5afe30817
children 0e9d8a1328d1
files light9/web/light9-music.coffee light9/web/timeline-elements.html light9/web/timeline.coffee
diffstat 3 files changed, 55 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/light9/web/light9-music.coffee	Sat Jun 04 22:38:30 2016 +0000
+++ b/light9/web/light9-music.coffee	Sat Jun 04 23:17:50 2016 +0000
@@ -24,9 +24,8 @@
       @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
--- a/light9/web/timeline-elements.html	Sat Jun 04 22:38:30 2016 +0000
+++ b/light9/web/timeline-elements.html	Sat Jun 04 23:17:50 2016 +0000
@@ -33,7 +33,11 @@
     </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>
--- a/light9/web/timeline.coffee	Sat Jun 04 22:38:30 2016 +0000
+++ b/light9/web/timeline.coffee	Sat Jun 04 23:17:50 2016 +0000
@@ -9,6 +9,7 @@
     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:
@@ -16,19 +17,23 @@
   _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)
@@ -66,11 +71,48 @@
         @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 = []