1 2 /** 3 * @class Text类提供简单的文字显示功能。复杂的文本功能可以使用DOMElement。 4 * @augments View 5 * @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。 6 * @module hilo/view/Text 7 * @requires hilo/core/Class 8 * @requires hilo/core/Hilo 9 * @requires hilo/view/View 10 * @property {String} text 指定要显示的文本内容。 11 * @property {String} color 指定使用的字体颜色。 12 * @property {String} textAlign 指定文本的对齐方式。可以是以下任意一个值:'start', 'end', 'left', 'right', and 'center'。 13 * @property {Boolean} outline 指定文本是绘制边框还是填充。 14 * @property {Number} lineSpacing 指定文本的行距。单位为像素。默认值为0。 15 * @property {Number} textWidth 指示文本内容的宽度,只读属性。仅在canvas模式下有效。 16 * @property {Number} textHeight 指示文本内容的高度,只读属性。仅在canvas模式下有效。 17 * @property {String} font 指定使用的字体样式。 18 */ 19 var Text = Class.create(/** @lends Text.prototype */{ 20 Extends: View, 21 constructor: function Text(properties){ 22 properties = properties || {}; 23 this.id = this.id || properties.id || Hilo.getUid('Text'); 24 Text.superclass.constructor.call(this, properties); 25 26 if(!this.width) this.width = 200; //default width 27 if(!this.font) this.font = '12px arial'; //default font style 28 }, 29 30 text: null, 31 color: null, 32 textAlign: null, 33 outline: false, 34 lineSpacing: 0, 35 textWidth: 0, //read-only 36 textHeight: 0, //read-only 37 font: { 38 get: function(){ 39 return this._font || null; 40 }, 41 set: function(value){ 42 if(this._font === value) return; 43 this._font = value; 44 this._fontHeight = Text.measureFontHeight(value); 45 } 46 }, 47 48 /** 49 * 覆盖渲染方法。 50 */ 51 render: function(renderer, delta){ 52 var me = this, canvas = renderer.canvas; 53 54 if(canvas.getContext){ 55 me._draw(renderer.context); 56 }else{ 57 var drawable = me.drawable; 58 var domElement = drawable.domElement; 59 var style = domElement.style; 60 61 style.font = me.font; 62 style.textAlign = me.textAlign; 63 style.color = me.color; 64 style.width = me.width + 'px'; 65 style.height = me.height + 'px'; 66 style.lineHeight = (me._fontHeight + me.lineSpacing) + 'px'; 67 68 domElement.innerHTML = me.text; 69 renderer.draw(this); 70 } 71 }, 72 73 /** 74 * 在指定的渲染上下文上绘制文本。 75 * @private 76 */ 77 _draw: function(context){ 78 var me = this, text = me.text.toString(); 79 if(!text) return; 80 81 //set drawing style 82 context.font = me.font; 83 context.textAlign = me.textAlign; 84 context.textBaseline = 'top'; 85 if(me.outline) context.strokeStyle = me.color; 86 else context.fillStyle = me.color; 87 88 //find and draw all explicit lines 89 var lines = text.split(/\r\n|\r|\n|<br(?:[ \/])*>/); 90 var width = 0, height = 0; 91 var lineHeight = me._fontHeight + me.lineSpacing; 92 var i, line, w; 93 94 for(i = 0, len = lines.length; i < len; i++){ 95 line = lines[i]; 96 w = context.measureText(line).width; 97 98 //check if the line need to split 99 if(w <= me.width){ 100 me._drawTextLine(context, line, height); 101 if(width < w) width = w; 102 height += lineHeight; 103 continue; 104 } 105 106 var str = '', oldWidth = 0, newWidth, j, word; 107 108 for(j = 0, wlen = line.length; j < wlen; j++){ 109 word = line[j]; 110 newWidth = context.measureText(str + word).width; 111 112 if(newWidth > me.width){ 113 me._drawTextLine(context, str, height); 114 if(width < oldWidth) width = oldWidth; 115 height += lineHeight; 116 str = word; 117 }else{ 118 oldWidth = newWidth; 119 str += word; 120 } 121 122 if(j == wlen - 1){ 123 me._drawTextLine(context, str, height); 124 if(str !== word && width < newWidth) width = newWidth; 125 height += lineHeight; 126 } 127 } 128 } 129 130 me.textWidth = width; 131 me.textHeight = height; 132 if(!me.height) me.height = height; 133 }, 134 135 /** 136 * 在指定的渲染上下文上绘制一行文本。 137 * @private 138 */ 139 _drawTextLine: function(context, text, y){ 140 var me = this, x = 0, width = me.width; 141 142 switch(me.textAlign){ 143 case 'center': 144 x = width * 0.5 >> 0; 145 break; 146 case 'right': 147 case 'end': 148 x = width; 149 break; 150 }; 151 152 if(me.outline) context.strokeText(text, x, y); 153 else context.fillText(text, x, y); 154 }, 155 156 Statics: /** @lends Text */{ 157 /** 158 * 测算指定字体样式的行高。 159 * @param {String} font 指定要测算的字体样式。 160 * @return {Number} 返回指定字体的行高。 161 */ 162 measureFontHeight: function(font){ 163 var docElement = document.documentElement, fontHeight; 164 var elem = Hilo.createElement('div', {style:{font:font, position:'absolute'}, innerHTML:'M'}); 165 166 docElement.appendChild(elem); 167 fontHeight = elem.offsetHeight; 168 docElement.removeChild(elem); 169 return fontHeight; 170 } 171 } 172 173 });