Turn audio into a shareable video. forked from nypublicradio/audiogram

text-wrapper.js 2.1KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. var smartquotes = require("smartquotes").string;
  2. module.exports = function(theme) {
  3. // Do some typechecking
  4. var left = ifNumeric(theme.captionLeft, 0),
  5. right = ifNumeric(theme.captionRight, theme.width),
  6. bottom = ifNumeric(theme.captionBottom, null),
  7. top = ifNumeric(theme.captionTop, null);
  8. if (bottom === null && top === null) {
  9. top = 0;
  10. }
  11. var captionWidth = right - left;
  12. return function(context, caption) {
  13. if (!caption) {
  14. return;
  15. }
  16. var lines = [[]],
  17. maxWidth = 0,
  18. words = smartquotes(caption + "").trim().replace(/\s\s+/g, " \n").split(/ /g);
  19. context.font = theme.captionFont;
  20. context.textBaseline = "top";
  21. context.textAlign = theme.captionAlign || "center";
  22. // Check whether each word exceeds the width limit
  23. // Wrap onto next line as needed
  24. words.forEach(function(word,i){
  25. var width = context.measureText(lines[lines.length - 1].concat([word]).join(" ")).width;
  26. if (word[0] === "\n" || (lines[lines.length - 1].length && width > captionWidth)) {
  27. word = word.trim();
  28. lines.push([word]);
  29. width = context.measureText(word).width;
  30. } else {
  31. lines[lines.length - 1].push(word);
  32. }
  33. maxWidth = Math.max(maxWidth,width);
  34. });
  35. var totalHeight = lines.length * theme.captionLineHeight + (lines.length - 1) * theme.captionLineSpacing;
  36. // horizontal alignment
  37. var x = theme.captionAlign === "left" ? left : theme.captionAlign === "right" ? right : (left + right) / 2;
  38. // Vertical alignment
  39. var y;
  40. if (top !== null && bottom !== null) {
  41. // Vertical center
  42. y = (bottom + top - totalHeight) / 2;
  43. } else if (bottom !== null) {
  44. // Vertical align bottom
  45. y = bottom - totalHeight;
  46. } else {
  47. // Vertical align top
  48. y = top;
  49. }
  50. context.fillStyle = theme.captionColor;
  51. lines.forEach(function(line, i){
  52. context.fillText(line.join(" "), x, y + i * (theme.captionLineHeight + theme.captionLineSpacing));
  53. });
  54. };
  55. }
  56. function ifNumeric(val, alt) {
  57. return (typeof val === "number" && !isNaN(val)) ? val : alt;
  58. }