在Canvas中围绕图像环绕文本

时间:2013-07-04 10:17:33

标签: html5 image text canvas javascript-framework

是否可以在HTML 5 Canvas中的图像周围包装文本?例如使用一些Javascript框架?我查看了KineticJS,但找不到有用的东西。

编辑:

我的问题似乎不清楚。我正在找点事情:

http://www.monkeydoit.com/images/panda2.gif

1 个答案:

答案 0 :(得分:3)

您可以使用画布变换(翻译+旋转)

围绕图像(矩形)包装文本

enter image description here

例如,这是旋转画布并在图像右侧绘制文本的方法:

// save the untransformed state of the context
ctx.save();

// translate to the top-right corner of the image
// ( x/y properties have been added to the standard img element )
ctx.translate(image.x+image.width,image.y);

// rotate the canvas 90 degrees (PI/2 radians)
ctx.rotate(Math.PI/2);

// the canvas is now properly moved and rotated
// so we can just draw the text at [0,0]
ctx.fillText(subtext,0,0);

// restore the context to its untransformed state
ctx.restore();

使用context.measureText:

计算一侧有多少单词
var end=0;

var subtext="";

while(ctx.measureText(text.split(" ",end+1).join(" ")).width<=length)
{
    subtext=text.split(" ",end+1).join(" ");
    end++;
}

一个有趣的增强功能是在带圆角的矩形周围绘制文字。

这是代码和小提琴:http://jsfiddle.net/m1erickson/U2hE3/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; padding:10px; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var rect={x:40,y:40,width:150,height:120};

    var text="This is some text that wraps on the outside of a rectangle.";

    var font="14px Verdana";

    drawTextAroundRect(rect,text,7,font);


    function drawTextAtAngle(text,length,x,y,radians){

        // if text is empty then return
        if(text.length==0){return;}

        var end=0;
        var subtext="";

        if(ctx.measureText(text).width<=length){

            // all the text fits
            subtext=text; 

        }else{

            // calc how many words will fit on this length
            while(ctx.measureText(text.split(" ",end+1).join(" ")).width<=length)
            {
                subtext=text.split(" ",end+1).join(" ");
                end++;
            }

        }

        // draw the text at the appropriate angle
        ctx.save();
        ctx.translate(x,y);
        ctx.rotate(radians);
        ctx.fillText(subtext,0,0);
        ctx.restore();

        // return any text that didn't fit for further processing
        if(end==text.length){
            return("");
        }else{
            return(text.substr(subtext.length));
        }

    }


    function drawTextAroundRect(rect,text,textPadding,font){

        // set the font
        ctx.font=font;

        // top
        text=drawTextAtAngle(text,rect.width,rect.x,rect.y-textPadding,0);

        // right
        text=drawTextAtAngle(text,rect.height,rect.x+rect.width+textPadding,rect.y,Math.PI/2);

        // bottom
        text=drawTextAtAngle(text,rect.width,rect.x+rect.width,rect.y+rect.height+textPadding,Math.PI);

        // left
        text=drawTextAtAngle(text,rect.height,rect.x-textPadding,rect.y+rect.height,Math.PI*1.5);

        // draw the rect (just for illustration)
        ctx.beginPath();
        ctx.rect(rect.x,rect.y,rect.width,rect.height);
        ctx.stroke();

    }


}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=250></canvas>
</body>
</html>

[根据提问者澄清添加更多自动换行代码]

您可以使用context.measureText来获取文本的宽度,并使用它来包装图像周围的文本。

enter image description here

给定文本宽度,当文本超出所需宽度时,可以通过前进到下一行来构建自动换行。

在环绕图片的情况下,您将有2个所需的宽度 - 更短,而文本可能会在图像中运行,之后会更长。

这是代码和小提琴:http://jsfiddle.net/m1erickson/XM5Yp/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var maxWidth = 350;
    var lineHeight = 25;
    var x = (canvas.width - maxWidth) / 2;
    var y = 60;
    var text = "'Twas the night before Christmas, when all through the house.  Not a creature was stirring, not even a mouse.  The stockings were hung by the chimney with care in hopes that St. Nicholas soon would be there.";

    ctx.font = '16pt Calibri';
    ctx.fillStyle = '#333';

    var imgWidth;
    var imgHeight;

    var img=new Image();
    img.onload=function(){

        imgWidth=img.width;
        imgHeight=img.height;

        ctx.drawImage(img,canvas.width-img.width,0)

        wrapText(text, x, y, maxWidth, lineHeight);

    }
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg";


    function wrapText(text, x, y, maxWidth, lineHeight) {

      var words = text.split(' ');
      var line = '';

      var maxLineWidth=y>imgHeight+10?maxWidth:maxWidth-imgWidth;

      for(var n = 0; n < words.length; n++) {
        var testLine = line + words[n] + ' ';
        var metrics = ctx.measureText(testLine);
        var testWidth = metrics.width;
        if(testWidth > maxLineWidth) {
          ctx.fillText(line, x, y);
          line = words[n] + ' ';
          y += lineHeight;
          maxLineWidth= y>imgHeight+10?maxWidth:maxWidth-imgWidth;

        }
        else {
          line = testLine;
        }
      }
      ctx.fillText(line, x, y);
    }

}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=400 height=325></canvas>
</body>
</html>