前端生成支付宝个人年度关键词

昨天,整个朋友圈都被支付宝的年度账单刷屏了。突然发现,原来自己的朋友圈里隐藏着众多土豪。当然啦,也有一些朋友ps一些好玩的截图。
实在无聊,晚上下班之后,就想着写个页面,让那些贪玩的朋友生成自己的年度关键词。先来看一下效果图。

基本功能点

  • 用户输入文案
  • 选取图片并裁剪
  • 图片合成

实现思路

天下武功,唯快不破。这是移动端的单页小应用,便于快速实现,于是选择了vue。
找了一下图片裁剪相关的库,vue-cropper 可以满足需求,于是就不需要自己造轮子了。具体的使用请看文档,这里不再赘述。
前端图片合成,可以使用canvas。

关键代码

思路有了,接下来就是搬砖的时候了。

一、图片上传读取

html:

<input type="file" accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg">

js:

uploadImg (e, num) {
    var file = e.target.files[0];
    if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
        alert('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种');
        return false;
    }
    var reader = new FileReader(file);

    reader.onload = (e) => {
        var data;
        if (typeof e.target.result === 'object') {
            data = window.URL.createObjectURL(new Blob([e.target.result]));
        } else {
            data = e.target.result;
        }
        this.option.img = data;
    }
    reader.readAsArrayBuffer(file);
}

二、图片合成

vue-cropper提供了一个getCropData的方法,用来获取裁剪框中的数据。将裁剪后的图像与背景图绘制在canvas上,再加上用户输入的文案,即可合成最终的效果图。
最后通过canvas的toDataURL方法,把画布里的图案转变成base64编码格式的图片数据,放在img标签中即可显示出来,用户长按图片,即可弹出保存选项。

function drawText(ctx, t, x, y, w) {//多行文字的绘制
    var chr = t.split('');
    var temp = '';
    var row = [];

    ctx.font = '45px Arial';
    ctx.fillStyle = '#7B7B7B';
    ctx.textBaseline = 'middle';

    for (var a = 0; a < chr.length; a++) {
        if (ctx.measureText(temp).width < w) {
        } else {
            row.push(temp);
            temp = '';
        }
        temp += chr[a];
    }

    row.push(temp);

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

this.$refs.cropper.getCropData(data => {
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    var width = 1080;
    var height = 1920;
    canvas.width = width;
    canvas.height = height;
    canvas.style.width = width + 'px';
    canvas.style.height = height + 'px';

    var bgImg = document.createElement('img');
    bgImg.src = bg;
    var avatarImg = document.createElement('img');
    avatarImg.src = data;
    var vm = this;
    bgImg.onload = function() {
        ctx.clearRect(0, 0, width, height);
        ctx.drawImage(bgImg, 0, 0, width, height);
        ctx.drawImage(avatarImg, 88, 476, 906, 664);
        ctx.font = '120px SimSun';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillStyle = '#636363';
        ctx.fillText(vm.title, 540, 1240);
        drawText(ctx, vm.desc, 540, 1310, 700);
        var dataURL = canvas.toDataURL('image/png');
        vm.resultUrl = dataURL;
    };
});

实现效果

猛戳体验

TODO

效果上看,最突出的问题在于字体。
如何在canvas中描绘文字的时候使用自定义的字体呢?

后记

朋友圈中常见的生成个性化图片的小应用,基本上是通过这种方式实现的。比如某某学校校庆,然后生成个性化头像。套路就是这样。
不说了,我去做头发了。

原文链接

原文链接

分享到:

发表评论

昵称

沙发空缺中,还不快抢~