Mercurial > code > home > repos > light9
changeset 1325:4210bbaf528f
lots of adjuster work. zoom adjs are usable.
Ignore-this: e7d49768f0f60ec2aa89f87af93003bf
author | Drew Perttula <drewp@bigasterisk.com> |
---|---|
date | Sat, 04 Jun 2016 05:51:59 +0000 |
parents | bb4cd6d7d274 |
children | e4c65310c050 |
files | light9/web/timeline-elements.html light9/web/timeline.coffee |
diffstat | 2 files changed, 132 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/light9/web/timeline-elements.html Sat Jun 04 01:41:25 2016 +0000 +++ b/light9/web/timeline-elements.html Sat Jun 04 05:51:59 2016 +0000 @@ -45,7 +45,7 @@ <light9-timeline-audio id="audio"></light9-timeline-audio> <light9-timeline-time-zoomed id="zoomed" zoom="{{viewState.zoomSpec}}"></light9-timeline-time-zoomed> <light9-timeline-diagram-layer id="dia"></light9-timeline-diagram-layer> - <light9-timeline-adjusters id="adjusters" adjs="{{adjs}}"></light9-timeline-adjusters> + <light9-timeline-adjusters id="adjusters" dia="{{dia}}" adjs="{{adjs}}"></light9-timeline-adjusters> <div id="debug">[[debug]]</div> </template> @@ -128,21 +128,12 @@ } </style> <svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" viewBox="0 0 1021 600" > <g id="layer1"> - - <path - style="fill:none;stroke:#d4d4d4;stroke-width:0.9282527;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.78475821, 2.78475821;stroke-dashoffset:0;" - d="m 202.190957,301.51493 22.56802038,0" - id="adjConnector"/> <text 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;" @@ -150,9 +141,9 @@ 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="notes"> - </g> + <g id="mouse"></g> + <g id="notes"></g> + <g id="connectors"></g> <g id="cursor"> <path id="cursor1" style="fill:none; stroke:#ff0303; stroke-width:1.5; stroke-linecap:butt;" /> <path id="cursor2" style="fill:#9c0303;" /> @@ -257,14 +248,16 @@ </style> <template is="dom-repeat" items="{{adjs}}"> - <light9-timeline-adjuster adj="{{item}}"></light9-timeline-adjuster> + <light9-timeline-adjuster dia="{{dia}}" adj="{{item}}"></light9-timeline-adjuster> </template> </template> <script> Polymer({ is: "light9-timeline-adjusters", properties: { - adjs: { type: Array } + adjs: { type: Array }, + dia: { type: Object } + } }); </script> @@ -281,8 +274,16 @@ <dom-module id="light9-timeline-adjuster"> <template> <style> + #top { + position: absolute; + display: inline-block; + outline: 2px solid rgba(255, 0, 0, 0.25); + } table { - position: absolute; + position: relative; + left: -50%; + top: -40px; /* percent had no effect */ + outline: 2px solid rgba(0, 0, 255, 0.19); z-index: 2; border-collapse: collapse; } @@ -300,12 +301,20 @@ cursor: ew-resize; -webkit-user-select: none; } + span.empty { + width: 30px; + height: 13px; + display: inline-block; + background: rgba(0,0,0,0); + } </style> - <table id="top" style$="left: [[centerStyle.x]]px; top: [[centerStyle.y]]px"> - <tr><td></td><td>↑</td><td></td></tr> - <tr><td>←</td><td><span id="label">[[displayValue]]</span></td><td>→</td></tr> - <tr><td></td><td>↓</td><td></td></tr> - </table> + <div id="top" style$="left: [[centerStyle.x]]px; top: [[centerStyle.y]]px"> + <table> + <tr><td></td><td style="visibility: hidden">↑</td><td></td></tr> + <tr><td>←</td><td><span id="label" class$="[[spanClass]]">[[displayValue]]</span></td><td>→</td></tr> + <tr><td></td><td style="visibility: hidden">↓</td><td></td></tr> + </table> + </div> </template> </dom-module>
--- a/light9/web/timeline.coffee Sat Jun 04 01:41:25 2016 +0000 +++ b/light9/web/timeline.coffee Sat Jun 04 05:51:59 2016 +0000 @@ -9,7 +9,7 @@ @prefix dev: <http://light9.bigasterisk.com/device/> . <http://example.com/> { - :demoResource :startTime 0.5; :endTime 1.6 . + :demoResource :startTime 110; :endTime 120 . } ") @@ -19,9 +19,10 @@ # have a <light9-timeline-adjuster> associated. This object does the # layout and positioning. constructor: (@config) -> - # config has getTarget, getSuggestedTargetOffset, getValue + # config has getTarget, getSuggestedTargetOffset, getValue, emptyBox getDisplayValue: () -> + return '' if @config.emptyBox d3.format(".4g")(@_getValue()) getCenter: () -> # vec2 of pixels @@ -51,7 +52,7 @@ class AdjustableFloatObservable extends Adjustable constructor: (@config) -> - # config has observable, valueLow, targetLow, valueHigh, targetHigh, getSuggestedTargetOffset + # config has observable, getValueForPos, valueLow, targetLow, valueHigh, targetHigh, getSuggestedTargetOffset ko.computed => @_normalizedValue = d3.scaleLinear().domain([ ko.unwrap(@config.valueLow), @@ -65,13 +66,34 @@ [lo, hi] = [ko.unwrap(@config.targetLow), ko.unwrap(@config.targetHigh)] return lo.add(hi.subtract(lo).multiply(f)) + + _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 + # pos is vec2 of pixels relative to the drag start. + + epos = @_editorCoordinates() + log('offsetParentPos', epos.elements) - newValue = @dragStartValue + pos.e(1) * .2 + newValue = @config.getValueForPos(epos) @config.observable(newValue) + subscribe: (onChange) -> + ko.computed => + @config.observable() + onChange() class AdjustableFloatObject extends Adjustable constructor: (@config) -> @@ -103,6 +125,7 @@ debug: {type: String} attached: -> + @dia = @$.dia @viewState = zoomSpec: duration: ko.observable(190) @@ -142,7 +165,7 @@ pred: graph.Uri(':startTime') ctx: ctx getTarget: () => $V([200, 300]) - getSuggestedTargetOffset: () => $V([-30, 0]) + getSuggestedTargetOffset: () => $V([-30, 80]) }) new AdjustableFloatObject({ graph: graph @@ -150,31 +173,60 @@ pred: graph.Uri(':endTime') ctx: ctx getTarget: () => $V([300, 300]) - getSuggestedTargetOffset: () => $V([30, 0]) + getSuggestedTargetOffset: () => $V([30, 100]) }) ] makeZoomAdjs: -> - + dur = @viewState.zoomSpec.duration + valForPos = (pos) => + x = pos.e(1) + t = @fullZoomX.invert(x) left = new AdjustableFloatObservable({ observable: @viewState.zoomSpec.t1, valueLow: 0 - valueHigh: @viewState.zoomSpec.duration + valueHigh: dur targetLow: $V([0, 30]) # y = @$.audio.offsetTop + @$.audio.offsetHeight / 2] targetHigh: $V([@offsetWidth, 30]) getSuggestedTargetOffset: () => $V([-30, 0]) + getValueForPos: valForPos }) right = new AdjustableFloatObservable({ observable: @viewState.zoomSpec.t2, valueLow: 0 - valueHigh: @viewState.zoomSpec.duration + valueHigh: dur targetLow: $V([0, 30]) # y = @$.audio.offsetTop + @$.audio.offsetHeight / 2] targetHigh: $V([@offsetWidth, 30]) getSuggestedTargetOffset: () => $V([30, 0]) + getValueForPos: valForPos }) - return [left, right] + + panObs = ko.pureComputed({ + read: () => + (@viewState.zoomSpec.t1() + @viewState.zoomSpec.t2()) / 2 + write: (value) => + zs = @viewState.zoomSpec + span = zs.t2() - zs.t1() + zs.t1(value - span / 2) + zs.t2(value + span / 2) + }) + pan = new AdjustableFloatObservable({ + observable: panObs + emptyBox: true + valueLow: 0 + valueHigh: dur + # not right- the sides shouldn't be able to go offscreen + targetLow: $V([0, 30]) # y = @$.audio.offsetTop + @$.audio.offsetHeight / 2] + targetHigh: $V([@offsetWidth, 30]) + getSuggestedTargetOffset: () => $V([0, 0]) + getValueForPos: valForPos + }) + + return [left, right, pan] + +_adjusterSerial = 0 Polymer is: 'light9-timeline-adjuster' @@ -190,14 +242,23 @@ type: String centerStyle: type: Object - + spanClass: + type: String + value: '' + onAdj: (adj) -> @adj.subscribe () => + @spanClass = if @adj.config.emptyBox then 'empty' else '' @displayValue = @adj.getDisplayValue() center = @adj.getCenter() @centerStyle = {x: center.e(1), y: center.e(2)} + @dia?.setAdjusterConnector(@myId, @adj.getCenter(), + @adj.getTarget()) attached: -> + @myId = 'adjuster-' + _adjusterSerial + _adjusterSerial += 1 + drag = d3.drag() sel = d3.select(@$.label) sel.call(drag) @@ -212,6 +273,7 @@ svgPathFromPoints = (pts) -> out = '' pts.forEach (p) -> + p = p.elements if p.elements # for vec2 if out.length == 0 out = 'M ' else @@ -225,26 +287,40 @@ properties: {} ready: -> window.setNote = @setNote.bind(this) + window.setMouse = @setMouse.bind(this) @cursorPath = top: @querySelector('#cursor1') mid: @querySelector('#cursor2') bot: @querySelector('#cursor3') - @noteById = {} - return + @elemById = {} + + setMouse: (pos) -> + elem = @getOrCreateElem('mouse-x', 'mouse', 'path', {style: "fill:none;stroke:#333;stroke-width:0.5;"}) + elem.setAttribute('d', svgPathFromPoints([[-999, pos.e(2)], [999, pos.e(2)]])) + 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 + elem = @elemById[uri] = document.createElementNS("http://www.w3.org/2000/svg", tag) + @$[groupId].appendChild(elem) + elem.setAttribute('id', uri) + for k,v of attrs + elem.setAttribute(k, v) + return elem + setNote: (uri, x1, x2, y1, y2) -> - elem = @noteById[uri] - if !elem - s = '<path id="' + uri + '" style="fill:#53774b; stroke:#000000; stroke-width:1.5;"/>' - @$.notes.innerHTML += s - elem = @noteById[uri] = @$.notes.lastChild + elem = @getOrCreateElem(uri, 'notes', 'path', {style:"fill:#53774b; stroke:#000000; stroke-width:1.5;"}) d = svgPathFromPoints([ [x1, y2] [x1 * .75 + x2 * .25, y1] [x1 * .25 + x2 * .75, y1] [x2, y2] ]) - elem.setAttribute 'd', d - return + elem.setAttribute('d', d) + setCursor: (y1, h1, y2, h2, fullZoomX, zoomInX, cursor) -> xZoomedOut = fullZoomX(cursor.t) xZoomedIn = zoomInX(cursor.t) @@ -262,7 +338,7 @@ [xZoomedIn, y2 + h2] [xZoomedIn, @offsetParent.offsetHeight] ]) - return - setAdjusterConnector: (id, center, target) -> - console.log 'setAdjusterConnector', id, center, target - return + + setAdjusterConnector: (uri, center, target) -> + elem = @getOrCreateElem(uri, 'connectors', 'path', {style: "fill:none;stroke:#d4d4d4;stroke-width:0.9282527;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.78475821, 2.78475821;stroke-dashoffset:0;"}) + elem.setAttribute('d', svgPathFromPoints([center, target]))