Changeset - 46c1ed2b0fb8
[Not reviewed]
default
0 1 0
drewp@bigasterisk.com - 7 years ago 2018-05-05 09:10:45
drewp@bigasterisk.com
update timeline code to polymer2 element api. pixi test is displaying again.
Ignore-this: 2137f5b5b5f6e1a723c99a07c9fd0d8e
1 file changed with 43 insertions and 41 deletions:
0 comments (0 inline, 0 general)
light9/web/timeline/timeline.coffee
Show inline comments
 
log = console.log
 
RDF = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#'
 
Drawing = window.Drawing
 
ROW_COUNT = 7
 

	
 

	
 
Polymer
 
  is: 'light9-timeline-editor'
 
  behaviors: [ Polymer.IronResizableBehavior ]
 
  properties:
 
class TimelineEditor extends Polymer.Element
 
  @is: 'light9-timeline-editor'
 
  @behaviors: [ Polymer.IronResizableBehavior ]
 
  @properties:
 
    viewState: { type: Object }
 
    debug: {type: String}
 
    graph: {type: Object, notify: true}
 
    setAdjuster: {type: Function, notify: true}
 
    playerSong: {type: String, notify: true}
 
    followPlayerSong: {type: Boolean, notify: true, value: true}
 
    song: {type: String, notify: true}
 
    show: {value: 'http://light9.bigasterisk.com/show/dance2017'}
 
    songTime: {type: Number, notify: true, observer: '_onSongTime'}
 
    songDuration: {type: Number, notify: true, observer: '_onSongDuration'}
 
    songPlaying: {type: Boolean, notify: true}
 
    fullZoomX: {type: Object, notify: true}
 
    zoomInX: {type: Object, notify: true}
 
    selection: {type: Object, notify: true}
 
  width: ko.observable(1)
 
  listeners:
 
  @listeners:
 
    'iron-resize': '_onIronResize'
 
  observers: [
 
  @observers: [
 
    'setSong(playerSong, followPlayerSong)'
 
    ]
 
  _onIronResize: ->
 
    @width(@offsetWidth)
 
  _onSongTime: (t) ->
 
    @viewState.cursor.t(t)
 
  _onSongDuration: (d) ->
 
    d = 700 if d < 1 # bug is that asco isn't giving duration, but 0 makes the scale corrupt
 
    @viewState.zoomSpec.duration(d)
 
  setSong: (s) ->
 
    @song = @playerSong if @followPlayerSong
 

	
 
  ready: ->
 
  connectedCallback: ->
 
    super.connectedCallback()
 
    ko.options.deferUpdates = true;
 
    @selection = {hover: ko.observable(null), selected: ko.observable([])}
 

	
 
    window.debug_zoomOrLayoutChangedCount = 0
 
    window.debug_adjUpdateDisplay = 0
 
    
 
    @viewState =
 
      zoomSpec:
 
        duration: ko.observable(100) # current song duration
 
        t1: ko.observable(0) # need validation to stay in bounds and not go too close
 
        t2: ko.observable(100)
 
      cursor:
 
        t: ko.observable(20)
 
      mouse:
 
        pos: ko.observable($V([0,0]))
 
    @fullZoomX = d3.scaleLinear()
 
    @zoomInX = d3.scaleLinear()
 
    @setAdjuster = @$.adjustersCanvas.setAdjuster.bind(@$.adjustersCanvas)
 
    #@setAdjuster = @$.adjustersCanvas.setAdjuster.bind(@$.adjustersCanvas)
 

	
 
    setInterval(@updateDebugSummary.bind(@), 100)
 

	
 
    #if anchor == loadtest
 
    #  add note and delete it repeatedly
 
    #  disconnect the graph, make many notes, drag a point over many steps, measure lag somewhere
 

	
 
  updateDebugSummary: ->
 
    elemCount = (tag) -> document.getElementsByTagName(tag).length
 
    @debug = "#{window.debug_zoomOrLayoutChangedCount} layout change,
 
     #{elemCount('light9-timeline-note')} notes,
 
     #{@selection.selected().length} selected
 
@@ -247,49 +248,51 @@ Polymer
 
      })
 

	
 
    @setAdjuster('zoom-pan', => new AdjustableFloatObservable({
 
      observable: panObs
 
      emptyBox: true
 
      # fullzoom is not right- the sides shouldn't be able to go
 
      # offscreen
 
      getTarget: () => $V([@fullZoomX(panObs()), yMid()])
 
      getSuggestedTargetOffset: () => $V([0, 0])
 
      getValueForPos: valForPos
 
      }))
 
      
 
customElements.define(TimelineEditor.is, TimelineEditor)
 

	
 
# plan: in here, turn all the notes into simple js objects with all
 
# their timing data and whatever's needed for adjusters. From that, do
 
# the brick layout. update only changing adjusters.
 
Polymer
 
  is: 'light9-timeline-time-zoomed'
 
  behaviors: [ Polymer.IronResizableBehavior ]
 
  properties:
 
class TimeZoomed extends Polymer.Element
 
  @is: 'light9-timeline-time-zoomed'
 
  @behaviors: [ Polymer.IronResizableBehavior ]
 
  @properties:
 
    graph: { type: Object, notify: true }
 
    selection: { type: Object, notify: true }
 
    dia: { type: Object, notify: true }
 
    song: { type: String, notify: true }
 
    zoomInX: { type: Object, notify: true }
 
    zoom: { type: Object, notify: true, observer: 'onZoom' } # viewState.zoomSpec
 
    zoomFlattened: { type: Object, notify: true }
 
  observers: [
 
  @observers: [
 
    'onGraph(graph, dia, setAdjuster, song, zoomInX)'
 
  ]
 
  onZoom: ->
 
    updateZoomFlattened = ->
 
      log('updateZoomFlattened')
 
      @zoomFlattened = ko.toJS(@zoom)
 
    ko.computed(updateZoomFlattened.bind(@))
 
  ready: ->
 
    
 
  connectedCallback: ->
 
     super.connectedCallback()
 
     root = @closest('light9-timeline-editor')
 
     stage = new PIXI.Container();
 
     
 
     renderer = PIXI.autoDetectRenderer(300,200, {
 
         backgroundColor: 0xff6060,
 
     });
 
     
 
     @$.rows.appendChild(renderer.view);
 
     graphics = new PIXI.Graphics();
 

	
 
     graphics.beginFill(0xFF3300);
 
     graphics.lineStyle(4, 0xffd900, 1);
 

	
 
@@ -302,28 +305,25 @@ Polymer
 
     stage.addChild(graphics);
 
     renderer.render(stage);
 

	
 
  onGraph: ->
 
    U = (x) => @graph.Uri(x)
 
    log('assign rows',@song)
 

	
 
    for uri in _.sortBy(@graph.objects(@song, U(':note')), 'uri')
 
      #should only make new ones
 
      child = new Note(@graph, @selection, @dia, uri, @setAdjuster, @song, @zoomInX)
 
      log('note ',uri)
 
    
 
    @rows = (new NoteRow(@graph, @dia, @song, @zoomInX, @noteUris, i, @selection) for i in [0...ROW_COUNT])
 

	
 
  attached: ->
 
    root = @closest('light9-timeline-editor')
 
    @rows = []#(new NoteRow(@graph, @dia, @song, @zoomInX, @noteUris, i, @selection) for i in [0...ROW_COUNT])
 

	
 
  onDrop: (effect, pos) ->
 
    U = (x) => @graph.Uri(x)
 

	
 
    return unless effect and effect.match(/^http/)
 

	
 
    # we could probably accept some initial overrides right on the
 
    # effect uri, maybe as query params
 

	
 
    if not @graph.contains(effect, RDF + 'type', U(':Effect'))
 
      if @graph.contains(effect, RDF + 'type', U(':LightSample'))
 
        effect = @makeEffect(effect)
 
@@ -390,29 +390,32 @@ Polymer
 
    for i in [0...4]
 
      pt = points[i]
 
      pointQuads.push(quad(newCurve, U(':point'), pt))
 
      pointQuads.push(quad(pt, U(':time'), @graph.LiteralRoundedFloat(i/3 * desiredWidthT)))
 
      pointQuads.push(quad(pt, U(':value'), @graph.LiteralRoundedFloat(i == 1 or i == 2)))
 

	
 
    patch = {
 
      delQuads: []
 
      addQuads: curveQuads.concat(pointQuads)
 
      }
 
    @graph.applyAndSendPatch(patch)
 

	
 
Polymer
 
  is: "light9-timeline-time-axis",
 
customElements.define(TimeZoomed.is, TimeZoomed)
 

	
 
class TimeAxis extends Polymer.Element
 
  @is: "light9-timeline-time-axis",
 
  # for now since it's just one line calling dia,
 
  # light9-timeline-editor does our drawing work.
 

	
 
customElements.define(TimeAxis.is, TimeAxis)
 

	
 
class NoteRow
 
  constructor: (@graph, @dia, @song, @zoomInX, @noteUris, @rowIndex, @selection) ->
 
    @graph.runHandler(@update.bind(@), "row notes #{@rowIndex}")
 

	
 
  observers: [
 
    'observedUpdate(graph, song, rowIndex)'
 
    'onZoom(zoomInX)'
 
    ]
 

	
 

	
 
  observedUpdate: (graph, song, rowIndex) ->
 
@@ -616,37 +619,36 @@ class Note
 

	
 
  _makeFadeAdjuster: (yForV, ctx, adjId, i0, i1, offset) ->
 
    @adjusterIds[adjId] = true
 
    @setAdjuster adjId, => new AdjustableFade(yForV, i0, i1, @, offset, ctx)
 
    
 
  _suggestedOffset: (pt) ->
 
    if pt.e(2) > .5
 
      $V([0, 30])
 
    else
 
      $V([0, -30])
 
    
 
    
 

	
 
Polymer
 
  is: "light9-timeline-note-inline-attrs"
 
  properties:
 
class InlineAttrs extends Polymer.Element
 
  @is: "light9-timeline-note-inline-attrs"
 
  @properties:
 
    graph: { type: Object, notify: true }
 
    song: { type: String, notify: true }
 
    uri: { type: String, notify: true }  # the Note
 
    rect: { type: Object, notify: true }
 
    effect: { type: String, notify: true }
 
    colorScale: { type: String, notify: true }
 
    noteLabel: { type: String, notify: true }
 
    selection: { type: Object, notify: true }
 
  observers: [
 
  @observers: [
 
    'addHandler(graph, uri)'
 
    'onColorScale(graph, uri, colorScale)'
 
    ]
 
  displayed: ->
 
    @querySelector('light9-color-picker').displayed()
 
  onColorScale: ->
 
    U = (x) => @graph.Uri(x)
 
    if @colorScale == @colorScaleFromGraph
 
      return
 
    @editAttr(@song, @uri, U(':colorScale'), @graph.Literal(@colorScale))
 

	
 
  editAttr: (song, note, attr, value) ->
 
@@ -689,44 +691,45 @@ Polymer
 
      if ea == U(':colorScale')
 
        @colorScaleFromGraph = value
 
        @colorScale = value
 
        existingColorScaleSetting = setting
 
    if existingColorScaleSetting == null
 
      @colorScaleFromGraph = '#ffffff'
 
      @colorScale = '#ffffff'
 
    #console.timeEnd('attrs update')
 

	
 

	
 
  onDel: ->
 
    deleteNote(@graph, @song, @uri, @selection)
 

	
 
customElements.define(InlineAttrs.is, InlineAttrs)
 

	
 
deleteNote = (graph, song, note, selection) ->
 
  patch = {delQuads: [{subject: song, predicate: graph.Uri(':note'), object: note, graph: song}], addQuads: []}
 
  graph.applyAndSendPatch(patch)
 
  if note in selection.selected()
 
    selection.selected(_.without(selection.selected(), note))
 
  
 

	
 
Polymer
 
  is: 'light9-adjusters-canvas'
 
  behaviors: [ Polymer.IronResizableBehavior ]
 
  properties:
 
class AdjustersCanvas extends Polymer.Element
 
  @is: 'light9-adjusters-canvas'
 
  @behaviors: [ Polymer.IronResizableBehavior ]
 
  @properties:
 
    adjs: { type: Object, notify: true }, # adjId: Adjustable
 
  observers: [
 
  @observers: [
 
    'updateAllCoords(adjs)'
 
  ]
 
  listeners:
 
  @listeners:
 
    'iron-resize': 'resizeUpdate'
 
  ready: ->
 
  connectedCallback: ->
 
    super.connectedCallback()
 
    @adjs = {}
 
    @ctx = @$.canvas.getContext('2d')
 

	
 
    @redraw()
 
   
 
  onDown: (ev) ->
 
    if ev.buttons == 1
 
      ev.stopPropagation()
 
      start = $V([ev.x, ev.y])
 
      adj = @_adjAtPoint(start)
 
      if adj
 
        @currentDrag = {start: start, adj: adj}
 
@@ -852,36 +855,34 @@ Polymer
 

	
 
    @ctx.font = "12px sans"
 
    @ctx.fillStyle = '#000'
 
    @ctx.fillText(label, x1 + 5, y2 - 5, x2 - x1 - 10)
 

	
 
    # coords from a center that's passed in
 
    # # special layout for the thaeter ones with middinh 
 
    # l/r arrows
 
    # mouse arrow cursor upon hover, and accent the hovered adjuster
 
    # connector
 

	
 
  
 
Polymer
 
class DiagramLayer extends Polymer.Element
 
  # note boxes. 
 
  is: 'light9-timeline-diagram-layer'
 
  properties: {
 
  @is: 'light9-timeline-diagram-layer'
 
  @properties: {
 
    selection: {type: Object, notify: true}
 
  }
 
  ready: ->
 
  connectedCallback: ->
 
    super.connectedCallback()
 
    @elemById = {}
 

	
 
  attached: ->
 
    
 

	
 
  setTimeAxis: (width, yTop, scale) ->
 
    pxPerTick = 50
 
    axis = d3.axisTop(scale).ticks(width / pxPerTick)
 
    d3.select(@$.timeAxis).attr('transform', 'translate(0,'+yTop+')').call(axis)
 

	
 
  getOrCreateElem: (uri, groupId, tag, attrs, moreBuild) ->
 
    elem = @elemById[uri]
 
    if !elem
 
      elem = @elemById[uri] = document.createElementNS("http://www.w3.org/2000/svg", tag)
 
      @$[groupId].appendChild(elem)
 
      elem.setAttribute('id', uri)
 
      for k,v of attrs
 
@@ -956,12 +957,13 @@ Polymer
 
    return !!@elemById[uri + '/area']
 

	
 
  _updateNotePathClasses: (uri, elem) ->
 
    ko.computed =>
 
      return if not @_noteInDiagram(uri)
 
      classes = 'light9-timeline-diagram-layer ' + (if @selection.hover() == uri then 'hover' else '') + ' '  + (if uri in @selection.selected() then 'selected' else '')
 
      elem.setAttribute('class', classes)
 
    
 
    #elem = @getOrCreateElem(uri+'/label', 'noteLabels', 'text', {style: "font-size:13px;line-height:125%;font-family:'Verana Sans';text-align:start;text-anchor:start;fill:#000000;"})
 
    #elem.setAttribute('x', curvePts[0].e(1)+20)
 
    #elem.setAttribute('y', curvePts[0].e(2)-10)
 
    #elem.innerHTML = effectLabel;
 
customElements.define(DiagramLayer.is, DiagramLayer)
 
\ No newline at end of file
0 comments (0 inline, 0 general)