Changeset - 338ea27aeb23
[Not reviewed]
default
0 2 0
Drew Perttula - 7 years ago 2018-05-12 09:22:00
drewp@bigasterisk.com
fix axis and cursor
Ignore-this: c53185c841b29ce43356c2858d275e0e
2 files changed with 60 insertions and 49 deletions:
0 comments (0 inline, 0 general)
light9/web/timeline/timeline-elements.html
Show inline comments
 
@@ -107,13 +107,13 @@
 
     }
 
     light9-timeline-graph-row {
 
         flex-grow: 1;
 
     }
 
    </style>
 
    <div id="top">
 
      <light9-timeline-time-axis id="time"></light9-timeline-time-axis>
 
      <light9-timeline-time-axis id="time" view-state="{{viewState}}"></light9-timeline-time-axis>
 
      <light9-timeline-audio id="audio"
 
                             graph="{{graph}}"
 
                             song="{{song}}"
 
                             show="{{show}}"
 
                             zoom="{{zoomFlattened}}">
 
      </light9-timeline-audio>
 
@@ -133,23 +133,22 @@
 
     notes, adjusters, etc) are caught on their respective elements. (But is that
 
     wrong in the case of notes?)
 
   -->
 
<dom-module id="light9-timeline-diagram-layer">
 
  <template>
 
    <style>
 
      :host {
 
      }
 
      svg {
 
      width: 100%;
 
      height: 100%;
 
      }
 
      #notes > path {
 
      
 
      stroke:#000000;
 
      stroke-width:1.5;
 
      }
 
     :host {
 
     }
 
     svg {
 
         width: 100%;
 
         height: 100%;
 
     }
 
     #notes > path {
 
         stroke:#000000;
 
         stroke-width:1.5;
 
     }
 
     #notes > path.hover {
 
         stroke-width: 1.5;
 
         stroke: #888;
 
     }
 
     #notes > path.selected {
 
         stroke-width: 5;
 
@@ -164,13 +163,13 @@
 
            xml:space="preserve"
 
            style="font-size:13px;line-height:125%;font-family:'Verana Sans';-inkscape-font-specification:'Verana Sans';text-align:start;text-anchor:start;fill:#000000;"
 
            x="-338.38403"
 
            y="631.3988"
 
            id="text4290"
 
            sodipodi:linespacing="125%" ><tspan sodipodi:role="line" id="tspan4292" x="-338.38403" y="631.3988">spotchase</tspan></text>
 
        <g id="timeAxis" transform="translate(0,40)"></g>
 
        <g id="zzztimeAxis" transform="translate(0,40)"></g>
 
        <g id="mouse"></g>
 
        <g id="notes"></g>
 
      </g>
 
    </svg>
 
  </template>
 
</dom-module>
 
@@ -199,18 +198,24 @@
 
      
 

	
 
<!-- seconds labels -->
 
<dom-module id="light9-timeline-time-axis">
 
  <template>
 
    <style>
 
     div {
 
         width: 100%;
 
         height: 31px;
 
     }
 
      div {
 
          width: 100%;
 
          height: 31px;
 
      }
 
      svg {
 
          width: 100%;
 
          height: 30px;
 
      }
 
    </style>
 
    <div></div>
 
    <svg id="timeAxis" xmlns="http://www.w3.org/2000/svg">
 
      <g id="axis" transform="translate(0,30)"></g>    
 
    </svg>
 
  </template>
 
</dom-module>
 

	
 
<!-- One trapezoid note shape in a row.
 
     This element has the right Y coords.
 
     We compute X coords from the zoom setting.
light9/web/timeline/timeline.coffee
Show inline comments
 
@@ -106,12 +106,16 @@ class ViewState
 
      pos: ko.observable($V([0,0]))
 
      
 
    @fullZoomX = d3.scaleLinear()
 
    @zoomInX = d3.scaleLinear()
 

	
 
    ko.computed(@zoomOrLayoutChanged.bind(@))    
 
 
 
  setWidth: (w) ->
 
    @width(w)
 
    @zoomOrLayoutChanged() # before other handleers run
 
    
 
  zoomOrLayoutChanged: () ->
 
    log('zoomOrLayoutChanged')
 
    # not for cursor updates
 

	
 
    window.debug_zoomOrLayoutChangedCount++
 
@@ -121,17 +125,15 @@ class ViewState
 
    if @zoomSpec.duration() and @zoomSpec.t2() > @zoomSpec.duration()
 
      @zoomSpec.t2(@zoomSpec.duration())
 

	
 
    @fullZoomX.domain([0, @zoomSpec.duration()])
 
    @fullZoomX.range([0, @width()])
 

	
 
    # had trouble making notes update when this changes
 
    zoomInX = d3.scaleLinear()
 
    zoomInX.domain([@zoomSpec.t1(), @zoomSpec.t2()])
 
    zoomInX.range([0, @width()])
 
    @zoomInX = zoomInX
 
    @zoomInX.domain([@zoomSpec.t1(), @zoomSpec.t2()])
 
    @zoomInX.range([0, @width()])
 
    log('update zoomInX')
 
    
 
  latestMouseTime: ->
 
    @zoomInX.invert(@mouse.pos().e(1))
 

	
 
  onMouseWheel: (deltaY) ->
 
    zs = @zoomSpec
 
@@ -162,40 +164,38 @@ class ViewState
 
        lastTime = delay
 
    setTimeout(=>
 
        @zoomSpec.t1(newT1)
 
        @zoomSpec.t2(newT2)
 
      , lastTime + 10)  
 
    
 
class TimelineEditor extends Polymer.Element
 
class TimelineEditor extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior], Polymer.Element)
 
  @is: 'light9-timeline-editor'
 
  @behaviors: [ Polymer.IronResizableBehavior ]
 
  @properties:
 
    viewState: { type: Object }
 
    debug: {type: String}
 
    graph: {type: Object, notify: true}
 
    project: {type: Object}
 
    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'}
 
    songTime: {type: Number, notify: true},#, observer: '_onSongTime'}
 
    songDuration: {type: Number, notify: true},#, observer: '_onSongDuration'}
 
    songPlaying: {type: Boolean, notify: true}
 
    selection: {type: Object, notify: true}
 
  @listeners:
 
    'iron-resize': '_onIronResize'
 
  @observers: [
 
    'setSong(playerSong, followPlayerSong)',
 
    'onGraph(graph)',
 
    ]
 
    
 
  connectedCallback: ->
 
    super.connectedCallback()
 
    
 
    ko.options.deferUpdates = true;
 

	
 
    
 
    @dia = @$.dia
 
    
 

	
 
    @selection = {hover: ko.observable(null), selected: ko.observable([])}
 

	
 
    window.debug_zoomOrLayoutChangedCount = 0
 
@@ -204,14 +204,14 @@ class TimelineEditor extends Polymer.Ele
 
    @viewState = new ViewState()
 
    window.viewState = @viewState
 
    @setAdjuster = (adjId, makeAdjustable) =>
 
      ac = @$.adjustersCanvas
 
      setTimeout((()=>ac.setAdjuster(adjId, makeAdjustable)),10)
 

	
 
    ko.computed(@zoomOrLayoutChanged.bind(@))
 
    setTimeout =>
 
      ko.computed(@zoomOrLayoutChanged.bind(@))
 
      ko.computed(@songTimeChanged.bind(@))
 

	
 
      @trackMouse()
 
      @bindKeys()
 
      @bindWheelZoom(@dia)
 
      setTimeout => # depends on child node being ready
 
@@ -224,19 +224,23 @@ class TimelineEditor extends Polymer.Ele
 
      setupDrop(@$.dia.shadowRoot.querySelector('svg'),
 
                zoomed.$.rows, @, zoomed.onDrop.bind(zoomed))
 

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

	
 
    @addEventListener('iron-resize', @_onIronResize.bind(@))
 
    @_onIronResize()
 
    
 
    #if anchor == loadtest
 
    #  add note and delete it repeatedly
 
    #  disconnect the graph, make many notes, drag a point over many steps, measure lag somewhere
 

	
 
  _onIronResize: ->
 
    log('set w to',   @offsetWidth)
 
    @viewState.width(@offsetWidth)
 
    @viewState.setWidth(@offsetWidth)
 

	
 
    log('changed width')
 
  _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)
 
    
 
@@ -259,38 +263,39 @@ class TimelineEditor extends Polymer.Ele
 
  
 
    vs = @viewState
 
    
 
  
 
    # todo: these run a lot of work purely for a time change
 
    if @$.zoomed?.$?.audio?
 
      @dia.setTimeAxis(vs.width(), @$.zoomed.$.audio.offsetTop, vs.zoomInX)
 
      vs.zoomSpec.t1()
 
      #@dia.setTimeAxis(vs.width(), @$.zoomed.$.audio.offsetTop, vs.zoomInX)
 
      @$.adjustersCanvas.updateAllCoords()
 

	
 
    # cursor needs update when layout changes, but I don't want
 
    # zoom/layout to depend on the playback time
 
    setTimeout(@songTimeChanged.bind(@), 1)
 

	
 
  songTimeChanged: ->
 
    return unless @$.zoomed?.$?.time?
 
    @$.cursorCanvas.setCursor(@$.audio.offsetTop, @$.audio.offsetHeight,
 
                              @$.zoomed.$.time.offsetTop,
 
                              @$.zoomed.$.time.offsetHeight,
 
                              30,#@$.zoomed.$.time.offsetHeight,
 
                              @viewState)
 
    
 
  trackMouse: ->
 
    # not just for show- we use the mouse pos sometimes
 
    for evName in ['mousemove', 'touchmove']
 
      @addEventListener evName, (ev) =>
 
        ev.preventDefault()
 

	
 
        # todo: consolidate with _editorCoordinates version
 
        if ev.touches?.length
 
          ev = ev.touches[0]
 

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

	
 
        @$.cursorCanvas.setMouse(@viewState.mouse.pos())
 
        # should be controlled by a checkbox next to follow-player-song-choice
 
        @sendMouseToVidref() unless window.location.hash.match(/novidref/)
 

	
 
  sendMouseToVidref: ->
 
@@ -381,13 +386,13 @@ class TimelineEditor extends Polymer.Ele
 
      
 
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.
 
class TimeZoomed extends Polymer.Element
 
class TimeZoomed extends Polymer.mixinBehaviors([Polymer.IronResizableBehavior], Polymer.Element)
 
  @is: 'light9-timeline-time-zoomed'
 
  @behaviors: [ Polymer.IronResizableBehavior ]
 
  @properties:
 
    graph: { type: Object, notify: true }
 
    project: { type: Object }
 
    selection: { type: Object, notify: true }
 
@@ -395,13 +400,12 @@ class TimeZoomed extends Polymer.Element
 
    song: { type: String, notify: true }
 
    viewState: { type: Object, notify: true }
 
  @observers: [
 
    'onGraph(graph, setAdjuster, song, viewState, project)',
 
    'onZoom(viewState)',
 
  ]
 
  @listeners: {'iron-resize': 'update'}
 
  update: ->
 
    @renderer.resize(@clientWidth, @clientHeight)
 
    @renderer.render(@stage)
 

	
 
  onZoom: ->
 
    updateZoomFlattened = ->
 
@@ -417,17 +421,17 @@ class TimeZoomed extends Polymer.Element
 
         backgroundColor: 0xff6060,
 
    })
 
     
 
  connectedCallback: ->
 
    super.connectedCallback()
 
     
 
    @addEventListener('iron-resize', @update.bind(@))
 
    @update()
 
    
 
    @$.rows.appendChild(@renderer.view);
 
  
 
    # iron-resize should be doing this but it never fires
 
    setInterval(@update.bind(@), 1000)
 
    
 
  onGraph: ->
 
    @graph.runHandler(@gatherNotes.bind(@), 'zoom notes')
 
  gatherNotes: ->
 
    U = (x) => @graph.Uri(x)
 

	
 
    log('assign rows',@song, 'graph has', @graph.quads().length)
 
@@ -484,14 +488,20 @@ class TimeZoomed extends Polymer.Element
 
    @project.makeNewNote(effect, dropTime, desiredWidthT)
 
        
 
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.
 
  @properties:
 
    viewState: { type: Object, notify: true, observer: "onViewState" }
 
  onViewState: ->
 
    ko.computed =>
 
      dependOn = [@viewState.zoomSpec.t1(), @viewState.zoomSpec.t2()]
 
      pxPerTick = 50
 
      axis = d3.axisTop(@viewState.zoomInX).ticks(@viewState.width() / pxPerTick)
 
      d3.select(@$.axis).call(axis)
 

	
 
customElements.define(TimeAxis.is, TimeAxis)
 

	
 
class NoteRow
 
  constructor: (@graph, @dia, @song, @zoomInX, @noteUris, @rowIndex, @selection) ->
 
    @graph.runHandler(@update.bind(@), "row notes #{@rowIndex}")
 
@@ -703,17 +713,13 @@ class DiagramLayer extends Polymer.Eleme
 
    selection: {type: Object, notify: true}
 
  }
 
  connectedCallback: ->
 
    super.connectedCallback()
 
    @elemById = {}
 

	
 
  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)
0 comments (0 inline, 0 general)