Kinetic Text object have left,right,center (http://kineticjs.com/docs/Kinetic.Text.html) align possible. Is there some way to achieve justified text ?
KineticJS is based on the html canvas element and canvas does not offer text justification.
You could construct your own text justification routine using canvas's context.measureText
to measure the width of each word and fill each line of text in a justified pattern.
Example code and a Demo: http://jsfiddle.net/m1erickson/c7dwC/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.1.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
function Justifier(text,font,linewidth,lineheight){
//
this.font=font;
this.lorem=text;
this.maxLineWidth=linewidth;
this.lineHeight=lineheight;
//
this.canvas=document.createElement("canvas");
this.ctx=this.canvas.getContext("2d");
this.aLorem=this.lorem.split(" ");
this.aWidths=[];
this.spaceWidth;
//this.run();
}
Justifier.prototype.run=function(){
this.ctx.save();
this.ctx.font=this.font;
spaceWidth=this.ctx.measureText(" ").width;
for(var i=0;i<this.aLorem.length;i++){
this.aWidths.push(this.ctx.measureText(this.aLorem[i]).width);
}
this.ctx.restore();
//
var justifiedLines=[];
var startingIndex=0;
do{
var line=this.justifyLine(startingIndex);
justifiedLines.push(line);
startingIndex=line.endingIndex+1;
}while(startingIndex<this.aLorem.length-1);
//
this.canvas.width=this.maxLineWidth;
this.canvas.height=justifiedLines.length*this.lineHeight+5;
this.ctx.font=this.font;
for(var i=0;i<justifiedLines.length;i++){
this.drawJustifiedLine(justifiedLines[i],i*this.lineHeight+this.lineHeight);
}
}
Justifier.prototype.justifyLine=function(startingIndex){
var accumWidth=0;
var accumWordWidth=0;
var padding=0;
var justifiedPadding;
var index=startingIndex;
while(index<this.aLorem.length && accumWidth+padding+this.aWidths[index]<=this.maxLineWidth){
accumWidth+=padding+this.aWidths[index];
accumWordWidth+=this.aWidths[index];
padding=spaceWidth;
index++;
};
if(index<this.aWidths.length-1){
index--;
justifiedPadding=(this.maxLineWidth-accumWordWidth)/(index-startingIndex);
}else{
justifiedPadding=(this.maxLineWidth-accumWordWidth)/(index-startingIndex-1);
}
return({
startingIndex:startingIndex,
endingIndex:index,
justifiedPadding:justifiedPadding}
);
}
Justifier.prototype.drawJustifiedLine=function(jLine,y){
var sp=jLine.justifiedPadding;
var accumLeft=0;
for(var i=jLine.startingIndex;i<=jLine.endingIndex;i++){
this.ctx.fillText(this.aLorem[i],accumLeft,y);
accumLeft+=this.aWidths[i]+sp;
}
}
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
var font="14px verdana";
var text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s.";
var J=new Justifier(text,font,250,18);
J.run();
var textImage=new Kinetic.Image({
x:20,
y:20,
image:J.canvas,
draggable:true,
});
layer.add(textImage);
layer.draw();
}); // end $(function(){});
</script>
</head>
<body>
<h4>KineticJS Justified Text</h4>
<div id="container"></div>
</body>
</html>