Browse Source

Add a citation to your clip.

parisminton 7 years ago
parent
commit
b4809f442f
8 changed files with 117 additions and 2 deletions
  1. 1 0
      audiogram/draw-frames.js
  2. 1 0
      audiogram/index.js
  3. 9 0
      client/index.js
  4. 7 0
      client/preview.js
  5. 6 0
      editor/index.html
  6. 5 0
      renderer/index.js
  7. 73 0
      renderer/text-wrapper.js
  8. 15 2
      settings/themes.json

+ 1 - 0
audiogram/draw-frames.js View File

@@ -25,6 +25,7 @@ function drawFrames(renderer, options, cb) {
25 25
 
26 26
     renderer.drawFrame(context, {
27 27
       caption: options.caption,
28
+      citation: options.citation,
28 29
       label: options.label,
29 30
       waveform: options.waveform[frameNumber],
30 31
       frame: frameNumber

+ 1 - 0
audiogram/index.js View File

@@ -115,6 +115,7 @@ Audiogram.prototype.drawFrames = function(cb) {
115 115
       numFrames: self.numFrames,
116 116
       frameDir: self.frameDir,
117 117
       caption: self.settings.caption,
118
+      citation: self.settings.citation,
118 119
       label: self.settings.label,
119 120
       waveform: self.waveform,
120 121
       tick: function() {

+ 9 - 0
client/index.js View File

@@ -58,6 +58,7 @@ function submitted() {
58 58
 
59 59
   var theme = preview.theme(),
60 60
       caption = preview.caption(),
61
+      citation = preview.citation(),
61 62
       label = preview.label(),
62 63
       selection = preview.selection(),
63 64
       file = preview.file();
@@ -91,6 +92,7 @@ function submitted() {
91 92
   }
92 93
   formData.append("theme", JSON.stringify($.extend({}, theme, { backgroundImageFile: null })));
93 94
   formData.append("caption", caption);
95
+  formData.append("citation", citation);
94 96
   formData.append("label", label);
95 97
 
96 98
   setClass("loading");
@@ -176,6 +178,9 @@ function initialize(err, themesWithImages) {
176 178
   // Get initial caption (e.g. back button)
177 179
   d3.select("#input-caption").on("change keyup", updateCaption).each(updateCaption);
178 180
 
181
+  // Get initial citation (e.g. back button)
182
+  d3.select("#input-citation").on("change keyup", updateCitation).each(updateCitation);
183
+
179 184
   // Space bar listener for audio play/pause
180 185
   d3.select(document).on("keypress", function(){
181 186
     if (!d3.select("body").classed("rendered") && d3.event.key === " " && !d3.matcher("input, textarea, button, select").call(d3.event.target)) {
@@ -245,6 +250,10 @@ function updateCaption() {
245 250
   preview.caption(this.value);
246 251
 }
247 252
 
253
+function updateCitation() {
254
+  preview.citation(this.value);
255
+}
256
+
248 257
 function updateLabel() {
249 258
   preview.label(this.value);
250 259
 }

+ 7 - 0
client/preview.js View File

@@ -10,6 +10,7 @@ var context = d3.select("canvas").node().getContext("2d");
10 10
 
11 11
 var theme,
12 12
     caption,
13
+    citation,
13 14
     label,
14 15
     file,
15 16
     selection;
@@ -26,6 +27,10 @@ function _caption(_) {
26 27
   return arguments.length ? (caption = _, redraw()) : caption;
27 28
 }
28 29
 
30
+function _citation(_) {
31
+  return arguments.length ? (citation = _, redraw()) : citation;
32
+}
33
+
29 34
 function _label(_) {
30 35
   return arguments.length ? (label = _, redraw()) : label;
31 36
 }
@@ -85,6 +90,7 @@ function redraw() {
85 90
 
86 91
   renderer.drawFrame(context, {
87 92
     caption: caption,
93
+    citation: citation,
88 94
     label: label,
89 95
     waveform: sampleWave,
90 96
     frame: 0
@@ -114,6 +120,7 @@ function loadAudio(f, cb) {
114 120
 
115 121
 module.exports = {
116 122
   caption: _caption,
123
+  citation: _citation,
117 124
   label: _label,
118 125
   theme: _theme,
119 126
   file: _file,

+ 6 - 0
editor/index.html View File

@@ -40,6 +40,12 @@
40 40
           </label>
41 41
           <input id="input-caption" name="caption" type="text" autocomplete="off" placeholder="Add a caption" />
42 42
         </div>
43
+        <div class="row form-row" id="row-citation">
44
+          <label for="input-citation">
45
+            Citation
46
+          </label>
47
+          <input id="input-citation" name="citation" type="text" autocomplete="off" placeholder="Who's being quoted? In what context?" />
48
+        </div>
43 49
         <div id="preview">
44 50
           <div style="background-color: black;">
45 51
             <div id="canvas">

+ 5 - 0
renderer/index.js View File

@@ -58,6 +58,11 @@ module.exports = function(t) {
58 58
       wrapText(context, options.caption, 'caption');
59 59
     }
60 60
 
61
+    // Write the citation
62
+    if (options.citation) {
63
+      wrapText(context, options.citation, 'citation');
64
+    }
65
+
61 66
     // Write the label
62 67
     if (options.label) {
63 68
       wrapText(context, options.label, 'label');

+ 73 - 0
renderer/text-wrapper.js View File

@@ -7,6 +7,10 @@ module.exports = function(theme) {
7 7
       right = ifNumeric(theme.captionRight, theme.width),
8 8
       bottom = ifNumeric(theme.captionBottom, null),
9 9
       top = ifNumeric(theme.captionTop, null),
10
+      citationLeft = ifNumeric(theme.citationLeft, 0),
11
+      citationRight = ifNumeric(theme.citationRight, theme.width),
12
+      citationBottom = ifNumeric(theme.citationBottom, null),
13
+      citationTop = ifNumeric(theme.citationTop, null),
10 14
       labelLeft = ifNumeric(theme.labelLeft, 0),
11 15
       labelRight = ifNumeric(theme.labelRight, theme.width),
12 16
       labelBottom = ifNumeric(theme.labelBottom, null),
@@ -23,6 +27,7 @@ module.exports = function(theme) {
23 27
   }
24 28
 
25 29
   var captionWidth = right - left,
30
+      citationWidth = citationRight - citationLeft;
26 31
       labelWidth = labelRight - labelLeft;
27 32
 
28 33
   return function(context, caption, type) {
@@ -98,6 +103,74 @@ module.exports = function(theme) {
98 103
     } // end if caption
99 104
 
100 105
 
106
+    if (type === 'citation') {
107
+      var lines = [[]],
108
+          maxWidth = 0,
109
+          words = smartquotes(caption + "").trim().replace(/\s\s+/g, " \n").split(/ /g);
110
+
111
+      context.font = theme.citationFont;
112
+      context.textBaseline = "top";
113
+      context.textAlign = theme.citationAlign || "center";
114
+
115
+      // Check whether each word exceeds the width limit
116
+      // Wrap onto next line as needed
117
+      words.forEach(function(word,i){
118
+
119
+        var width = context.measureText(lines[lines.length - 1].concat([word]).join(" ")).width;
120
+
121
+        if (word[0] === "\n" || (lines[lines.length - 1].length && width > citationWidth)) {
122
+
123
+          word = word.trim();
124
+          lines.push([word]);
125
+          width = context.measureText(word).width;
126
+
127
+        } else {
128
+
129
+          word = (i === 0) ? '— ' + word : word;
130
+          lines[lines.length - 1].push(word);
131
+
132
+        }
133
+
134
+        maxWidth = Math.max(maxWidth,width);
135
+
136
+      });
137
+
138
+      var totalHeight = lines.length * theme.citationLineHeight + (lines.length - 1) * theme.citationLineSpacing;
139
+
140
+      // horizontal alignment
141
+      var x = theme.citationAlign === "left" ? left : theme.citationAlign === "right" ? right : (left + right) / 2;
142
+
143
+      // Vertical alignment
144
+      var y;
145
+
146
+      if (citationTop !== null && citationBottom !== null) {
147
+        // Vertical center
148
+        y = (citationBottom + citationTop - totalHeight) / 2;
149
+      } else if (citationBottom !== null) {
150
+        // Vertical align bottom
151
+        y = citationBottom - totalHeight;
152
+      } else {
153
+        // Vertical align top
154
+        y = citationTop;
155
+      }
156
+
157
+      // draw citation
158
+      context.fillStyle = theme.citationColor;
159
+      lines.forEach(function(line, i){
160
+
161
+        // negative indentation for opening em dash
162
+        var indented_x = (x + 50);
163
+
164
+        if (i === 0 && /^—/.test(line[0])) {
165
+          context.fillText(line.join(" "), x, y + i * (theme.citationLineHeight + theme.citationLineSpacing));
166
+        }
167
+        else {
168
+          context.fillText(line.join(" "), indented_x, y + i * (theme.citationLineHeight + theme.citationLineSpacing));
169
+        }
170
+      });
171
+    } // end if citation
172
+
173
+
101 174
     if (type === 'label' && caption != 'None') {
102 175
       var lines = [[]],
103 176
           maxWidth = 0,

+ 15 - 2
settings/themes.json View File

@@ -12,9 +12,18 @@
12 12
     "captionTop": 70,
13 13
     "captionLeft": 50,
14 14
     "captionRight": 860,
15
-    "captionFont": "300 71px 'NYT Franklin Light'",
16
-    "captionLineHeight": 80,
15
+    "captionFont": "300 68px 'NYT Franklin Light'",
16
+    "captionLineHeight": 76,
17 17
     "captionLineSpacing": 7,
18
+    "citationAlign": "left",
19
+    "citationFont": "300 38px 'NYT Franklin Light'",
20
+    "citationTopMargin": 40,
21
+    "citationTop": 342,
22
+    "citationLeft": 50,
23
+    "citationRight": 890,
24
+    "citationMaxBottom": 390,
25
+    "citationLineHeight": 38,
26
+    "citationLineSpacing": 7,
18 27
     "labelFont": "44px 'NYT Karnak'",
19 28
     "labelAlign": "left",
20 29
     "labelTop": 470,
@@ -25,6 +34,7 @@
25 34
   "NYT Light": {
26 35
     "waveColor": "#d9d9d9",
27 36
     "foregroundColor": "#000",
37
+    "citationColor": "#000",
28 38
     "backgroundImage": "t_logo_light.png",
29 39
     "labelColor": "#000"
30 40
   },
@@ -32,12 +42,14 @@
32 42
     "backgroundColor": "#000",
33 43
     "waveColor": "#4d4d4d",
34 44
     "foregroundColor": "#fff",
45
+    "citationColor": "#fff",
35 46
     "backgroundImage": "t_logo_dark.png",
36 47
     "labelColor": "#fff"
37 48
   },
38 49
   "Still Processing": {
39 50
     "waveColor": "rgba(102, 80, 62, 0.25)",
40 51
     "foregroundColor": "#66503e",
52
+    "citationColor": "#66503e",
41 53
     "backgroundColor": "#f4d7b9",
42 54
     "backgroundImage": "t_logo_white_alpha.png",
43 55
     "labelColor": "#fff",
@@ -46,6 +58,7 @@
46 58
   "The Daily": {
47 59
     "waveColor": "rgba(102, 102, 102, 0.25)",
48 60
     "foregroundColor": "#fff",
61
+    "citationColor": "#fff",
49 62
     "backgroundColor": "#f4d7b9",
50 63
     "backgroundImage": "the_daily_audiogram_background.png",
51 64
     "labelColor": "#fff",