vue使用canvas合成海报

接着上面随笔,继续探索~~~

上篇合成海报的过程有点负责冗余。完全可以不借助插件,用canvas合成~~

需求背景:多张模版可供选择,用户输入姓名,上传头像,最终合成海报保存分享。

1.头像有黑色边框,可利用背景图剧中显示。用户输入的姓名定位到海报具体位置。

2.上传头像部分通过@change=uploadImg(e),e拿到图片信息。

   ---先做个判断拦截

  //上传图片
  var file = e.target.files[0];
  if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
    this.$toast('图片类型必须是.gif,jpeg,jpg,png,bmp中的一种')
    return false;
  }
   ---然后读取图片信息
      var reader = new FileReader();
  reader.onload = e => { // 该事件是读取完成的时候触发。
    this.headSrc = e.target.result // 上传图片
  }
  reader.readAsDataURL(file) // 读取文件
    -------此时用户上传图片已经渲染在页面上
3.合成海报。分三部分,一部分模版,一部分用户输入姓名,一部分用户上传头像
    -----
  var c = document.createElement("canvas");
  var ctx = c.getContext("2d");
  c.width = this.pw; // 画布宽
  c.height = this.ph; // 画布高
    -----
  var img = new Image();
  img.src = _this.bgurl; // 背景图
      
  img.onload = function() {
    ctx.drawImage(img, 0, 0, c.width, c.height);
    var img2 = new Image(); // 头像
    _this.ClippingImage(_this.heardSrc,1,function(url){
      img2.src = url; // 头像
      console.log('img2',img2.src,url)
      img2.onload = function() {
        var d =2 * 58; // 头像圆圈直径
        var cx = 545 + 54; // 圆心X轴坐标
        var cy = 604 + 54; // 圆心Y轴坐标
        ctx.arc(cx, cy, 54, 0, 2 * Math.PI); // 画圆
        ctx.clip(); // 闭合圆圈 使后面的作图限制在圆圈内
        ctx.drawImage(img2, 545, 604, d, d);  // 画头像

        ctx.strokeStyle='#c8c8c8'; // 头像描边颜色
        ctx.lineWidth=6; // 头像描边宽度
        ctx.beginPath(); // 开始画图
        ctx.arc(cx, cy, 54, 0, 2 * Math.PI); // 描边绘画
        ctx.stroke()
      
        _this.modelSrc = c.toDataURL("image/png", 1);
      };
                  
      ctx.font = "30px Arial"; // 用户姓名字体样式
      ctx.fillStyle="#fff";// 用户姓名字体颜色
      ctx.fillText(_this.name,600,580); // 把用户姓名写入具体位置
    })
  }
4.ClippingImage方法是裁剪用户上传头像的方法。
    ------
  ClippingImage(base64Codes,quality,callback) {
    var img = new Image();
    img.src = base64Codes;
    //生成canvas
    var canvas = document.createElement('canvas');
    var ctx = canvas.getContext('2d');
    var sX,sY;
    img.onload = function () {
      if(img.width > img.height) { // 长形
        canvas.width = img.height
        canvas.height = img.height
        sX = (img.width-img.height)/2
        sY = 0
      } else if (img.width < img.height) { // 竖形
        canvas.width = img.width
        canvas.height = img.width
        sX = 0
        sY = (img.height-img.width)/2
      } else { // 正方形
        canvas.width = img.width
        canvas.height = img.width
        sX = 0
        sY = 0
      }
      ctx.drawImage(img,sX,sY,canvas.width,canvas.height,0,0,canvas.width,canvas.height);
      var base64Result = canvas.toDataURL('image/png', quality);
      callback(base64Result)
   }
 }
 
 
 
 
 
 
 
 
posted @   啥啥都不是  阅读(550)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示