How can I get textBaseline="alphabetic" behavior in Kineticjs? -


i'm trying align text in way canvas context textbaseline property set "alphabetic" does. can't same effect kineticjs.

var letters = [      { symbol: "a", x: 3.0, size: 20 },      { symbol: "b", x: 36.3, size: 30 },      { symbol: "c", x: 86.3, size: 40 },      { symbol: "d", x: 158.6, size: 50 },      { symbol: "e", x: 248.9, size: 40 },      { symbol: "f", x: 315.5, size: 30 },      { symbol: "g", x: 361.3, size: 20 } ];  // how kineticjs renders text  (function actual() {      var stage = new kinetic.stage({ container: "mycontainer",  width: 400,  height: 100 }),  		layer = new kinetic.layer(),          baseline = 60;  	letters.foreach(function(letter) {       	layer.add(new kinetic.text({          	x: letter.x,          	y: baseline - letter.size,          	text: letter.symbol,          	fontsize: letter.size,                    	fill: 'black',       	}));        	});      // baseline visualization   	layer.add(new kinetic.line({      	points: [0, baseline, 400, baseline ],      	stroke: "red"   	}));   	stage.add(layer);  })();  // how render text  (function expected() {      var c = document.getelementbyid("mycanvas"),      	ctx = c.getcontext("2d"),          baseline = 60;    	ctx.textbaseline = "alphabetic"; // redundant it's default behaviour 	   	letters.foreach(function(letter) {          ctx.font = letter.size + "px arial";          ctx.filltext(letter.symbol, letter.x, baseline);       });          // baseline visualization      ctx.strokestyle = "red";   	ctx.moveto(0, baseline);   	ctx.lineto(400, baseline);   	ctx.stroke();  })();
<script src="https://cdn.lukej.me/kineticjs/5.1.0/kinetic.min.js"></script>    <div id="mycontainer"></div>    <canvas id="mycanvas" width="400" height="150" style="position: absolute; left: 10px; top: 100px">

same code on jsfiddle.

i'm aware of this question haven't found right way of calculating offset alphabetic baseline.

the proper "y" position can calculated follows:

y = baseline - fontsize + descent;

where "descent" can obtained using "gettextheight" function this answer

the code below gives pixel perfect results in firefox , decent ones in chrome.

var letters = [      { symbol: "a", x: 3.0, size: 20 },      { symbol: "b", x: 36.3, size: 30 },      { symbol: "c", x: 86.3, size: 40 },      { symbol: "d", x: 158.6, size: 50 },      { symbol: "e", x: 248.9, size: 40 },      { symbol: "f", x: 315.5, size: 30 },      { symbol: "g", x: 361.3, size: 20 } ];  // how kineticjs renders text  (function actual() {      var stage = new kinetic.stage({ container: "mycontainer",  width: 400,  height: 100 }),  		layer = new kinetic.layer(),          baseline = 60;  	letters.foreach(function(letter) {       	layer.add(new kinetic.text({          	x: letter.x,          	y: baseline - letter.size + getmetrics("arial", letter.size).descent,          	text: letter.symbol,          	fontsize: letter.size,                    	fill: 'black',       	}));        	});      // baseline visualization   	layer.add(new kinetic.line({      	points: [0, baseline, 400, baseline ],      	stroke: "red"   	}));   	stage.add(layer);      function getmetrics(fontfamily, fontsize) {           var $text = $("<span>hg</span>").css({                "fontfamily": fontfamily,                "font-size": fontsize + "px",               "line-height": "normal"           });           var $block = $("<div></div>").css({               "display": "inline-block",               "width": "1px",               "height": "0px"           });           var $div = $("<div></div>");           $div.append($text, $block);           $("body").append($div);           try {               var result = {};               $block.css({ verticalalign: "baseline" });               result.ascent = $block.offset().top - $text.offset().top;               $block.css({ verticalalign: "bottom" });               result.height = $block.offset().top - $text.offset().top;               result.descent = result.height - result.ascent;           } {               $div.remove();           }           return result;    };   })();  // how render text  (function expected() {      var c = document.getelementbyid("mycanvas"),      	ctx = c.getcontext("2d"),          baseline = 60;    	ctx.textbaseline = "alphabetic"; // redundant it's default behaviour 	   	letters.foreach(function(letter) {          ctx.font = letter.size + "px arial";          ctx.filltext(letter.symbol, letter.x, baseline);       });          // baseline visualization      ctx.strokestyle = "red";   	ctx.moveto(0, baseline);   	ctx.lineto(400, baseline);   	ctx.stroke();  })();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>  <script src="https://cdn.lukej.me/kineticjs/5.1.0/kinetic.min.js"></script>    <div id="mycontainer"></div>    <canvas id="mycanvas" width="400" height="150" style="position: absolute; left: 10px; top: 100px">


Comments

Popular posts from this blog

java - UnknownEntityTypeException: Unable to locate persister (Hibernate 5.0) -

python - ValueError: empty vocabulary; perhaps the documents only contain stop words -

ubuntu - collect2: fatal error: ld terminated with signal 9 [Killed] -