text.js 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
  2. var Util = require('../../util/common');
  3. var Shape = require('../shape');
  4. var textWidthCacheCounter = 0;
  5. var textWidthCache = {};
  6. var TEXT_CACHE_MAX = 5000;
  7. var Text =
  8. /*#__PURE__*/
  9. function (_Shape) {
  10. _inheritsLoose(Text, _Shape);
  11. function Text() {
  12. return _Shape.apply(this, arguments) || this;
  13. }
  14. var _proto = Text.prototype;
  15. _proto._initProperties = function _initProperties() {
  16. _Shape.prototype._initProperties.call(this);
  17. this._attrs.canFill = true;
  18. this._attrs.canStroke = true;
  19. this._attrs.type = 'text';
  20. };
  21. _proto.getDefaultAttrs = function getDefaultAttrs() {
  22. return {
  23. lineWidth: 0,
  24. lineCount: 1,
  25. fontSize: 12,
  26. fontFamily: 'sans-serif',
  27. fontStyle: 'normal',
  28. fontWeight: 'normal',
  29. fontVariant: 'normal',
  30. textAlign: 'start',
  31. textBaseline: 'bottom',
  32. lineHeight: null,
  33. textArr: null
  34. };
  35. };
  36. _proto._getFontStyle = function _getFontStyle() {
  37. var attrs = this._attrs.attrs;
  38. var fontSize = attrs.fontSize,
  39. fontFamily = attrs.fontFamily,
  40. fontWeight = attrs.fontWeight,
  41. fontStyle = attrs.fontStyle,
  42. fontVariant = attrs.fontVariant;
  43. return fontStyle + " " + fontVariant + " " + fontWeight + " " + fontSize + "px " + fontFamily;
  44. };
  45. _proto._afterAttrsSet = function _afterAttrsSet() {
  46. var attrs = this._attrs.attrs;
  47. attrs.font = this._getFontStyle();
  48. if (attrs.text) {
  49. var text = attrs.text;
  50. var textArr = null;
  51. var lineCount = 1;
  52. if (Util.isString(text) && text.indexOf('\n') !== -1) {
  53. textArr = text.split('\n');
  54. lineCount = textArr.length;
  55. }
  56. attrs.lineCount = lineCount;
  57. attrs.textArr = textArr;
  58. }
  59. this.set('attrs', attrs);
  60. };
  61. _proto._getTextHeight = function _getTextHeight() {
  62. var attrs = this._attrs.attrs;
  63. if (attrs.height) {
  64. return attrs.height;
  65. }
  66. var lineCount = attrs.lineCount;
  67. var fontSize = attrs.fontSize * 1;
  68. if (lineCount > 1) {
  69. var spaceingY = this._getSpaceingY();
  70. return fontSize * lineCount + spaceingY * (lineCount - 1);
  71. }
  72. return fontSize;
  73. };
  74. _proto._getSpaceingY = function _getSpaceingY() {
  75. var attrs = this._attrs.attrs;
  76. var lineHeight = attrs.lineHeight;
  77. var fontSize = attrs.fontSize * 1;
  78. return lineHeight ? lineHeight - fontSize : fontSize * 0.14;
  79. };
  80. _proto.drawInner = function drawInner(context) {
  81. var self = this;
  82. var attrs = self._attrs.attrs;
  83. var text = attrs.text;
  84. var x = attrs.x;
  85. var y = attrs.y;
  86. if (Util.isNil(text) || isNaN(x) || isNaN(y)) {
  87. // text will be 0
  88. return;
  89. }
  90. var textArr = attrs.textArr;
  91. var fontSize = attrs.fontSize * 1;
  92. var spaceingY = self._getSpaceingY();
  93. if (attrs.rotate) {
  94. // do rotation
  95. context.translate(x, y);
  96. context.rotate(attrs.rotate);
  97. x = 0;
  98. y = 0;
  99. }
  100. var textBaseline = attrs.textBaseline;
  101. var height;
  102. if (textArr) {
  103. height = self._getTextHeight();
  104. }
  105. var subY; // context.beginPath();
  106. if (self.hasFill()) {
  107. var fillOpacity = attrs.fillOpacity;
  108. if (!Util.isNil(fillOpacity) && fillOpacity !== 1) {
  109. context.globalAlpha = fillOpacity;
  110. }
  111. if (textArr) {
  112. for (var i = 0, len = textArr.length; i < len; i++) {
  113. var subText = textArr[i];
  114. subY = y + i * (spaceingY + fontSize) - height + fontSize; // bottom;
  115. if (textBaseline === 'middle') {
  116. subY += height - fontSize - (height - fontSize) / 2;
  117. }
  118. if (textBaseline === 'top') {
  119. subY += height - fontSize;
  120. }
  121. context.fillText(subText, x, subY);
  122. }
  123. } else {
  124. context.fillText(text, x, y);
  125. }
  126. }
  127. if (self.hasStroke()) {
  128. if (textArr) {
  129. for (var _i = 0, _len = textArr.length; _i < _len; _i++) {
  130. var _subText = textArr[_i];
  131. subY = y + _i * (spaceingY + fontSize) - height + fontSize; // bottom;
  132. if (textBaseline === 'middle') {
  133. subY += height - fontSize - (height - fontSize) / 2;
  134. }
  135. if (textBaseline === 'top') {
  136. subY += height - fontSize;
  137. }
  138. context.strokeText(_subText, x, subY);
  139. }
  140. } else {
  141. context.strokeText(text, x, y);
  142. }
  143. }
  144. };
  145. _proto.calculateBox = function calculateBox() {
  146. var self = this;
  147. var attrs = self._attrs.attrs;
  148. var x = attrs.x,
  149. y = attrs.y,
  150. textAlign = attrs.textAlign,
  151. textBaseline = attrs.textBaseline;
  152. var width = self._getTextWidth(); // attrs.width
  153. if (!width) {
  154. return {
  155. minX: x,
  156. minY: y,
  157. maxX: x,
  158. maxY: y
  159. };
  160. }
  161. var height = self._getTextHeight(); // attrs.height
  162. var point = {
  163. x: x,
  164. y: y - height
  165. }; // default textAlign: start, textBaseline: bottom
  166. if (textAlign) {
  167. if (textAlign === 'end' || textAlign === 'right') {
  168. point.x -= width;
  169. } else if (textAlign === 'center') {
  170. point.x -= width / 2;
  171. }
  172. }
  173. if (textBaseline) {
  174. if (textBaseline === 'top') {
  175. point.y += height;
  176. } else if (textBaseline === 'middle') {
  177. point.y += height / 2;
  178. }
  179. }
  180. return {
  181. minX: point.x,
  182. minY: point.y,
  183. maxX: point.x + width,
  184. maxY: point.y + height
  185. };
  186. };
  187. _proto._getTextWidth = function _getTextWidth() {
  188. var attrs = this._attrs.attrs;
  189. if (attrs.width) {
  190. return attrs.width;
  191. }
  192. var text = attrs.text;
  193. var context = this.get('context');
  194. if (Util.isNil(text)) return undefined;
  195. var font = attrs.font;
  196. var textArr = attrs.textArr;
  197. var key = text + '' + font;
  198. if (textWidthCache[key]) {
  199. return textWidthCache[key];
  200. }
  201. var width = 0;
  202. if (textArr) {
  203. for (var i = 0, length = textArr.length; i < length; i++) {
  204. var subText = textArr[i];
  205. width = Math.max(width, Util.measureText(subText, font, context).width);
  206. }
  207. } else {
  208. width = Util.measureText(text, font, context).width;
  209. }
  210. if (textWidthCacheCounter > TEXT_CACHE_MAX) {
  211. textWidthCacheCounter = 0;
  212. textWidthCache = {};
  213. }
  214. textWidthCacheCounter++;
  215. textWidthCache[key] = width;
  216. return width;
  217. };
  218. return Text;
  219. }(Shape);
  220. Shape.Text = Text;
  221. module.exports = Text;