Changeset - e4825767a4bf
[Not reviewed]
default
0 4 0
Drew Perttula - 9 years ago 2016-06-04 07:43:45
drewp@bigasterisk.com
fixes to RDF adjusters. put graph load in an element.
Ignore-this: dfe48e2553769b4dfe17fc9041798e51
4 files changed with 121 insertions and 79 deletions:
0 comments (0 inline, 0 general)
light9/web/adjustable.coffee
Show inline comments
 
@@ -45,6 +45,22 @@ class Adjustable
 
  endDrag: () ->
 
    0
 

	
 
  _editorCoordinates: () -> # vec2 of mouse relative to <l9-t-editor>
 
    ev = d3.event.sourceEvent
 

	
 
    if ev.target.tagName == "LIGHT9-TIMELINE-EDITOR"
 
      rootElem = ev.target
 
    else
 
      rootElem = ev.target.closest('light9-timeline-editor')
 

	
 
    # storing root on the object to remember it across calls in case
 
    # you drag outside the editor.
 
    @root = rootElem.getBoundingClientRect() if rootElem
 
    offsetParentPos = $V([ev.pageX - @root.left, ev.pageY - @root.top])
 

	
 
    setMouse(offsetParentPos) # for debugging
 
    return offsetParentPos 
 

	
 
class window.AdjustableFloatObservable extends Adjustable
 
  constructor: (@config) ->
 
    # config also has:
 
@@ -55,26 +71,10 @@ class window.AdjustableFloatObservable e
 
  _getValue: () ->
 
    @config.observable()
 

	
 
  _editorCoordinates: () -> # vec2 of mouse relative to <l9-t-editor>
 
    ev = d3.event.sourceEvent
 

	
 
    if ev.target.tagName == "LIGHT9-TIMELINE-EDITOR"
 
      rootElem = ev.target
 
    else
 
      rootElem = ev.target.closest('light9-timeline-editor')
 
    
 
    @root = rootElem.getBoundingClientRect() if rootElem
 
    offsetParentPos = $V([ev.pageX - @root.left, ev.pageY - @root.top])
 

	
 
    setMouse(offsetParentPos)
 
    return offsetParentPos 
 
    
 
  continueDrag: (pos) ->
 
    # pos is vec2 of pixels relative to the drag start.
 

	
 
    epos = @_editorCoordinates()
 
    log('offsetParentPos', epos.elements)
 
    
 
    newValue = @config.getValueForPos(epos)
 
    @config.observable(newValue)
 

	
 
@@ -85,14 +85,21 @@ class window.AdjustableFloatObservable e
 

	
 
class window.AdjustableFloatObject extends Adjustable
 
  constructor: (@config) ->
 
    # config has graph, subj, pred, ctx, getSuggestedTargetOffset
 
    # config also has:
 
    #   graph
 
    #   subj
 
    #   pred
 
    #   ctx
 
    #   getTargetTransform(value) -> getTarget result for value
 
    #   getValueForPos
 

	
 
    super(@config)
 

	
 
  _getValue: () -> # for drag math
 
  _getValue: () ->
 
    @config.graph.floatValue(@config.subj, @config.pred)
 

	
 
  getCenter: () ->    
 
    $V([100 + 200 * @_getValue(), 200])
 
  getTarget: () ->
 
    @config.getTargetTransform(@_getValue())
 

	
 
  subscribe: (onChange) ->
 
    @config.graph.subscribe @config.subj, @config.pred, null, (patch) =>
 
@@ -101,5 +108,5 @@ class window.AdjustableFloatObject exten
 
  continueDrag: (pos) ->
 
    # pos is vec2 of pixels relative to the drag start
 
    
 
    newValue = @dragStartValue + pos.e(1) / 200
 
    newValue = @config.getValueForPos(@_editorCoordinates())
 
    @config.graph.patchObject(@config.subj, @config.pred, @config.graph.Literal(newValue), @_ctx)
light9/web/graph.coffee
Show inline comments
 
@@ -65,9 +65,9 @@ class window.SyncedGraph
 

	
 
  applyAndSendPatch: (patch, cb) ->
 
    @applyPatch(patch)
 
    #console.log('patch to server:')
 
    #console.log('  delete:', JSON.stringify(patch.delQuads))
 
    #console.log('  add:', JSON.stringify(patch.addQuads))
 
    console.log('patch to server:')
 
    console.log('  delete:', JSON.stringify(patch.delQuads))
 
    console.log('  add:', JSON.stringify(patch.addQuads))
 
    # post to server
 

	
 
  applyPatch: (patch) ->
light9/web/timeline-elements.html
Show inline comments
 
@@ -2,6 +2,42 @@
 
<link rel="import" href="light9-timeline-audio.html">
 
<link rel="import" href="/lib/iron-resizable-behavior/iron-resizable-behavior.html">
 

	
 
<dom-module id="rdfdb-synced-graph">
 
  <template>
 
    <style>
 
     :host { display: none; }
 
    </style>
 
  </template>
 
  <script src="graph.js"></script>
 
  <script>
 
   Polymer({
 
       is: "rdfdb-synced-graph",
 
       properties: {
 
           graph: {type: Object, notify: true}
 
       },
 
       ready: function() {
 
           this.graph = new SyncedGraph('noServerYet', {
 
               '': 'http://light9.bigasterisk.com/',
 
               'xsd': 'http://www.w3.org/2001/XMLSchema#',
 
           });
 
           this.graph.loadTrig(
 
'          @prefix : <http://light9.bigasterisk.com/> .'+
 
'          @prefix dev: <http://light9.bigasterisk.com/device/> .'+
 
'          <http://example.com/> {'+
 
'            :demoResource0 :startTime 1; :endTime 120 .'+
 
'            :demoResource1 :startTime 13; :endTime 16 .'+
 
'            :demoResource2 :startTime 38; :endTime 60 .'+
 
'            :demoResource3 :startTime 56; :endTime 60 .'+
 
'            :demoResource4 :startTime 73; :endTime 74 .'+
 
'            :demoResource5 :startTime 91; :endTime 105 .'+
 
'            :demoResource6 :startTime 110; :endTime 120 .'+
 
'            :demoResource7 :startTime 133; :endTime 140 .'+
 
'          }');
 
       }
 
   });
 
  </script>
 
</dom-module>
 

	
 
<!-- Whole editor- include this on your page.
 
     Most coordinates are relative to this element.
 
   -->
 
@@ -14,6 +50,7 @@
 
         flex-direction: column;
 
         position: relative;
 
         border: 1px solid black;
 
         overflow: hidden;
 
     }
 
     light9-timeline-audio {
 
         width: 100%;
 
@@ -33,6 +70,9 @@
 
         }
 
    </style>
 
    <div>
 
      <rdfdb-synced-graph graph="{{graph}}">
 
       
 
      </rdfdb-synced-graph>
 
      timeline editor: song [uri] <button>unlink</button>
 
      <label><input type="checkbox"> follow player song choice</label>
 
    </div>
 
@@ -251,16 +291,6 @@
 
      <light9-timeline-adjuster dia="{{dia}}" adj="{{item}}"></light9-timeline-adjuster>
 
    </template>
 
  </template>
 
  <script>
 
   Polymer({
 
       is: "light9-timeline-adjusters",
 
       properties: {
 
           adjs: { type: Array },
 
           dia: { type: Object }
 
           
 
       }
 
   });
 
  </script>
 
</dom-module>
 

	
 
<!-- Yellow dotted handle that you can adjust to edit something.
 
@@ -302,7 +332,7 @@
 
         -webkit-user-select: none;
 
     }
 
     span.empty {
 
         width: 30px;
 
         width: 30px; /* todo: supposed to fill the whole visible section*/
 
         height: 13px;
 
         display: inline-block;
 
         background: rgba(0,0,0,0);
 
@@ -337,6 +367,5 @@
 
<script src="/lib/d3/build/d3.js"></script>
 
<script src="/lib/N3.js/browser/n3-browser.js"></script>
 
<script src="/lib/knockout/dist/knockout.js"></script>
 
<script src="graph.js"></script>
 
<script src="adjustable.js"></script>
 
<script src="timeline.js"></script>
light9/web/timeline.coffee
Show inline comments
 
log = console.log
 
window.graph = new SyncedGraph('noServerYet', {
 
'': 'http://light9.bigasterisk.com/',
 
'xsd', 'http://www.w3.org/2001/XMLSchema#',
 
  })
 
  
 
window.graph.loadTrig("
 
@prefix : <http://light9.bigasterisk.com/> .
 
@prefix dev: <http://light9.bigasterisk.com/device/> .
 

	
 
<http://example.com/> {
 
  :demoResource :startTime 110; :endTime 120 .
 
}
 
    ")
 

	
 
    
 
      
 
Polymer
 
  is: 'light9-timeline-editor'
 
@@ -21,6 +6,7 @@ Polymer
 
  properties:
 
    viewState: { type: Object }
 
    debug: {type: String}
 
    graph: {type: Object, notify: true}
 
    
 
  attached: ->
 
    @dia = @$.dia
 
@@ -36,44 +22,50 @@ Polymer
 
      @debug = ko.toJSON(@viewState)
 

	
 
    ko.computed =>
 
      @fullZoomX = d3.scaleLinear().domain([0, @viewState.zoomSpec.duration()]).range([0, @offsetWidth]) # need to update this if width changes or if duration changes
 
      @zoomInX = d3.scaleLinear().domain([@viewState.zoomSpec.t1(), @viewState.zoomSpec.t2()]).range([0, @offsetWidth]) # need to update this if width changes or if duration changes
 
      # todo: need to trigger this when @offsetWidth changes, too
 
      @fullZoomX = d3.scaleLinear().domain([0, @viewState.zoomSpec.duration()]).range([0, @offsetWidth])
 
      @zoomInX = d3.scaleLinear().domain([@viewState.zoomSpec.t1(), @viewState.zoomSpec.t2()]).range([0, @offsetWidth])
 
      @$.adjusters.updateAllCoords()
 

	
 
    animCursor = () => 
 
      #@viewState.cursor.t = 130 + 20 * Math.sin(Date.now() / 2000)
 
      @viewState.cursor.t = 130 + 20 * Math.sin(Date.now() / 2000)
 
      @$.dia.setCursor(@$.audio.offsetTop, @$.audio.offsetHeight,
 
                       @$.zoomed.$.time.offsetTop,
 
                       @$.zoomed.$.time.offsetHeight,
 
                       @fullZoomX, @zoomInX, @viewState.cursor)
 

	
 
      @viewState.zoomSpec.t1(80 + 10 * Math.sin(Date.now() / 3000))
 
      #@viewState.zoomSpec.t1(80 + 10 * Math.sin(Date.now() / 3000))
 
      
 
    #setInterval(animCursor, 50)
 
    setInterval(animCursor, 50)
 

	
 
    setTimeout(() =>
 
      @adjs = @makeZoomAdjs().concat(@persistDemo())
 
    , 100)
 
    , 500)
 

	
 
  persistDemo: ->
 
    ctx = graph.Uri('http://example.com/')
 
    return [
 
      new AdjustableFloatObject({
 
        graph: graph
 
        subj: graph.Uri(':demoResource')
 
        pred: graph.Uri(':startTime')
 
    ctx = @graph.Uri('http://example.com/')
 
    adjs = []
 
    for n in [0..7]
 
      subj = @graph.Uri(':demoResource'+n)
 
      adjs.push(new AdjustableFloatObject({
 
        graph: @graph
 
        subj: subj
 
        pred: @graph.Uri(':startTime')
 
        ctx: ctx
 
        getTarget: () => $V([200, 300])
 
        getTargetTransform: (value) => $V([@zoomInX(value), 300])
 
        getValueForPos: (pos) => @zoomInX.invert(pos.e(1))
 
        getSuggestedTargetOffset: () => $V([-30, 80])
 
      })
 
      new AdjustableFloatObject({
 
        graph: graph
 
        subj: graph.Uri(':demoResource')
 
        pred: graph.Uri(':endTime')
 
      }))
 
      adjs.push(new AdjustableFloatObject({
 
        graph: @graph
 
        subj: subj
 
        pred: @graph.Uri(':endTime')
 
        ctx: ctx
 
        getTarget: () => $V([300, 300])
 
        getTargetTransform: (value) => $V([@zoomInX(value), 300])
 
        getValueForPos: (pos) => @zoomInX.invert(pos.e(1))
 
        getSuggestedTargetOffset: () => $V([30, 100])
 
      })
 
      ]
 
      }))
 
    return adjs
 

	
 
  makeZoomAdjs: ->
 
    yMid = @$.audio.offsetTop + @$.audio.offsetHeight / 2
 
@@ -120,6 +112,17 @@ Polymer
 
      
 
    return [left, right, pan]
 

	
 

	
 
Polymer
 
  is: "light9-timeline-adjusters"
 
  properties:
 
    adjs: { type: Array },
 
    dia: { type: Object }
 
  updateAllCoords: ->
 
    for elem in @querySelectorAll('light9-timeline-adjuster')
 
      elem.updateDisplay()
 
    
 

	
 
_adjusterSerial = 0
 

	
 
Polymer
 
@@ -141,7 +144,9 @@ Polymer
 
      value: ''
 

	
 
  onAdj: (adj) ->
 
    @adj.subscribe () =>
 
    @adj.subscribe(@updateDisplay.bind(this))
 

	
 
  updateDisplay: () ->
 
      @spanClass = if @adj.config.emptyBox then 'empty' else ''
 
      @displayValue = @adj.getDisplayValue()
 
      center = @adj.getCenter()
 
@@ -180,13 +185,9 @@ Polymer
 
  is: 'light9-timeline-diagram-layer'
 
  properties: {}
 
  ready: ->
 
    @elemById = {}
 
    window.setNote = @setNote.bind(this)
 
    window.setMouse = @setMouse.bind(this)
 
    @cursorPath =
 
      top: @querySelector('#cursor1')
 
      mid: @querySelector('#cursor2')
 
      bot: @querySelector('#cursor3')
 
    @elemById = {}
 

	
 
  setMouse: (pos) ->
 
    elem = @getOrCreateElem('mouse-x', 'mouse', 'path', {style: "fill:none;stroke:#333;stroke-width:0.5;"})
 
@@ -194,7 +195,6 @@ Polymer
 
    elem = @getOrCreateElem('mouse-y', 'mouse', 'path', {style: "fill:none;stroke:#333;stroke-width:0.5;"})
 
    elem.setAttribute('d', svgPathFromPoints([[pos.e(1), -999], [pos.e(1), 999]]))
 
    
 

	
 
  getOrCreateElem: (uri, groupId, tag, attrs) ->
 
    elem = @elemById[uri]
 
    if !elem
 
@@ -216,6 +216,12 @@ Polymer
 
    elem.setAttribute('d', d)
 

	
 
  setCursor: (y1, h1, y2, h2, fullZoomX, zoomInX, cursor) ->
 
    @cursorPath =
 
      top: @querySelector('#cursor1')
 
      mid: @querySelector('#cursor2')
 
      bot: @querySelector('#cursor3')
 
    return if !@cursorPath.top
 
    
 
    xZoomedOut = fullZoomX(cursor.t)
 
    xZoomedIn = zoomInX(cursor.t)
 
    @cursorPath.top.setAttribute 'd', svgPathFromPoints([
0 comments (0 inline, 0 general)