小程序canvas常用方法

小程序中的canvas和其他端的稍有不同,大多数canvas库在小程序中都不能直接import后使用,分享项目中小程序绘制canvas图片常用的一些方法,可以保存文件后直接使用,以下代码赶工出来的很粗糙,目的为抛砖引玉,或解急需使用的燃眉之急;

功能预览:

  1. 计算元素实际尺寸
  2. 保存网络图片到本地
  3. canvas2Img
  4. 绘制背景
  5. 插入图片
  6. 插入文本
  7. 绘制线条
  8. 绘制圆环
  9. 绘制圆角矩形
  10. 实心圆角矩形
/*
	name:makeCanvas
	author:I1326
	tel:
	weChat:
*/
const promisify = require('promisify');
const downFile = promisify(wx.downloadFile);
let realWidth,realHeight;
// 计算实际尺寸
function getPx(el){
  return new Promise(function (resolve, reject){
    let canvasQuery = wx.createSelectorQuery();
    canvasQuery.select('#'+el).boundingClientRect();
    canvasQuery.exec(function (res) {
      realWidth = res[0].width;
      realHeight = res[0].height;
      resolve(realWidth, realHeight)
    });
  })
}

function changeR(w, h){
  let tmpW = w,
     tmpH = h;
  tmpW = w * realWidth / 340;
  tmpH = h * realHeight / 380;
  return {
    w: tmpW,
    h: tmpH
  };
}

//保存网路图片
function saveIntPic(_url,callback){
  // wx.showLoading({  })
  return downFile({ url: _url }).then(img => {
    callback(img.tempFilePath);
  }, err => {
    console.log('save pic error')
  })
}

// 将生成的canvas图片,转为真实图片
function getPic(el,callback){
  wx.canvasToTempFilePath({
    x: 0,
    y: 0,
    canvasId: el,
    success: function (res) {
      callback(res.tempFilePath)
    },
    fail: function (res) {
      console.log('err==')
    }
  })
}

//绘制背景--把图片素材推进画布
function postBg(_img,ctx) {
  return new Promise(resolve=>{
    getPx(ctx.canvasId).then(function(){
      ctx.save();
      ctx.drawImage(_img, 0, 0, realWidth, realHeight);
      ctx.restore();
      resolve();
    })
  })
}

//插入图片素材到画布
function postImg(_img,ctx,dx=0,dy=0,dw=realHeight,dh=realHeight) {
  return new Promise(resolve=>{
    getPx(ctx.canvasId).then(function(){
      let xy = changeR(dx,dy);
      let wh = changeR(dw, dh);
      ctx.save();
      ctx.drawImage(_img, xy.w,xy.h, wh.w, wh.h);
      ctx.restore();
    })
  })
}
//插字
function addFont(ctx,x=0,y=0,txt='.',col='#000',size=12,align='left'){
  getPx(ctx.canvasId).then(function () {
    let xy = changeR(x, y);
    let wh = changeR(size, 1);
    ctx.save();
    ctx.setFontSize(wh.w);
    ctx.setFillStyle(col);
    ctx.setTextAlign(align);
    ctx.fillText(txt,xy.w,xy.h);
    ctx.restore();
  })
}

//插线
function addLine(ctx,x=0,y=0,dx=0,dy=0,wid=1,col='#000'){
  getPx(ctx.canvasId).then(function () {
    let xy = changeR(x, y);
    let wh = changeR(dx,dy);
    let _width = changeR(wid,1);
    ctx.save();
    ctx.beginPath()
    ctx.setLineWidth(_width.w)
    ctx.strokeStyle = col;
    ctx.moveTo(xy.w,xy.h)
    ctx.lineTo(wh.w, wh.h)
    ctx.stroke()
    ctx.restore();
  })
}

// 绘制圆环
function ring(ctx, x, y, w,ho,col1,no,col2){
  const hodeg = ho / (ho + no);
  getPx(ctx.canvasId).then(function () {
    let xy = changeR(x, y);
    let wh = changeR(w, 1);
    ctx.save()
    ctx.beginPath();
    ctx.lineWidth = wh.w;
    ctx.strokeStyle = col1;
    ctx.arc(xy.w, xy.h, wh.w, 0, Math.PI * 2 * hodeg, false);
    ctx.stroke();
    ctx.closePath();
    ctx.beginPath();
    ctx.strokeStyle = col2;
    ctx.arc(xy.w, xy.h, wh.w, Math.PI * 2 * hodeg, Math.PI * 2, false);
    ctx.stroke();
    ctx.closePath();
    ctx.restore();
  })
}



/**该方法用来绘制一个有填充色的圆角矩形 
 * cxt:canvas的上下文环境 
 * x:左上角x轴坐标 
 * y:左上角y轴坐标 
 * width:矩形的宽度 
 * height:矩形的高度 
 * radius:圆的半径 
 * fillColor:填充颜色 
 **/
function fillRoundRect(cxt, x, y, width, height, radius, fillColorA, fillColorB) {
  getPx(cxt.canvasId).then(function () {
    let xy = changeR(x, y);
    //圆的直径必然要小于矩形的宽高          
    if (2 * radius > width || 2 * radius > height) { return false; }
    cxt.save();
    cxt.translate(xy.w, xy.h);
    //绘制圆角矩形的各个边  
    drawRoundRectPath(cxt, width, height, radius);
    let gradient = cxt.createLinearGradient(width - 90, height, width, height);
    gradient.addColorStop(0, fillColorA);
    gradient.addColorStop(1, fillColorB);
    cxt.fillStyle = gradient; //若是给定了值就用给定的值否则给予默认值  
    cxt.fill();
    cxt.restore();
  })
}


/**该方法用来绘制圆角矩形 
 * cxt:canvas的上下文环境 
 * x:左上角x轴坐标 
 * y:左上角y轴坐标 
 * width:矩形的宽度 
 * height:矩形的高度 
 * radius:圆的半径 
 * lineWidth:线条粗细 
 * strokeColor:线条颜色 
 **/
function strokeRoundRect(cxt, x, y, width, height, radius, /*optional*/ lineWidth, /*optional*/ strokeColor) {
  //圆的直径必然要小于矩形的宽高          
  if (2 * radius > width || 2 * radius > height) { return false; }
  cxt.save();
  cxt.translate(x, y);
  //绘制圆角矩形的各个边  
  drawRoundRectPath(cxt, width, height, radius);
  cxt.lineWidth = lineWidth || 2; //若是给定了值就用给定的值否则给予默认值2  
  cxt.strokeStyle = strokeColor || "#000";
  cxt.stroke();
  cxt.restore();
}

function drawRoundRectPath(cxt, width, height, radius) {
  cxt.beginPath(0);
  //从右下角顺时针绘制,弧度从0到1/2PI  
  cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
  //矩形下边线  
  cxt.lineTo(radius, height);
  //左下角圆弧,弧度从1/2PI到PI  
  cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
  //矩形左边线  
  cxt.lineTo(0, radius);
  //左上角圆弧,弧度从PI到3/2PI  
  cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);
  //上边线  
  cxt.lineTo(width - radius, 0);
  //右上角圆弧  
  cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2)
  //右边线  
  cxt.lineTo(width, height - radius);
  cxt.closePath();
}


module.exports = {
  saveIntPic: saveIntPic,
  getPic: getPic,
  postBg: postBg,
  postImg:postImg,
  addFont:addFont,
  addLine: addLine,
  ring: ring,
  fillRoundRect: fillRoundRect,
  changeR: changeR,
  getPx: getPx
};
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值