writeTextToCanvas.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. import measureText from '../ThirdParty/measureText.js';
  2. import Color from './Color.js';
  3. import defaultValue from './defaultValue.js';
  4. import defined from './defined.js';
  5. import DeveloperError from './DeveloperError.js';
  6. var imageSmoothingEnabledName;
  7. /**
  8. * Writes the given text into a new canvas. The canvas will be sized to fit the text.
  9. * If text is blank, returns undefined.
  10. *
  11. * @param {String} text The text to write.
  12. * @param {Object} [options] Object with the following properties:
  13. * @param {String} [options.font='10px sans-serif'] The CSS font to use.
  14. * @param {String} [options.textBaseline='bottom'] The baseline of the text.
  15. * @param {Boolean} [options.fill=true] Whether to fill the text.
  16. * @param {Boolean} [options.stroke=false] Whether to stroke the text.
  17. * @param {Color} [options.fillColor=Color.WHITE] The fill color.
  18. * @param {Color} [options.strokeColor=Color.BLACK] The stroke color.
  19. * @param {Number} [options.strokeWidth=1] The stroke width.
  20. * @param {Color} [options.backgroundColor=Color.TRANSPARENT] The background color of the canvas.
  21. * @param {Number} [options.padding=0] The pixel size of the padding to add around the text.
  22. * @returns {Canvas} A new canvas with the given text drawn into it. The dimensions object
  23. * from measureText will also be added to the returned canvas. If text is
  24. * blank, returns undefined.
  25. * @exports writeTextToCanvas
  26. */
  27. function writeTextToCanvas(text, options) {
  28. //>>includeStart('debug', pragmas.debug);
  29. if (!defined(text)) {
  30. throw new DeveloperError('text is required.');
  31. }
  32. //>>includeEnd('debug');
  33. if (text === '') {
  34. return undefined;
  35. }
  36. options = defaultValue(options, defaultValue.EMPTY_OBJECT);
  37. var font = defaultValue(options.font, '10px sans-serif');
  38. var stroke = defaultValue(options.stroke, false);
  39. var fill = defaultValue(options.fill, true);
  40. var strokeWidth = defaultValue(options.strokeWidth, 1);
  41. var backgroundColor = defaultValue(options.backgroundColor, Color.TRANSPARENT);
  42. var padding = defaultValue(options.padding, 0);
  43. var doublePadding = padding * 2.0;
  44. var canvas = document.createElement('canvas');
  45. canvas.width = 1;
  46. canvas.height = 1;
  47. canvas.style.font = font;
  48. var context2D = canvas.getContext('2d');
  49. if (!defined(imageSmoothingEnabledName)) {
  50. if (defined(context2D.imageSmoothingEnabled)) {
  51. imageSmoothingEnabledName = 'imageSmoothingEnabled';
  52. } else if (defined(context2D.mozImageSmoothingEnabled)) {
  53. imageSmoothingEnabledName = 'mozImageSmoothingEnabled';
  54. } else if (defined(context2D.webkitImageSmoothingEnabled)) {
  55. imageSmoothingEnabledName = 'webkitImageSmoothingEnabled';
  56. } else if (defined(context2D.msImageSmoothingEnabled)) {
  57. imageSmoothingEnabledName = 'msImageSmoothingEnabled';
  58. }
  59. }
  60. context2D.font = font;
  61. context2D.lineJoin = 'round';
  62. context2D.lineWidth = strokeWidth;
  63. context2D[imageSmoothingEnabledName] = false;
  64. // textBaseline needs to be set before the measureText call. It won't work otherwise.
  65. // It's magic.
  66. context2D.textBaseline = defaultValue(options.textBaseline, 'bottom');
  67. // in order for measureText to calculate style, the canvas has to be
  68. // (temporarily) added to the DOM.
  69. canvas.style.visibility = 'hidden';
  70. document.body.appendChild(canvas);
  71. var dimensions = measureText(context2D, text, stroke, fill);
  72. canvas.dimensions = dimensions;
  73. document.body.removeChild(canvas);
  74. canvas.style.visibility = '';
  75. //Some characters, such as the letter j, have a non-zero starting position.
  76. //This value is used for kerning later, but we need to take it into account
  77. //now in order to draw the text completely on the canvas
  78. var x = -dimensions.bounds.minx;
  79. //Expand the width to include the starting position.
  80. var width = Math.ceil(dimensions.width) + x + doublePadding;
  81. //While the height of the letter is correct, we need to adjust
  82. //where we start drawing it so that letters like j and y properly dip
  83. //below the line.
  84. var height = dimensions.height + doublePadding;
  85. var baseline = height - dimensions.ascent + padding;
  86. var y = height - baseline + doublePadding;
  87. canvas.width = width;
  88. canvas.height = height;
  89. // Properties must be explicitly set again after changing width and height
  90. context2D.font = font;
  91. context2D.lineJoin = 'round';
  92. context2D.lineWidth = strokeWidth;
  93. context2D[imageSmoothingEnabledName] = false;
  94. // Draw background
  95. if (backgroundColor !== Color.TRANSPARENT) {
  96. context2D.fillStyle = backgroundColor.toCssColorString();
  97. context2D.fillRect(0, 0, canvas.width, canvas.height);
  98. }
  99. if (stroke) {
  100. var strokeColor = defaultValue(options.strokeColor, Color.BLACK);
  101. context2D.strokeStyle = strokeColor.toCssColorString();
  102. context2D.strokeText(text, x + padding, y);
  103. }
  104. if (fill) {
  105. var fillColor = defaultValue(options.fillColor, Color.WHITE);
  106. context2D.fillStyle = fillColor.toCssColorString();
  107. context2D.fillText(text, x + padding, y);
  108. }
  109. return canvas;
  110. }
  111. export default writeTextToCanvas;