Browse Source

Refactoring wave/caption

Noah 7 years ago
parent
commit
32095455d5

+ 11 - 5
audiogram/draw-frames.js View File

@@ -1,23 +1,29 @@
1 1
 var fs = require("fs"),
2 2
     path = require("path"),
3
+    Canvas = require("canvas"),
3 4
     queue = require("d3").queue;
4 5
 
5 6
 function drawFrames(renderer, options, cb) {
6 7
 
7
-  var frameQueue = queue(10);
8
+  var frameQueue = queue(10),
9
+      canvas = new Canvas(options.width, options.height),
10
+      context = canvas.getContext("2d");
8 11
 
9 12
   for (var i = 0; i < options.numFrames; i++) {
10
-
11 13
     frameQueue.defer(drawFrame, i);
12
-
13 14
   }
14 15
 
15 16
   frameQueue.awaitAll(cb);
16 17
 
17 18
   function drawFrame(frameNumber, frameCallback) {
18 19
 
19
-    renderer.drawFrame(frameNumber);
20
-    fs.writeFile(path.join(options.frameDir, zeropad(frameNumber + 1, 6) + ".png"), renderer.context.canvas.toBuffer(), function(err) {
20
+    renderer.drawFrame(context, {
21
+      caption: options.caption,
22
+      waveform: options.waveform[frameNumber],
23
+      frame: frameNumber
24
+    });
25
+
26
+    fs.writeFile(path.join(options.frameDir, zeropad(frameNumber + 1, 6) + ".png"), canvas.toBuffer(), function(err) {
21 27
       if (err) {
22 28
         return frameCallback(err);
23 29
       }

+ 4 - 0
audiogram/index.js View File

@@ -115,8 +115,12 @@ Audiogram.prototype.drawFrames = function(cb) {
115 115
     self.status("frames");
116 116
 
117 117
     drawFrames(renderer, {
118
+      width: self.settings.width,
119
+      height: self.settings.height,
118 120
       numFrames: self.numFrames,
119 121
       frameDir: self.frameDir,
122
+      caption: self.settings.caption,
123
+      waveform: self.settings.waveform,
120 124
       tick: function() {
121 125
         transports.incrementField(self.id, "framesComplete");
122 126
       }

+ 6 - 12
audiogram/initialize-canvas.js View File

@@ -1,25 +1,19 @@
1 1
 var fs = require("fs"),
2 2
     path = require("path"),
3 3
     Canvas = require("canvas"),
4
-    getRenderer = require("../renderer/"),
5
-    serverSettings = require("../settings/");
4
+    getRenderer = require("../renderer/");
6 5
 
7
-function initializeCanvas(options, cb) {
6
+function initializeCanvas(theme, cb) {
8 7
 
9 8
   // Fonts pre-registered in bin/worker
9
+  var renderer = getRenderer(theme);
10 10
 
11
-  var canvas = new Canvas(options.width, options.height),
12
-      context = canvas.getContext("2d"),
13
-      renderer = getRenderer(context).update(options);
14
-
15
-  renderer.caption = options.caption;
16
-
17
-  if (!options.backgroundImage) {
11
+  if (!theme.backgroundImage) {
18 12
     return cb(null, renderer);
19 13
   }
20 14
 
21 15
   // Load background image from file (done separately so renderer code can work in browser too)
22
-  fs.readFile(path.join(__dirname, "..", "settings", "backgrounds", options.backgroundImage), function(err, raw){
16
+  fs.readFile(path.join(__dirname, "..", "settings", "backgrounds", theme.backgroundImage), function(err, raw){
23 17
 
24 18
     if (err) {
25 19
       return cb(err);
@@ -27,7 +21,7 @@ function initializeCanvas(options, cb) {
27 21
 
28 22
     var bg = new Canvas.Image;
29 23
     bg.src = raw;
30
-    renderer.backgroundImage = bg;
24
+    renderer.backgroundImage(bg);
31 25
 
32 26
     return cb(null, renderer);
33 27
 

+ 11 - 6
client/preview.js View File

@@ -2,12 +2,12 @@ var d3 = require("d3"),
2 2
     audio = require("./audio.js"),
3 3
     video = require("./video.js"),
4 4
     minimap = require("./minimap.js"),
5
+    sampleWave = require("./sample-wave.js"),
6
+    getRenderer = require("../renderer/"),
5 7
     getWaveform = require("./waveform.js");
6 8
 
7 9
 var context = d3.select("canvas").node().getContext("2d");
8 10
 
9
-var renderer = require("../renderer/")(context);
10
-
11 11
 var theme,
12 12
     caption,
13 13
     file,
@@ -74,10 +74,15 @@ function redraw() {
74 74
 
75 75
   video.kill();
76 76
 
77
-  renderer.update(theme);
78
-  renderer.caption = caption;
79
-  renderer.backgroundImage = theme.backgroundImageFile || null;
80
-  renderer.drawFrame(0);
77
+  var renderer = getRenderer(theme);
78
+
79
+  renderer.backgroundImage(theme.backgroundImageFile || null);
80
+
81
+  renderer.drawFrame(context, {
82
+    caption: caption,
83
+    waveform: sampleWave,
84
+    frame: 0
85
+  });
81 86
 
82 87
 }
83 88
 

renderer/sample-wave.js → client/sample-wave.js View File


+ 39 - 31
renderer/index.js View File

@@ -1,63 +1,71 @@
1 1
 var d3 = require("d3"),
2 2
     patterns = require("./patterns.js"),
3
-    sample = require("./sample-wave.js"),
4 3
     textWrapper = require("./text-wrapper.js");
5 4
 
6
-module.exports = function(context) {
5
+module.exports = function(t) {
7 6
 
8
-  context.patternQuality = "best";
7
+  var renderer = {},
8
+      backgroundImage,
9
+      wrapText,
10
+      theme;
9 11
 
10
-  var renderer = {};
12
+  renderer.backgroundImage = function(_) {
13
+    if (!arguments.length) return backgroundImage;
14
+    backgroundImage = _;
15
+    return this;
16
+  };
11 17
 
12
-  renderer.context = context;
18
+  renderer.theme = function(_) {
19
+    if (!arguments.length) return theme;
13 20
 
14
-  renderer.update = function(options) {
21
+    theme = _;
15 22
 
16
-    // TODO cleaner defaults
17
-    options.backgroundColor = options.backgroundColor || "#fff";
18
-    options.waveColor = options.waveColor || options.foregroundColor || "#000";
19
-    options.captionColor = options.captionColor || options.foregroundColor || "#000";
23
+    // Default colors
24
+    theme.backgroundColor = theme.backgroundColor || "#fff";
25
+    theme.waveColor = theme.waveColor || theme.foregroundColor || "#000";
26
+    theme.captionColor = theme.captionColor || theme.foregroundColor || "#000";
20 27
 
21
-    if (typeof options.waveTop !== "number") options.waveTop = 0;
22
-    if (typeof options.waveBottom !== "number") options.waveBottom = options.height;
23
-    if (typeof options.waveLeft !== "number") options.waveLeft = 0;
24
-    if (typeof options.waveRight !== "number") options.waveRight = options.width;
28
+    // Default wave dimensions
29
+    if (typeof theme.waveTop !== "number") theme.waveTop = 0;
30
+    if (typeof theme.waveBottom !== "number") theme.waveBottom = theme.height;
31
+    if (typeof theme.waveLeft !== "number") theme.waveLeft = 0;
32
+    if (typeof theme.waveRight !== "number") theme.waveRight = theme.width;
25 33
 
26
-    this.wrapText = textWrapper(context, options);
27
-    this.options = options;
28
-    this.waveform = options.waveform || [sample.slice(0, options.samplesPerFrame)];
29
-    return this;
30
-  };
34
+    wrapText = textWrapper(theme);
31 35
 
32
-  // Get the waveform data for this frame
33
-  renderer.getWaveform = function(frameNumber) {
34
-    return this.waveform[Math.min(this.waveform.length - 1, frameNumber)];
36
+    return this;
35 37
   };
36 38
 
37 39
   // Draw the frame
38
-  renderer.drawFrame = function(frameNumber) {
40
+  renderer.drawFrame = function(context, options){
41
+
42
+    context.patternQuality = "best";
39 43
 
40 44
     // Draw the background image and/or background color
41
-    context.clearRect(0, 0, this.options.width, this.options.height);
45
+    context.clearRect(0, 0, theme.width, theme.height);
42 46
 
43
-    context.fillStyle = this.options.backgroundColor;
44
-    context.fillRect(0, 0, this.options.width, this.options.height);
47
+    context.fillStyle = theme.backgroundColor;
48
+    context.fillRect(0, 0, theme.width, theme.height);
45 49
 
46
-    if (this.backgroundImage) {
47
-      context.drawImage(this.backgroundImage, 0, 0, this.options.width, this.options.height);
50
+    if (backgroundImage) {
51
+      context.drawImage(backgroundImage, 0, 0, theme.width, theme.height);
48 52
     }
49 53
 
50
-    patterns[this.options.pattern || "wave"](context, this.getWaveform(frameNumber), this.options);
54
+    patterns[theme.pattern || "wave"](context, options.waveform, theme);
51 55
 
52 56
     // Write the caption
53
-    if (this.caption) {
54
-      this.wrapText(this.caption);
57
+    if (options.caption) {
58
+      wrapText(context, options.caption);
55 59
     }
56 60
 
57 61
     return this;
58 62
 
59 63
   };
60 64
 
65
+  if (t) {
66
+    renderer.theme(t);
67
+  }
68
+
61 69
   return renderer;
62 70
 
63 71
 }

+ 14 - 14
renderer/text-wrapper.js View File

@@ -1,16 +1,12 @@
1 1
 var smartquotes = require("smartquotes").string;
2 2
 
3
-module.exports = function(context, options) {
4
-
5
-  context.font = options.captionFont;
6
-  context.textBaseline = "top";
7
-  context.textAlign = options.captionAlign || "center";
3
+module.exports = function(theme) {
8 4
 
9 5
   // Do some typechecking
10
-  var left = ifNumeric(options.captionLeft, 0),
11
-      right = ifNumeric(options.captionRight, options.width),
12
-      bottom = ifNumeric(options.captionBottom, null),
13
-      top = ifNumeric(options.captionTop, null);
6
+  var left = ifNumeric(theme.captionLeft, 0),
7
+      right = ifNumeric(theme.captionRight, theme.width),
8
+      bottom = ifNumeric(theme.captionBottom, null),
9
+      top = ifNumeric(theme.captionTop, null);
14 10
 
15 11
   if (bottom === null && top === null) {
16 12
     top = 0;
@@ -18,7 +14,7 @@ module.exports = function(context, options) {
18 14
 
19 15
   var captionWidth = right - left;
20 16
 
21
-  return function(caption) {
17
+  return function(context, caption) {
22 18
 
23 19
     if (!caption) {
24 20
       return;
@@ -28,6 +24,10 @@ module.exports = function(context, options) {
28 24
         maxWidth = 0,
29 25
         words = smartquotes(caption + "").trim().replace(/\s\s+/g, " \n").split(/ /g);
30 26
 
27
+    context.font = theme.captionFont;
28
+    context.textBaseline = "top";
29
+    context.textAlign = theme.captionAlign || "center";
30
+
31 31
     // Check whether each word exceeds the width limit
32 32
     // Wrap onto next line as needed
33 33
     words.forEach(function(word,i){
@@ -50,10 +50,10 @@ module.exports = function(context, options) {
50 50
 
51 51
     });
52 52
 
53
-    var totalHeight = lines.length * options.captionLineHeight + (lines.length - 1) * options.captionLineSpacing;
53
+    var totalHeight = lines.length * theme.captionLineHeight + (lines.length - 1) * theme.captionLineSpacing;
54 54
 
55 55
     // horizontal alignment
56
-    var x = options.captionAlign === "left" ? left : options.captionAlign === "right" ? right : (left + right) / 2;
56
+    var x = theme.captionAlign === "left" ? left : theme.captionAlign === "right" ? right : (left + right) / 2;
57 57
 
58 58
     // Vertical alignment
59 59
     var y;
@@ -69,9 +69,9 @@ module.exports = function(context, options) {
69 69
       y = top;
70 70
     }
71 71
 
72
-    context.fillStyle = options.captionColor;
72
+    context.fillStyle = theme.captionColor;
73 73
     lines.forEach(function(line, i){
74
-      context.fillText(line.join(" "), x, y + i * (options.captionLineHeight + options.captionLineSpacing));
74
+      context.fillText(line.join(" "), x, y + i * (theme.captionLineHeight + theme.captionLineSpacing));
75 75
     });
76 76
 
77 77
  };