Mercurial > code > home > repos > light9
changeset 1314:c91d1044fe49
start timeline elements
Ignore-this: efa190369534a08c8ad3267ca151bee5
author | Drew Perttula <drewp@bigasterisk.com> |
---|---|
date | Wed, 01 Jun 2016 10:56:39 +0000 |
parents | ed27b45526b1 |
children | b21e31c79f31 |
files | light9/web/light9-timeline-audio.html light9/web/timeline-elements.html light9/web/timeline.html |
diffstat | 3 files changed, 534 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/light9/web/light9-timeline-audio.html Wed Jun 01 10:56:39 2016 +0000 @@ -0,0 +1,53 @@ +<link rel="import" href="/lib/polymer/polymer.html"> + +<!-- (potentially-zoomed) spectrogram view --> +<dom-module id="light9-timeline-audio"> + <template> + <style> + :host { + display: block; + background: red; + } + div { + width: 100%; + height: 100%; + overflow: hidden; + } + img { + height: 100%; + position: relative; + } + </style> + <div> + <img src="show/dance2016/spectrogram/01-dream.png" + style="width: {{imgWidth}} ; left: {{imgLeft}}"> + </div> + </template> + <script> + Polymer({ + is: "light9-timeline-audio", + properties: { + uri: {type: String, notify: true}, // song + zoom: {type: Object, notify: true}, + imgWidth: { computed: '_imgWidth(zoom)' }, + imgLeft: { computed: '_imgLeft(zoom)' }, + }, + ready: function() { + this.zoom = {duration: 0}; + }, + _imgWidth: function(zoom) { + if (!zoom.duration) { + return "100%"; + } + return (100 / ((zoom.t2 - zoom.t1) / zoom.duration)) + "%"; + }, + _imgLeft: function(zoom) { + if (!zoom.duration) { + return "0"; + } + return (-100 * zoom.t1 / zoom.duration) + "%"; + }, + + }); + </script> +</dom-module>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/light9/web/timeline-elements.html Wed Jun 01 10:56:39 2016 +0000 @@ -0,0 +1,467 @@ +<link rel="import" href="/lib/polymer/polymer.html"> +<link rel="import" href="light9-timeline-audio.html"> +<link rel="import" href="/lib/iron-resizable-behavior/iron-resizable-behavior.html"> + + +<script> + var zoomSpec = { + duration: 190, + t1: 102, + t2: 161 + }; + +</script> + +<!-- Whole editor- include this on your page. + Most coordinates are relative to this element. + --> +<dom-module id="light9-timeline-editor"> + <template> + <style> + :host { + background: #444; + display: flex; + flex-direction: column; + position: relative; + border: 1px solid black; + } + light9-timeline-audio { + width: 100%; + height: 30px; + } + light9-timeline-time-zoomed { + flex-grow: 1; + } + light9-timeline-diagram-layer, light9-timeline-adjustors { + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + } + </style> + <div> + timeline editor: song [uri] <button>unlink</button> + <label><input type="checkbox"> follow player song choice</label> + </div> + + <!-- + Old zoom menu: + See current time .. esc + See from current time -> end .. shift+esc + Zoom all .. ctrl+esc + --> + <light9-timeline-audio></light9-timeline-audio> + <light9-timeline-time-zoomed></light9-timeline-time-zoomed> + <light9-timeline-diagram-layer></light9-timeline-diagram-layer> + <light9-timeline-adjustors></light9-timeline-adjustors> + </template> + <script> + Polymer({ + is: "light9-timeline-editor", + behaviors: [ + Polymer.IronResizableBehavior + ], + properties: { + } + }); + </script> +</dom-module> + + +<!-- the whole section that pans/zooms in time (most of the editor) --> +<dom-module id="light9-timeline-time-zoomed"> + <template> + <style> + :host { + display: flex; + height: 100%; + } + div { + display: flex; + flex-direction: column; + height: 100%; + + } + light9-timeline-cursor { + width: 0; + height: 100%; + z-index: 1; + } + light9-timeline-audio { + width: 100%; + height: 90px; + } + light9-timeline-graph-row { + flex-grow: 1; + } + </style> + <light9-timeline-cursor></light9-timeline-cursor> + <div> + <light9-timeline-time-axis></light9-timeline-time-axis> + <light9-timeline-audio zoom="{{zoom}}"></light9-timeline-audio> + <template is="dom-repeat" items="{{rows}}"> + <light9-timeline-graph-row></light9-timeline-graph-row> + </template> + </div> + </template> + <script> + Polymer({ + is: "light9-timeline-time-zoomed", + behaviors: [ + Polymer.IronResizableBehavior + ], + properties: { + rows: {value: [0, 1, 2, 3]}, + zoom: {value: zoomSpec} + } + }); + </script> +</dom-module> + + +<!-- + SVG or canvas that draws these: + - background grids + - zoom arcs + - notes + - annotations on notes + - connectors between adjustors and their targets + + This element is not responsible for any hit detection. Things you click (rows, + notes, adjustors, etc) are caught on their respective elements. (But is that + wrong in the case of notes?) + --> +<dom-module id="light9-timeline-diagram-layer"> + <template> +<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: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 1006 600" +> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1"> + <path + style="display:inline;fill:#758f8a;fill-opacity:0.32421055;fill-rule:evenodd;stroke:none;stroke-width:1px;" + d="m -559.27177,395.81 2.22362,-54.79762 C -204.84146,338.25666 -8.4912266,336.03416 0.40325327,297.52215 9.8280633,285.70343 40.880483,289.65152 49.016853,296.10794 c 20.15718,42.1653 270.720527,47.21149 589.526257,46.31865 l -4.2185,53.3834 z" + id="path4837" + sodipodi:nodetypes="ccccccc" /> + <path + style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.30736844" + d="M 0.75681338,294.44118 C -5.8919466,328.78953 -182.9094,341.3924 -555.73623,340.04956" + id="path4862" + sodipodi:nodetypes="cc" /> + <path + sodipodi:nodetypes="cc" + id="path4864" + d="m 48.622093,293.73407 c 6.6488,34.34835 183.666187,46.95123 556.493117,45.60839" + style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.30736844" /> + <path + style="display:inline;fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;" + d="m -570.58547,460.25772 1210.56688,0" + id="path5354"/> + <path + style="fill:#53774b;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.50000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" + d="m -393.10167,652.33195 70.00357,-68.30517 169.70563,0 161.5297134,68.30517" + id="note1" + sodipodi:nodetypes="cccc" /> + <rect + style="color:#000000;display:inline;overflow:visible;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:0.12637365;fill-rule:evenodd;stroke:none;stroke-width:1.10000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;" + id="note1Attrs" + width="108" + height="47" + x="-234.38405" + y="598.8988" + rx="0" + ry="0" /> + <path + id="path4246" + d="m -153.53195,562.60592 0,19.81802" + style="opacity:0.21600001;fill:none;fill-rule:evenodd;stroke:#d4d4d4;stroke-width:0.92825276;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.78475824, 2.78475824;stroke-dashoffset:0;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13px;line-height:125%;font-family:'Verana Sans';-inkscape-font-specification:'Verana Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;" + 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> + <rect + style="color:#000000;display:inline;overflow:visible;solid-color:#000000;solid-opacity:1;fill:#1ed8ec;fill-opacity:0.53846154;fill-rule:evenodd;stroke:#f2ff0e;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1;" + id="rect4294" + width="22.5" + height="17" + x="-224.88405" + y="603.8988" /> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13px;line-height:125%;font-family:'Verana Sans';-inkscape-font-specification:'Verana Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;" + x="-192.88405" + y="615.8988" + id="text4296" + sodipodi:linespacing="125%" ><tspan sodipodi:role="line" id="tspan4298" x="-192.88405" y="615.8988">color</tspan></text> + <rect + y="620.97205" + x="-224.98763" + height="17" + width="22.5" + id="rect4304" + style="color:#000000;display:inline;overflow:visible;solid-color:#000000;solid-opacity:1;fill:#1ed8ec;fill-opacity:0;fill-rule:evenodd;stroke:#f2ff0e;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1;" /> + <g + id="g4310" + transform="translate(-880.47502,196.64838)" > + <circle + r="6" + cy="432.78705" + cx="666.625" + id="path4306" + style="color:#000000;display:inline;overflow:visible;solid-color:#000000;solid-opacity:1;fill:#1ed8ec;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:1.10000014;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;" /> + <circle + style="color:#000000;display:inline;overflow:visible;solid-color:#000000;solid-opacity:1;fill:#1ed8ec;fill-opacity:0;fill-rule:evenodd;stroke:#000000;stroke-width:1.10000014;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;" + id="circle4308" + cx="666.625" + cy="432.78705" + r="3.6249998" /> + </g> + <path + style="opacity:0.21600001;fill:none;fill-rule:evenodd;stroke:#d4d4d4;stroke-width:0.92825276;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.78475822, 2.78475822;stroke-dashoffset:0;stroke-opacity:1" + d="m 7.2180534,637.60592 0,13.56802" + id="path4314"/> + <path + id="path4332" + d="m -393.38403,639.64882 0,12.75" + style="opacity:0.21600001;fill:none;fill-rule:evenodd;stroke:#d4d4d4;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:3.00000026, 3.00000026;stroke-dashoffset:0;stroke-opacity:1" /> + <path + style="opacity:1;fill:none;fill-rule:evenodd;stroke:#d4d4d4;stroke-width:0.9282527;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.78475821, 2.78475821;stroke-dashoffset:0;stroke-opacity:1" + d="m -22.190957,301.51493 22.56802038,0" + id="adjConnector"/> + <path + sodipodi:nodetypes="cccc" + id="path4893" + d="m -568.94472,458.6374 2.17576,-52.2338 1205.37474,0 1.5058,52.2338" + style="fill:#216ca1;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.50000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13px;line-height:125%;font-family:'Verana Sans';-inkscape-font-specification:'Verana Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;" + x="-535.36261" + y="433.71609" + id="noteLabel" + sodipodi:linespacing="125%" ><tspan sodipodi:role="line" id="tspan4902" x="-535.36261" y="433.71609">song4</tspan></text> + <g + id="noteAttrs" + transform="translate(-930.38403,193.23677)" > + <rect + style="color:#000000;display:inline;overflow:visible;solid-color:#000000;solid-opacity:1;fill:#ffffff;fill-opacity:0.12637365;fill-rule:evenodd;stroke:none;stroke-width:1.10000002;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;" + id="rect4904" + width="108" + height="33" + x="454.5" + y="223.66205" + rx="0" + ry="0" /> + <rect + style="color:#000000;display:inline;overflow:visible;solid-color:#000000;solid-opacity:1;fill:#1ed8ec;fill-opacity:0.53846154;fill-rule:evenodd;stroke:#f2ff0e;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2, 2;stroke-dashoffset:0;stroke-opacity:1;" + id="rect4906" + width="22.5" + height="17" + x="467" + y="230.66205" /> + <text + xml:space="preserve" + style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:13px;line-height:125%;font-family:'Verana Sans';-inkscape-font-specification:'Verana Sans';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;" + x="499" + y="242.66205" + id="text4908" + sodipodi:linespacing="125%"><tspan sodipodi:role="line" id="tspan4910" x="499" y="242.66205">color</tspan></text> + </g> + </g> +</svg> + + </template> + <script> + Polymer({ + is: "light9-timeline-diagram-layer", + properties: { + }, + ready: function() { +window.setNote = this.setNote.bind(this); + }, + setNote: function(uri, x1, x2, y1, y2) { + console.log('set', uri, x1, x2, y1, y2); + var s = '<path style="fill:#53774b;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.50000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m '+x1+','+y2+' 70.00357,-68.30517 169.70563,0 161.5297134,68.30517"/>'; + console.log(s); + this.$.layer1.innerHTML += s; + } + }); + </script> +</dom-module> + + +<!-- seconds labels --> +<dom-module id="light9-timeline-time-axis"> + <template> + <pre>0 sec 10 20 30 40 50</pre> + </template> + <script> + Polymer({ + is: "light9-timeline-time-axis", + properties: { + } + }); + </script> +</dom-module> + +<!-- one row of notes --> +<dom-module id="light9-timeline-graph-row"> + <template> + <style> + :host { + border-top: 1px solid black; + display: flex; + } + </style> + <template is="dom-repeat" items="[1,2,3]"> + <light9-timeline-note></light9-timeline-note> + </template> + </template> + <script> + Polymer({ + is: "light9-timeline-graph-row", + behaviors: [ + Polymer.IronResizableBehavior + ], + properties: { + + } + }); + </script> +</dom-module> + +<!-- playback cursor on top of everything. Maybe other cursors too: hover, snap, etc --> +<dom-module id="light9-timeline-cursor"> + <template> + <style> + :host { + /* parent has arranged for us to be 0 wide and the proper height */ + } + div { + background: red; + position: relative; + height: 100%; + width: 3px; + box-shadow: 3px 0 5px rgba(0, 0, 0, 0.34); + } + </style> + <div style="left: {{x}}px"></div> + </template> + <script> + Polymer({ + is: "light9-timeline-cursor", + properties: { + x: {type: Number} + }, + ready: function () { + setInterval(function() { this.x = 50 + 35 * Math.sin(Date.now()/4); }.bind(this), 50); + } + }); + </script> +</dom-module> + +<!-- One trapezoid note shape in a row. + This element has the right Y coords. + We compute X coords from the zoom setting. + diagram-layer draws the note body. --> +<dom-module id="light9-timeline-note"> + <template> + <style> + :host { + display: block; + background: green; + outline: 2px solid red; + } + </style> + <light9-timeline-note-inline-attrs></light9-timeline-note-inline-attrs> + </template> + <script> + Polymer({ + is: "light9-timeline-note", + behaviors: [ + Polymer.IronResizableBehavior + ], + listeners: { + 'iron-resize': '_onIronResize' + }, + properties: { + }, + + _onIronResize: function() { + + var r = this.getBoundingClientRect(); + setNote('myuri', 60, 180, r.top, r.bottom); + + if (this.parent) + console.log(this.parent.offsetWidth, this.parent.offsetHeight) + } + }); + </script> +</dom-module> + +<!-- All the adjustors you can edit or select. + This element manages their layout and suppresion. + Owns the selection. + Maybe includes selecting things that don't even have adjustors --> +<dom-module id="light9-timeline-adjustors"> + <template> + <style> + </style> + <div>{{greeting}}</div> + </template> + <script> + Polymer({ + is: "light9-timeline-adjustors", + properties: { + } + }); + </script> +</dom-module> + +<!-- Yellow dotted handle that you can adjust to edit something. + Knows an attribute to edit and the true screen location, even if + parent <light9-timeline-adjustors> has offset us a bit to avoid a + text overlap. + Draws affordance arrows and a connector line if we're far + away from the point that we edit. + May grow to a bigger editor when you click or drag. + --> +<dom-module id="light9-timeline-adjustor"> + <template> + <span>{{value}}</span> + </template> + <script> + Polymer({ + is: "light9-timeline-adjustor", + properties: { + } + }); + </script> +</dom-module> + +<!-- sometimes we draw attrs within the shape of a note. --> +<dom-module id="light9-timeline-note-inline-attrs"> + <template> + + </template> + <script> + Polymer({ + is: "light9-timeline-note-inline-attrs", + properties: { + } + }); + </script> +</dom-module>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/light9/web/timeline.html Wed Jun 01 10:56:39 2016 +0000 @@ -0,0 +1,14 @@ +<!doctype html> +<html> + <head> + <title>timeline</title> + <meta charset="utf-8" /> + <script src="/lib/webcomponentsjs/webcomponents-lite.min.js"></script> + + <link rel="import" href="timeline-elements.html" + </head> + <body> + <light9-timeline-editor style="width: 100%; height: 600px"> + </light9-timeline-editor> + </body> +</html>