BloggerAds廣告

相關文章

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;
 };

2017年2月3日 星期五

XAMPP Apache Custom Directory list

To modify the default ugly directory list, normaly we need to modify mod_autoindex and recompile blar blar.

For me, i have no any knowledge of C, such actions will drive me nuts.

We are going to re write the directory using PHP, CSS & HTML. no C knowledge required

Here are the summary of what we'll doing:

1. Config .htaccess file

2. Prepare html assets

3. Hide original Directory output

4. Inject our php code

For easier to explain, i will create everything in root folder (rootFolder)

the default root folder of xampp should be c:/xampp/htdocs/
create a folder (custom_dir) in rootFolder which contains your custom html code
create a .htaccess file in rootFolder and copy the following code

<!-- .htaccess -->

# DIRECTORY CUSTOMIZATION 
<IfModule mod_autoindex.c> 
 # SET INDEX OPTIONS - this enable using FancyIndexing and tell apache we will use our own html to generate the directory list
 IndexOptions IgnoreCase FancyIndexing FoldersFirst NameWidth=* DescriptionWidth=* SuppressHTMLPreamble

 # SPECIFY HEADER FILE - tell Apache where our header file stores
 HeaderName /custom_dir/header.php 

 # SPECIFY FOOTER FILE - tell Apache where our footer file stores (yes, we use ReadmeName as our footer, since ReadmeName will keep generated at the bottom)
 ReadmeName /custom_dir/footer.html 

 # IGNORE THESE FILES - hide our html asset file in directory list
 IndexIgnore /custom_dir 
</IfModule>
    

create a header.php into custom_dir, we will write our own code to generate the list
<!-- header.php -->   

<?php
$serverRoot = $_SERVER['DOCUMENT_ROOT'];
$cssPath = $serverRoot.'/custom_dir/css.php';

$currentPath = $_SERVER['DOCUMENT_ROOT'].$_SERVER['REQUEST_URI']; //always get the 'current' folder
$dirList = new DirectoryIterator(str_replace('/', '\\', $currentPath)); //just replace front-slash in case there're
?>
 
<html> 
 <head> 
  <title>Directory Title</title>
  
  <!-- make our directory responsive -->
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  
  <style>
   <?php include_once($cssPath); //hide our system path?> 
  </style>
 </head>

 <body>
  <header>
   <h1>Directory Title</h1>
  </header>

  <div>
   <table class='dirTable'> 
    <tr>
     <th>Name</th>
     <th>Last modified</th>
    </tr> 

    <?php foreach($dirList as $fileInfo): ?>
    <tr class='dirItem'>
     <td> <a href='<?=$fileInfo->getFilename() ?>'><?=$fileInfo->getFilename() ?></a> </td>
     <td> <?=date( "Y-m-d H:i", $fileInfo->getMTime()) ?> </td>
    </tr>
    <?php endforeach; ?>
   </table>
  </div>
    

then create the footer.php and do whatever you like
<!-- footer.php -->
   <footer class='yourFooterClass'>
    YOUR OWN FOOTER HTML CODE
   </footer>
 </body>
</html>
  
next, create css.php, by doing this instead of <link> is to hide the source path
/*the default list is generated by pre, we simply hide this by applying this css rule*/
pre { display:none; !important};

/*then do whatever you like*/ 
  

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;
  }

 };