canvas绘制

编写文本

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>canvas编写文本</title>
    <style type="text/css">
      canvas {
        border: 1px solid black;
        margin: 50px auto;
      }
    </style>
  </head>
  <body>
    <!-- canvas有兼容性问题,标签不识别时会读取里面内容 -->
    <canvas
      id="myCanvas"
      width="500"
      height="500"
      style="border:1px solid #000000;"
    >对不起,你的浏览器版本过低,点击<a href="#">下载</a>
    </canvas>
  </body>
  <script>
    window.onload = function() {
      var c = document.getElementById("myCanvas");
      //console.log(c);
      var ctx = c.getContext("2d");
      //绘制字体
      ctx.font = "30px Arial";
      //绘制空心字
      ctx.strokeText("年少的欢喜是你", 50, 100);
      //绘制实心字
      ctx.fillStyle = "dimgray";
      ctx.fillText("你是喜欢的少年", 50, 230);
      //绘制文本水平居中 (文本定位属性 textAlign)
      // ctx.textAlign="center"
      // ctx.fillText("你是喜欢的少年", canvas盒子的宽度/2, 230);
    };
  </script>
</html>
//注意点:谷歌浏览器要加载完之后才能使用canvas,所以js要写在window.οnlοad=function(){}中

绘制图片

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>canvas图片</title>
    <style type="text/css">
      canvas {
        /* border: 1px solid black; */
      }
    </style>
  </head>
  <body>
    <!-- canvas有兼容性问题,标签不识别时会读取里面内容 -->
    <canvas id="myCanvas" width="500" height="500">对不起,你的浏览器版本过低,点击<a href="#">下载</a></canvas>
    <img
      style="display:none;"
      src="https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1547028784732&di=77ff5804bf424d6d0cb0c175b2ff7f91&imgtype=0&src=http%3A%2F%2Fi2.hdslb.com%2Fbfs%2Fface%2F0f27137c1993f1a4034bb83349fb65601b7b420e.jpg"
      alt=""
    />
    <img style="display:none;" src="./images/timg.png" alt="" />
  </body>
  <script>
    window.onload = function() {
      var imgUrl = document.getElementsByTagName("img")[0].src; // 页面上已经加载了图片
      // 页面没有图片元素的要先加载图片才能绘制
      // const img = new Image()
	  // img.setAttribute('crossOrigin', 'Anonymous')
	  // img.src = src // src-图片地址
	
	  // img.onload = () => {
	  //   console.warn(src, '加载图片完成')
	  //   resolve(img)
	  // }
	  // img.onerror = (err) => {
	  //   console.warn(src, '加载图片失败')
	  //   reject(err)
	  // }
      var c = document.getElementById("myCanvas");
      //   console.log(c);
      var ctx = c.getContext("2d");
      // var img = new Image();
      // img.onload = function() {
      //   //图片平铺
      //   for (var i = 0; i < 4; i++) {
      //     for (var j = 0; j < 3; j++) {
      //       ctx.drawImage(img, j * 150, i * 150, 150, 150);
      //     }
      //   }
      // };
      // img.src = imgUrl;
      
      //相框制作:有层级关系,后画的图片在最上层
      // 相框
      ctx.drawImage(document.getElementsByTagName("img")[1], 0, 0,500,500);
      // 照片
      ctx.drawImage(document.getElementsByTagName("img")[0], 130, 150, 250, 250);      
    };
	//ctx.drawImage(所需绘制的图片, 图片在画布中的位置X, 图片在画布中的位置Y); //三个参数即可,可默认图片大小为绘制大小
    //ctx.drawImage(所需绘制的图片, 图片在画布中的位置X, 图片在画布中的位置Y, 绘制大小width, 绘制大小height);
    //ctx.drawImage(所需绘制的图片, 图片在画布中的位置X, 图片在画布中的位置Y, 绘制大小width, 绘制大小height, 图片裁剪起始位置X, 图片裁剪起始位置Y, 裁剪图片的宽度,裁剪图片的高度);//图片裁剪时使用
  </script>
</html>

小程序组件调用

ready() {
    //var pages = getCurrentPages()
    //var currentPage = pages[pages.length - 1]
    //var url = currentPage.route //当前页面路径
    //var options = currentPage.options //当前页面参数
    //console.log(url, 'url', options,'options')

    this.ctx = wx.createCanvasContext('myCanvas', this) //组件中调用需要导入this

    // var windowWidth = wx.getSystemInfoSync().windowWidth;
    // var width = windowWidth * this.data.width / 750
    // var height = width * this.data.height / this.data.width
    // this.setData({
    //   width: width,
    //   height: height
    // })

    // this.drawNormalImg();
    this.drawDetailsImg();   
    
  },

小程序组件中保存canvas绘制图片

saveImg() {
      this.drawDetailsImg();
      wx.showLoading({
        title: '加载中',
      })
      this.ctx.draw(false, wx.canvasToTempFilePath({
        canvasId: 'myCanvas',
        success(res) {
          wx.authorize({ //向用户发起授权请求
            scope: 'scope.writePhotosAlbum', //保存相册授权
            success: () => {
              wx.saveImageToPhotosAlbum({ //保存图片到系统相册
                filePath: res.tempFilePath,
                success: () => {
                  wx.hideLoading();
                  wx.showToast({
                    title: '图片保存成功'
                  })
                }
              })
            }
          })
        },
        fail: function (res) {
          console.log(res);
        }
      },this)); //同样需要导入this
    }

canvas特殊方法讲解

/* 以绘制分享海报图为例讲解 */
/* 1.beginPath() */
//开始一条路径,或重置当前的路径
//绘制网络图片时,一般是一个异步请求,需要保存之前全部路径,开始新的路径,所以需要重置(重新开始)一条新的路径时调用
//canvas中的绘制方法(如stroke,fill),都会以“上一次beginPath”之后的所有路径为基础进行绘制。
//绘制两条线时,如果找不到上一个beginPath(),会默认当一个路径重复绘制(不论你用moveTo()把画笔移动到哪里,只要不beginPath(),那你一直都是在画一条路径)
//fillRect与strokeRect,这种画出独立区域的函数,也不会打断当前的路径

/* 2.closePath() */
//创建从当前点到开始点的路径
//只是闭合当前的路径,从起点到现在的这个点形成一个闭合的回路
//并没有开启一个新路径

/* 3.save() */
//保存当前图像状态的一份拷贝
/* 4.restore() */
//将绘图状态置为保存值
//save()和restore()一般会一起使用,但是restore()的调用次数会远少于save(),每次save()会把当前绘画保存压入栈中,restore()会执行出栈操作
//以绘制圆形头像为例,先用save保存绘制的大圆,之后绘制小圆(剪切图像部分),绘制头像图片,使用restore恢复之前绘制状态

/* 5.clip() */
//从原始画布中剪切任意形状和尺寸

/* 6.measureText() */
//返回包含一个对象,该对象包含以像素计的指定字体宽度
//一般用于计算文本的宽度

/* 代码展示 */
drawNormalImg(){
      var that = this;
      let normal_img = that.data.normal_img;
      wx.getImageInfo({
        src: normal_img,
        success: res => {
          that.ctx.drawImage(res.path, 0, 0, that.data.width, that.data.height);
          that.ctx.save();
          that.ctx.beginPath();
          that.ctx.arc(164, 1502, 90, 0, 2 * Math.PI);
          that.ctx.fillStyle = "#fff";
          that.ctx.fill();
          that.ctx.save();
          that.ctx.beginPath();
          let image = that.data.avatarUrl;
          wx.getImageInfo({
            src: image,
            success: res => {
              that.ctx.arc(164, 1502, 81, 0, 2 * Math.PI);
              that.ctx.clip();
              let tempPath = res.path;
              that.ctx.drawImage(tempPath, 74, 1412, 180, 180);
              that.ctx.restore();

              that.ctx.setFontSize(40);
              that.ctx.setFillStyle('#999999');
              that.ctx.fillText('用户昵称有十个字的啊:', 84, 1648);
              that.ctx.save();
              that.ctx.setFillStyle('#333');
              that.ctx.font = "normal bold 58px 'Microsoft YaHei'";
              that.ctx.fillText('买农资 上大丰收', 84, 1726);
              that.ctx.save();
              that.ctx.beginPath();

              let img = that.data.ewmUrl;
              wx.getImageInfo({
                src: img,
                success: res => {
                  that.ctx.drawImage(res.path, 708, 1547, 292, 292);
                  that.ctx.restore();
                  that.ctx.draw();
                }
              });
            }
          })
        }
      });      
    },
    drawDetailsImg(){
      var that = this;
      var details_img = that.data.details_img;
      wx.getImageInfo({
        src: details_img,
        success: res => {
          that.ctx.drawImage(res.path, 0, 0, that.data.width, that.data.height);
          that.ctx.save();
          that.ctx.arc(135, 454, 89, 0, 2 * Math.PI);
          that.ctx.fillStyle = "#fff";
          that.ctx.fill();
          that.ctx.save();
          that.ctx.beginPath();
          let image = that.data.avatarUrl;
          wx.getImageInfo({
            src: image,
            success: res => {
              that.ctx.arc(135, 454, 81, 0, 2 * Math.PI);
              that.ctx.clip();
              let tempPath = res.path;
              that.ctx.drawImage(tempPath, 45, 364, 178, 178);
              that.ctx.restore();

              that.ctx.setFontSize(40);
              that.ctx.setFillStyle('#999999');
              that.ctx.fillText('用户昵称有十个字的啊:', 251, 424);
              that.ctx.save();
              that.ctx.setFillStyle('#333');
              that.ctx.font = "normal bold 54px 'Microsoft YaHei'";
              that.ctx.fillText('买农资 上大丰收', 251, 504);
              that.ctx.save();
              that.ctx.beginPath();

              let pro_img = that.data.proUrl;
              wx.getImageInfo({
                src: pro_img,
                success: res => {
                  that.ctx.drawImage(res.path, 90, 562, 899, 899);
                  that.ctx.restore();
                  that.ctx.setFillStyle('#FF5146');
                  that.ctx.font = "normal bold 54px 'Microsoft YaHei'";
                  that.ctx.fillText('¥', 53, 1559);
                  that.ctx.setFillStyle('#FF5146');
                  that.ctx.font = "normal bold 81px 'Microsoft YaHei'";
                  that.ctx.fillText('549', 104, 1559);
                  that.ctx.save();

                  that.ctx.setFillStyle('#999999');
                  that.ctx.font = "normal normal 45px 'Microsoft YaHei'";
                  that.ctx.fillText('¥999', 53, 1617);
                  var width = Math.floor(that.ctx.measureText('¥999').width); //获取划线价宽度
                  that.ctx.beginPath();
                  that.ctx.moveTo(53, 1600);//起始位置
                  that.ctx.lineTo(60 + width, 1600);//停止位置
                  that.ctx.lineWidth = 2;
                  that.ctx.strokeStyle = "#999999";
                  that.ctx.stroke();
                  that.ctx.save();

                  that.ctx.setFillStyle('#333');
                  that.ctx.font = "normal bold 54px 'Microsoft YaHei'";
                  var strArr = that.strSplit(that.data.pro_text, 550);
                  that.ctx.fillText(strArr[0], 53, 1700);
                  that.ctx.fillText(strArr[1], 53, 1766);
                  that.ctx.save();
                  that.ctx.beginPath();

                  let img = that.data.ewmUrl;
                  wx.getImageInfo({
                    src: img,
                    success: res => {
                      that.ctx.drawImage(res.path, 708, 1547, 292, 292);
                      that.ctx.restore();
                      that.ctx.draw();
                    }
                  });
                }
              });

            }
          })
        }
      });
      
    },
    strSplit(str,w){ //字符换行分段
      var temp = '';
      var row = [];
      for (var i = 0; i < str.split('').length; i++) {
        if (this.ctx.measureText(temp).width < w) {

        } else {
          row.push(temp);
          temp = "";
        }
        temp += str.split('')[i];
      }
      row.push(temp);
      return row;
    },

canvas绘制图片时获取定宽图片高

img.onload = () => {
   const ratio = img.height / img.width
   // halfWidth-需绘制图片宽度 halfHeight-等比缩放图片高度
   const halfHeight = ratio * halfWidth 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值