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>