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(context, options) {
  3. context.font = options.captionFont;
  4. context.textBaseline = "top";
  5. context.textAlign = options.captionAlign || "center";
  6. // Do some typechecking
  7. var left = ifNumeric(options.captionLeft, 0),
  8. right = ifNumeric(options.captionRight, options.width),
  9. bottom = ifNumeric(options.captionBottom, null),
  10. top = ifNumeric(options.captionTop, null);
  11. if (bottom === null && top === null) {
  12. top = 0;
  13. }
  14. var captionWidth = right - left;
  15. return function(caption) {
  16. if (!caption) {
  17. return;
  18. }
  19. var lines = [[]],
  20. maxWidth = 0,
  21. words = smartquotes(caption + "").trim().replace(/\s\s+/g, " \n").split(/ /g);
  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 * options.captionLineHeight + (lines.length - 1) * options.captionLineSpacing;
  36. // horizontal alignment
  37. var x = options.captionAlign === "left" ? left : options.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 = options.captionColor;
  51. lines.forEach(function(line, i){
  52. context.fillText(line.join(" "), x, y + i * (options.captionLineHeight + options.captionLineSpacing));
  53. });
  54. };
  55. }
  56. function ifNumeric(val, alt) {
  57. return (typeof val === "number" && !isNaN(val)) ? val : alt;
  58. }