BloggerAds廣告

相關文章

顯示具有 createjs 標籤的文章。 顯示所有文章
顯示具有 createjs 標籤的文章。 顯示所有文章

2017年4月13日 星期四

createjs TextField CJK text wrapping support

The TextField of official createjs supports only very basic text wrapping. It sucks when the content is CJK characters like Chinese, Korean & Japanese.

Here you are the workaround:

find the private method p._drawText in createjs (or easeljs for non combinded) and replace with the following code
this code has been well tested with one of my projects for half year

/**
  * Draws multiline text.
  * @method _drawText
  * @param {CanvasRenderingContext2D} ctx
  * @param {Object} o
  * @param {Array} lines
  * @return {Object}
  * @protected
  **/
 p._drawText = function(ctx, o, lines) {
  var paint = !!ctx;
  if (!paint) {
   ctx = Text._workingContext;
   ctx.save();
   this._prepContext(ctx);
  }
  var lineHeight = this.lineHeight || this.getMeasuredLineHeight();

  var maxW = 0,
   count = 0;
  var hardLines = String(this.text).split(/(?:\r\n|\r|\n)/);
  for (var i = 0, l = hardLines.length; i < l; i++) {
   var str = hardLines[i];
   var w = null;

   if (this.lineWidth != null && (w = ctx.measureText(str).width) > this.lineWidth) {
    // text wrapping:
    // hanyeah CJK wrapping
    var words0;
    var words;
    if ((/[\u4e00-\u9fa5]+/).test(str)) { //contains CJK characters
     words0 = str.split(/(\s)/);
     words = [];
     for (var hi = 0; hi < words0.length; hi++) {
      var hs = "";
      for (var hj = 0; hj < words0[hi].length; hj++) {
       var hjs = words0[hi][hj];
       if (hjs.charCodeAt(0) > 255) {
        if (hs != "") {
         words.push(hs);
        }
        words.push(hjs);
        hs = "";
       } else {
        hs += hjs;
       }
      }
      if (hs != "") {
       words.push(hs);
      }
     }
    } else {
     words = str.split(/(\s)/);
    }
    str = words[0];
    w = ctx.measureText(str).width;

    for (var j = 1, jl = words.length; j < jl; j += 1) {
     // Line needs to wrap:
     var wordW = ctx.measureText(words[j]).width;
     if (w + wordW > this.lineWidth) {
      if (paint) {
       this._drawTextLine(ctx, str, count * lineHeight);
      }
      if (lines) {
       lines.push(str);
      }
      if (w > maxW) {
       maxW = w;
      }
      str = words[j];
      w = ctx.measureText(str).width;
      count++;
     } else {
      str += words[j];
      w += wordW;
     }
    }
   }
   //end hanyeah CJK wrapping
   if (paint) {
    this._drawTextLine(ctx, str, count * lineHeight);
   }
   if (lines) {
    lines.push(str);
   }
   if (o && w == null) {
    w = ctx.measureText(str).width;
   }
   if (w > maxW) {
    maxW = w;
   }
   count++;
  }

  if (o) {
   o.width = maxW;
   o.height = count * lineHeight;
  }
  if (!paint) {
   ctx.restore();
  }
  return o;
 };

2016年9月1日 星期四

solve createjs DOMElement responsive

replace the function p._handleDrawEnd in Easeljs with the code below

credits to Ferry Kranenburg
http://stackoverflow.com/questions/27593088/using-domelement-input-text-and-resizing-canvas

p._handleDrawEnd = function(evt) {
  var o = this.htmlElement;
  if (!o) { return; }
  var style = o.style;

  var props = this.getConcatenatedDisplayProps(this._props), mtx = props.matrix;

  var visibility = props.visible ? "visible" : "hidden";
  if (visibility != style.visibility) { style.visibility = visibility; }
  if (!props.visible) { return; }

  // Change position of domElement
  var stage = this.getStage();        
  var ratio = $(canvas).width() / 1000; //replace the number to your canvas width
  mtx.scale(ratio,ratio);
  mtx.tx = mtx.tx*ratio;
  mtx.ty = mtx.ty*ratio;
  // End change position of domElement

  var oldProps = this._oldProps, oldMtx = oldProps&&oldProps.matrix;
  var n = 10000; // precision

  if (!oldMtx || !oldMtx.equals(mtx)) {
   var str = "matrix(" + (mtx.a*n|0)/n +","+ (mtx.b*n|0)/n +","+ (mtx.c*n|0)/n +","+ (mtx.d*n|0)/n +","+ (mtx.tx+0.5|0);
   style.transform = style.WebkitTransform = style.OTransform = style.msTransform = str +","+ (mtx.ty+0.5|0) +")";
   style.MozTransform = str +"px,"+ (mtx.ty+0.5|0) +"px)";
   if (!oldProps) { oldProps = this._oldProps = new createjs.DisplayProps(true, NaN); }
   oldProps.matrix.copy(mtx);
  }

  if (oldProps.alpha != props.alpha) {
   style.opacity = ""+(props.alpha*n|0)/n;
   oldProps.alpha = props.alpha;
  }

 };