更新记录

1.0.11(2022-05-31)

  • 修复 uni.canvasToTempFilePath中组件实例导致输出失败问题

1.0.10(2022-05-19)

  • drawArray支持zIndex
  • drawArray支持type为function类型便于zIndex排序后执行
  • uni-app环境支持本地图片绘制

1.0.8(2022-05-15)

  • 开放源码, 完善文档,新增示例项目, 修改某些方法名

查看更多

平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.4.8 app-vue ×
钉钉小程序 快手小程序 飞书小程序 京东小程序
× × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
1.0.11 更新说明
  • 修复 uni.canvasToTempFilePath中组件实例导致输出失败问题
一款支持 Node、web、uni-app 的canvas绘图工具
有使用ES6语法 有需要需自行转ES5
目前uni-app环境 H5、APP 会存在clip裁剪失效的情况 hbx 3.4.8+ 已修复

Node环境注意:需要安装canvas npm i canvas, 并且切换Node版本后需要重新安装canvas

npm

npm i qs-canvas

Step1 引入

  • node

    const QSCanvas = require('qs-canvas')
  • web

    <script src="xxx.js"></script>
  • uni-app

    import QSCanvas from 'xxx.js'

Step2 QSCanvas对象

const qsc = new QSCanvas(options, vm)
options<Object>: {
    width<Number>: 10, //canvas的宽
    height<Number>: 10, //canvas的高
    canvasId<String>: '', //canvasId, uni-app必传、web可不传
    setCanvasWH<Function>: undefined, //动态设置canvas宽高方法, uni-app需传
    asyncDrawMode<Boolean>: true, //异步绘制模式, web、node支持, 控制是否像uni-app一样只有在调用draw时才绘制内容
}

vm<Object>: undefined //uni-app, 自定义组件实例 this ,表示在这个自定义组件下查找拥有 canvas-id 的 <canvas/> ,如果省略,则不在任何自定义组件内查找

Attribute

qsc._data<Object>: {
    oldPaintbrushProps: paintbrushProps<Object>, //当前画笔设置
    width<Number>: 10, //画布宽度
    height<Number>: 10, //画布高度
}

API

  • 支持原生canvas上下文所有方法(如: fill、save、clip...)

  • setPaintbrush

    设置画笔属性, 原生canvas上下文除所有方法外的属性均在此设置
    // 展示的是默认值, 不用都传
    qsc.setPaintbrush(paintbrushProps<Object>)
    paintbrushProps<Object>: {
        fillStyle<String>?: '#000000',
        strokeStyle<String>?: '#000000',
        shadowColor<String>?: '#000000',
        shadowBlur<Number>?: 0,
        shadowOffsetX<Number>?: 0,
        shadowOffsetY<Number>?: 0,
        lineCap<String>?: 'butt',
        lineJoin<String>?: 'miter',
        lineWidth<Number>?: 1,
        miterLimit<Number>?: 10,
        font: { // 头条小程序只支持fontSize
            fontStyle<String>?: 'normal', 
            fontVariant<String>?: 'normal', 
            fontWeight<String>?: 'normal', 
            fontSize<Number>?: 10, 
            fontFamily<String>?: 'sans-serif' 
        },
        textAlign<String>?: 'start',
        textBaseline<String>?: 'top',
        globalAlpha<Number>?: 1.0,
        globalCompositeOperation<String>?: 'source-over',
    }
  • resetPaintbrush

    重置画笔属性
    // 若不传参则重置为setPaintbrush中展示的默认值, 若传可覆盖
    qsc.resetPaintbrush(paintbrushProps<Object>?)
  • savePaintbrush

    保存画笔属性, 推入栈(先入后出)中保存, 可调用restorePaintbrush恢复
    qsc.savePaintbrush()
  • restorePaintbrush

    恢复最近一次保存的画笔属性
    qsc.restorePaintbrush()
  • saveAndSetPaintbrush

    先保存一次画笔属性, 再设置
    qsc.saveAndSetPaintbrush(paintbrushProps<Object>)
  • updateCanvasWH promise

    更新画布宽高
    // 该方法会在结束时自动调用一次resetPaintbrush(this._data.oldPaintbrushProps)
    await qsc.updateCanvasWH(options<Object>?)
    options<Object>: {
    width<Number>?: this.width, // 若不传则使用初始化时的width
    height<Number>?: this.height, // 若不传则使用初始化时的height
    delay<Number>?: 50, // uni-app更新画布宽高后延时操作
    }
  • draw promise

    执行绘制, web、node在异步绘制模式下同uni-app一样需调用, uni-app必须调用才能绘制
    await qsc.draw(options<Object>?)
    options<Obeject>: {
    reserve<Boolean>?: false, // 是否接着上一次绘制
    }
  • toImage promise

    canvas转图片
    await qsc.toImage(options<Object>?)
    options<Obeject>: {
    // web、node、uni-app 支持
    fileType<String>: 'png', // 图片格式
    quality<Number>: 1, // 图片质量,jpg格式有效
    
    // uni-app 支持
    x<Number>?: 0, // 画布x轴起点(默认0)
    y<Number>?: 0, // 画布y轴起点(默认0)
    width<Number>?: canvas宽度-x, // 画布宽度(默认为canvas宽度-x)
    height<Number>?: canvas高度-y, // 画布高度(默认为canvas高度-y)
    destWidth<Number>?: width * 屏幕像素密度, // 输出图片宽度(默认为 width * 屏幕像素密度)
    destHeight<Number>?: height * 屏幕像素密度, // 输出图片高度(默认为 height * 屏幕像素密度)
    }
  • drawText promise

    绘制文字, 调用calcText后进行绘制
    const calcR<Object> = await qsc.drawText(options<Object>?)
    options<Obeject>: {
    val<String>?: '', // 文字内容
    x<Number>?: 0, // x轴位置
    y<Number>?: 0, // y轴位置
    maxWidth<Number>?: null, // 达到此最大宽度后换行
    line<Number>?: -1, // 换行时行数, 小于零则无限, 为0时会赋值为1
    lineHeight<Number>?: 0, // 行高, 行与行之间的距离, 不计文字本身高度
    paintbrushProps<Object>?: paintbrushProps, // 设置画笔属性,可以传 fillStyle 控制颜色、font.fontSize控制字体大小等
    textDecoration<Object>?: {
        line<String>?: 'line-through', // 线条类型, 支持 ['line-through','underline','overline']
        color<String>?: oldProps.fillStyle || '#000000', // 线条颜色
        thickness<Number>|width<Number>?: fontSize * 0.1 || 1, // 线条宽度
        style<String>?: 'solide', // 线条样式, 支持 ['solide', 'double', 'dotted']
        offset<Number>?: 0, // 线条偏移
        gap<Number>?: 1, // 间隔,double、dotted时的间隔
    }
    }
    calcR<Object>: {
    calcTexts<Array>, // 计算后的文字数组
    x<Number>, // x轴位置
    y<Number>, // y轴位置
    height<Number>, // 高度
    width<Number>, // 宽度
    top<Number>, // 上边界
    left<Number>, // 左边界
    right<Number>, // 右边界
    bottom<Number>, // 下边界
    }
  • calcText promise

    计算需绘制的文字
    // calcR可直接传给drawText绘制
    const calcR<Object> = await qsc.calcText(options<Object>)
    options<Object>: 同drawText的options
  • drawImg promise

    绘制图片, 调用calcImg后进行绘制
    const calcR<Object> = await qsc.drawImg(options<Object>?)
    options<Obeject>: {
    val<String>?: '', // 图片路径, 支持 网络图片、1.0.10+ 本地图片(字节小程序只支持相对路径)、base64图片(某些小程序无法获取图片信息)
    x<Number>?: 0, // x轴位置
    y<Number>?: 0, // y轴位置
    mode<String>?: 'scaleToFill', // 绘制模式 同uni-app image mode, 支持 ['scaleToFill', 'aspectFit', 'aspectFill', 'widthFix', 'heightFix']
    width<Number>?: 0, // 图片宽度
    height<Number>?: 0, // 图片高度
    }
    calcR<Object>: {
    drawImageArgs<Array>, // 计算后的绘制参数
    x<Number>, // x轴位置
    y<Number>, // y轴位置
    height<Number>, // 高度
    width<Number>, // 宽度
    top<Number>, // 上边界
    left<Number>, // 左边界
    right<Number>, // 右边界
    bottom<Number>, // 下边界
    }
  • calcImg promise

    计算需绘制的图片
    // calcR可直接传给drawImg绘制
    const calcR<Object> = await qsc.calcText(options<Object>)
    options<Object>: 同drawImg的options
  • loadImage promise

    加载图片
    // img可直接传给 drawImg 或者 calcImg 当做 val 值
    const img<Object> = await qsc.loadImage(url<String>)
    url<String>: 图片路径
  • drawQrCode promise

    绘制二维码, 参考诗小柒的二维码生成器代码
    await qsc.drawQrCode(options<Object>?)
    options<Obeject>: {
    val<String>?: '', // 二维码内容
    x<Number>, // x轴位置
    y<Number>, // y轴位置
    size<Number>?: 200, // 二维码大小
    background<String>?: '#ffffff', // 背景色
    foreground<String>?: '#000000', // 前景色
    pdground<String>?: '#000000', // 定位角点颜色
    correctLevel<Number>?: 3, // 容错级别
    }
  • setCircle

    设置圆形
    qsc.setCircle(options<Object>?)
    options<Obeject>: {
    x<Number>, // x轴位置
    y<Number>, // y轴位置
    d<Number>, // 直径
    mode<String>?: 'leftTop', // 圆心模式, 支持 ['leftTop', 'center']
    clip<Boolean>?: false, // 是否裁剪, 设置true后 需手动 qsc.restore()
    }
  • setRect

    设置矩形
    qsc.setRect(options<Object>?)
    options<Obeject>: {
    x<Number>, // x轴位置
    y<Number>, // y轴位置
    r<Number>, // 圆角值
    width<Number>, // 宽度
    height<Number>, // 高度
    clip<Boolean>?: false, // 是否裁剪, 设置true后 需手动 qsc.restore()
    }
  • drawArray promise

    Array形式绘制
    const drawR<Array> = await qsc.drawArray(options<[]<Object|Function>>?)
    options<[]<Object|Function>>: [
    <Function>, //直接执行函数, 支持返回Promise
    <Object>:{
        type<String>: '', // 类型, 支持 ['text','image','qrcode','method', 'function']
        zIndex<Number>: 0, //1.0.10+ 层级, 越大越往后绘制
        //type 为 'text'、'image'、'qrcode'传原本方法需要传的参数
        ...options<Object>,
    
        // type 为 method 时
        name<String>: '', // 需要执行qsc下的方法名称
        data<Array|Object>, //传给执行方法的参数, Array时以...arguments传给执行方法, Obejct时以[data<Object>]传给执行方法
    
        //1.0.10+ type 为 function 时
        val<Function>: '', // 需要执行qsc下的方法名称
    }
    ]
  • initAsyncDrawMode

    转为异步绘制模式 uni-app无效
    qsc.initAsyncDrawMode()
  • restoreAsyncDrawMode

    取消异步绘制模式 uni-app无效
    qsc.restoreAsyncDrawMode()

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

许可协议

MIT协议

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问