H5 通过canvas合成图片,canvas 绘制文字自动换行

蛰伏已久 蛰伏已久 2018-04-22

我们经常可以看到朋友圈发布的营销海报,最近公司也要做一个,要求图片上方为logo,中间为资讯简介,底部为公众号二维码,管理员可以在管理后台生成分享图片,查了一下资料,可以通过canvas功能来实现。

为了方便管理员看到图片生成后的效果,我决定整个页面分两部分,第一部分为预览部分,第二部分为canvas,预览部分可以模拟合成后的图片样式。

//模拟合成后的图片,顶部一张图,底部一张图中间一个输入框,可以输入想要显示的文字
<div class="canvas">
    <img src="/dist/img/canvas/head.png"  id="head">
    <textarea id="desc"><?=$detail->desc?></textarea>
    <img src="/dist/img/canvas/foot.png"  id="foot">
</div>

//此处为canvas,用来合成图片
<canvas id="share" width="750" height="613">

1.获取canvas对象

var mainCtx = document.getElementById("share").getContext("2d");

2.合成顶部和底部的图片

  • 设置画布的宽高

  • 获取顶部图片,填充到画布顶部

  • 获取底部二维码图片,填充到画布底部

function hechen(){
    
    //定义canvas的宽高
    var maxWidth = 750;
    var maxHeight = 613;


    mainCtx.width=maxWidth;
    mainCtx.height=maxHeight;

    //将整个背景填充为白色
    mainCtx.fillStyle="#fff";
    mainCtx.fillRect(0,0,maxWidth,maxHeight);
   
    //获取顶部图片,填充到画布起始位置 
    var img=document.getElementById("head");
    mainCtx.drawImage(img,0,0);
    
    //获取底部图片,填充到画布起始位置 
    var img=document.getElementById("foot");
    mainCtx.drawImage(img,0,maxHeight-117);

}

在画布上绘制图片有两种方式,一种如上,直接获取图片element,填充到画布

var img=document.getElementById("head");
    mainCtx.drawImage(img,0,0);

如果我们是填充网络图片,这样就不行了,必须等到图片加载完毕再填充

var img=new Image();
img.src="你的图片地址";
img.onload=function(){
   mainCtx.drawImage(img,0,0); 
}

如果有多张图片,需要一张一张加载,可以通过递归来实现

var  data=[
    {
        src:$("#head").attr("src"),
        x:0,
        y:0,
        width:750,
        height:131
    },
    {
        src:$("#foot").attr("src"),
        x:0,
        y:132,
        width:750,
        height:117
    },

];

draw(0,data,mainCtx);

function draw(n,data,ctx){

    var len=data.length;
    if(n < len){
        //绘制第n张图片
        var img=new Image();
        img.src=data[n].src
        img.onload=function(){
            ctx.drawImage(img,data[n].x,data[n].y,data[n].width,data[n].height)
            draw(n+1,data,ctx); //递归调用,直到加载所有的图片
        }
    }else {
    
        //所有图片加载完成之后要处理的业务,比如绘制文字,保存图片等
        drawText($('#desc').val(),90,120,600,40);
        saveImageInfo();
    }
}

3.绘制文字

canvas不支持自动换行绘制文字,因此必须要先对绘制的字符进行处理,根据长度分成数组,然后依次绘制

//t:要绘制的字符串
//x:文字起始x坐标  y:起始y坐标
//w:一行文字的宽度   h:行高
function drawText(t,x,y,w,h){

    var chr = t.split("");
    var temp = "";
    var row = [];
    //sans-serif Arial
    mainCtx.font ="normal normal lighter 30px  serif";
    mainCtx.fillStyle = "#777777";
    mainCtx.textBaseline = "middle";

    for(var a = 0; a < chr.length; a++){
        temp += chr[a];
        if( mainCtx.measureText(temp).width >= w || a==chr.length-1){
            row.push(temp);
            temp = "";
        }

    }


    for(var b = 0; b < row.length; b++){
        mainCtx.fillText(row[b],x,y+b*h);
    }
}

drawText($('#desc').val(),90,160,600,40);

4.保存图片

function saveImageInfo() {
    var mycanvas = document.getElementById("share");
    var image = mycanvas.toDataURL("image/jpg");
    var w=window.open('about:blank','image from canvas');
    w.document.write("<img src='"+image+"' alt='from canvas'/>");
}




分享到

点赞(0)