如何证明kinetic.js文本对象中的文本?

时间:2014-07-11 08:52:56

标签: text kineticjs justify

Kinetic Text对象可以左,右,中心(http://kineticjs.com/docs/Kinetic.Text.html)对齐。有没有办法实现合理的文本?

1 个答案:

答案 0 :(得分:1)

KineticJS基于html canvas元素,canvas不提供文本对齐。

您可以使用画布context.measureText构建自己的文本对齐例程,以测量每个单词的宽度,并以对齐的模式填充每行文本。

enter image description here

示例代码和演示: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>