Kinetic Text对象可以左,右,中心(http://kineticjs.com/docs/Kinetic.Text.html)对齐。有没有办法实现合理的文本?
答案 0 :(得分:1)
KineticJS基于html canvas元素,canvas不提供文本对齐。
您可以使用画布context.measureText
构建自己的文本对齐例程,以测量每个单词的宽度,并以对齐的模式填充每行文本。
示例代码和演示: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>