npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

taro-plugin-canvas

v1.0.10

Published

基于 Taro 框架的微信小程序 canvas 绘图组件,封装了常用的操作,通过配置的方式生成分享图片

Downloads

61

Readme

taro-plugin-canvas

小程序组件-小程序海报组件 npmnpm

概述

taro-plugin-canvas 是基于 Taro 框架的微信小程序 canvas 绘图组件,封装了常用的操作,通过配置的方式生成分享图片

本组件是基于 wxa-plugin-canvas 的Taro封装版本

生成效果

组件原理说明

参见 wxa-plugin-canvas => https://juejin.im/post/5b7e48566fb9a01a1059543f

使用之前

使用 taro-plugin-canvas 前,请确保你已经学习过微信官方的 小程序简易教程 和 自定义组件介绍

安装

通过 npm 安装 (推荐)

小程序已经支持使用 npm 安装第三方包,详见 npm 支持

# npm
npm i taro-plugin-canvas -S --production

# yarn
yarn add taro-plugin-canvas --production

使用组件

// 引入代码
import { TaroCanvasDrawer } from '../../component/taro-plugin-canvas';

// 在 render 方法中调用
<TaroCanvasDrawer
  config={this.state.config}
  onCreateSuccess={this.onCreateSuccess}
  onCreateFail={this.onCreateFail}
/>
// 注意点 
// config 绘图配置信息 - 必填项
// onCreateSuccess 绘图成功回调 - 必须实现 => 接收绘制结果、重置 TaroCanvasDrawer 状态
// onCreateFail 绘图失败回调 - 必须实现 => 接收绘制错误信息、重置 TaroCanvasDrawer 状态

方式二.下载代码

直接通过 git 下载 taro-plugin-canvas 源代码,并将src/component/taro-plugin-canvas目录拷贝到自己的项目的 src/component目录中

使用组件

// 引入代码 *引入方式和上面的方式一略有不同
import TaroCanvasDrawer from '../../component/taro-plugin-canvas';

// 在 render 方法中调用 和方式一一样

使用注意事项

  1. 图片的域名务必添加到downloadFile合法域名中(开发设置-服务器域名-downloadFile合法域名) 【P.s 开发时可 选中不校验合法域名、web-view(业务域名)、TLS 版本以及 HTTPS 证书】 【P.s 真机运行,可打开调试模式】

组件参数解释

config字段

| 字段 | 类型 | 必填 | 描述 | | --------------- | ------------------------ | ---- | ------------------------------------------ | | width | Number(单位:rpx) | 是 | 画布宽度 | | height | Number(单位:rpx) | 是 | 画布高度 | | backgroundColor | String | 否 | 画布颜色 | | debug | Boolean | 否 | false隐藏canvas,true显示canvas,默认false | | preload | Boolean | 否 | true:图片资源预下载 默认false | | hide-loading | Boolean | 否 | true:隐藏loading 默认false | | blocks | Object Array(对象数组) | 否 | 看下文 | | texts | Object Array(对象数组) | 否 | 看下文 | | images | Object Array(对象数组) | 否 | 看下文 | | lines | Object Array(对象数组) | 否 | 看下文 | | pixelRatio | Number | 否 | 1为一般,值越大越清晰 |

blocks字段

| 字段名 | 类型 | 必填 | 描述 | | --------------- | ---------------- | ---- | -------------------------------------- | | x | Number(单位:rpx) | 是 | 块的坐标 | | y | Number(单位:rpx) | 是 | 块的坐标 | | width | Number(单位:rpx) | 否 | 如果内部有文字,由文字宽度和内边距决定 | | height | Number(单位:rpx) | 是 | | | paddingLeft | Number(单位:rpx) | 否 | 内左边距 | | paddingRight | Number(单位:rpx) | 否 | 内右边距 | | borderWidth | Number(单位:rpx) | 否 | 边框宽度 | | borderColor | String | 否 | 边框颜色 | | backgroundColor | String | 否 | 背景颜色 | | borderRadius | Number(单位:rpx) | 否 | 圆角 | | text | Object | 否 | 块里面可以填充文字,参考texts字段解释 | | zIndex | Int | 否 | 层级,越大越高 |

texts字段

| 字段名 | 类型 | 必填 | 描述 | | -------------- | ---------------- | ---- | ------------------------------------------------------------ | | x | Number(单位:rpx) | 是 | 坐标 | | y | Number(单位:rpx) | 是 | 坐标 | | text | String|Object | 是 | 当Object类型时,参数为text字段的参数,marginLeft、marginRight这两个字段可用(示例请看下文) | | fontSize | Number(单位:rpx) | 是 | 文字大小 | | color | String | 否 | 颜色 | | opacity | Int | 否 | 1为不透明,0为透明 | | lineHeight | Number(单位:rpx) | 否 | 行高 | | lineNum | Int | 否 | 根据宽度换行,最多的行数 | | width | Number(单位:rpx) | 否 | 没有指定为画布宽度 | | marginLeft | Number(单位:rpx) | 否 | 当text字段为Object可以使用,用来控制多行文字间距 | | marginRight | Number(单位:rpx) | 否 | 当text字段为Object可以使用,用来控制多行文字间距 | | textDecoration | String | 否 | 目前只支持 line-through(贯穿线),默认为none | | baseLine | String | 否 | top| middle|bottom基线对齐方式 | | textAlign | String | 否 | left|center|right对齐方式 | | zIndex | Int | 否 | 层级,越大越高 | | fontFamily | String | 否 | 小程序默认字体为'sans-serif', 请输入小程序支持的字体,例如:'STSong' | | fontWeight | String | 否 | 'bold'加粗字体,目前小程序不支持 100 - 900 加粗 | | fontStyle | String | 否 | 'italic'倾斜字体 |

images字段

| 字段 | 类型 | 必填 | 描述 | | ------------ | ---------------- | ---- | ----------------------------------------- | | x | Number(单位:rpx) | 是 | 右上角的坐标 | | y | Number(单位:rpx) | 是 | 右上角的坐标 | | url | String | 是 | 图片url(需要添加到下载白名单域名中)也支持本地图片 | | width | Number(单位:rpx) | 是 | 宽度(会根据图片的尺寸同比例缩放) | | height | Number(单位:rpx) | 是 | 高度(会根据图片的尺寸同比例缩放) | | borderRadius | Number(单位:rpx) | 否 | 圆角,跟css一样 | | borderWidth | Number(单位:rpx) | 否 | 边框宽度 | | borderColor | String | 否 | 边框颜色 | | zIndex | Int | 否 | 层级,越大越高 |

lines字段

| 字段 | 类型 | 必填 | 描述 | | ------ | ---------------- | ---- | -------------- | | startX | Number(单位:rpx) | 是 | 起始坐标 | | startY | Number(单位:rpx) | 是 | 起始坐标 | | endX | Number(单位:rpx) | 是 | 终结坐标 | | endY | Number(单位:rpx) | 是 | 终结坐标 | | width | Number(单位:rpx) | 是 | 线的宽度 | | color | String | 否 | 线的颜色 | | zIndex | Int | 否 | 层级,越大越高 |

事件

success

成功回调 onCreateSuccess

返回生成海报图片的本地url,一般做法是使用wx.previewImage预览海报或者在指定位置预览,如下

// 绘制成功回调函数 (必须实现)=> 接收绘制结果、重置 TaroCanvasDrawer 状态
  onCreateSuccess = (result) => {
    const { tempFilePath, errMsg } = result;
    Taro.hideLoading();
    if (errMsg === 'canvasToTempFilePath:ok') {
      this.setState({
        shareImage: tempFilePath,
        // 重置 TaroCanvasDrawer 状态
        canvasStatus: false,
        config: null
      })
    } else {
      // 重置 TaroCanvasDrawer 状态
      this.setState({
        canvasStatus: false,
        config: null
      })
      Taro.showToast({ icon: 'none', title: errMsg || '出现错误' });
      console.log(errMsg);
    }
  }

fail

错误回调 onCreateFail

// 绘制失败回调函数 (必须实现)=> 接收绘制错误信息、重置 TaroCanvasDrawer 状态
  onCreateFail = (error) => {
    Taro.hideLoading();
    // 重置 TaroCanvasDrawer 状态
    this.setState({
      canvasStatus: false,
      config: null
    })
    console.log(error);
  }

Demo

以下是简易的Demo实现,也可以clone代码,里面有具体实现,线上案例见小程序 RssFeed

import Taro, { Component } from '@tarojs/taro'
import { View, Button, Image } from '@tarojs/components'
import TaroCanvasDrawer from '../../component/taro-plugin-canvas'; // 拷贝文件到component的引入方式
// import { TaroCanvasDrawer  } from 'taro-plugin-canvas'; // npm 引入方式
import './index.scss'

export default class Simple extends Component {
  config = {
    navigationBarTitleText: '首页'
  }
  constructor(props) {
    super(props);
    this.state = {
      // 绘图配置文件
      config: null,
      // 绘制的图片
      shareImage: null,
      // TaroCanvasDrawer 组件状态
      canvasStatus: false,
      rssConfig: {
        width: 750,
        height: 750,
        backgroundColor: '#fff',
        debug: false,
        blocks: [
          {
            x: 0,
            y: 0,
            width: 750,
            height: 750,
            paddingLeft: 0,
            paddingRight: 0,
            borderWidth: 0,
            // borderColor: '#ccc',
            backgroundColor: '#EFF3F5',
            borderRadius: 0,
          },
          {
            x: 40,
            y: 40,
            width: 670,
            height: 670,
            paddingLeft: 0,
            paddingRight: 0,
            borderWidth: 0,
            // borderColor: '#ccc',
            backgroundColor: '#fff',
            borderRadius: 12,
          }
        ],
        texts: [
          {
            x: 80,
            y: 420,
            text: '国产谍战 真人演出,《隐形守护者》凭什么成为Steam第一?',
            fontSize: 32,
            color: '#000',
            opacity: 1,
            baseLine: 'middle',
            lineHeight: 48,
            lineNum: 2,
            textAlign: 'left',
            width: 580,
            zIndex: 999,
          },
          {
            x: 80,
            y: 590,
            text: '长按扫描二维码阅读完整内容',
            fontSize: 24,
            color: '#666',
            opacity: 1,
            baseLine: 'middle',
            textAlign: 'left',
            lineHeight: 36,
            lineNum: 1,
            zIndex: 999,
          },
          {
            x: 80,
            y: 640,
            text: '分享来自 「 RssFeed 」',
            fontSize: 24,
            color: '#666',
            opacity: 1,
            baseLine: 'middle',
            textAlign: 'left',
            lineHeight: 36,
            lineNum: 1,
            zIndex: 999,
          }
        ],
        images: [
          {
            url: 'http://pic.juncao.cc/rssfeed/images/demo.png',
            width: 670,
            height: 320,
            y: 40,
            x: 40,
            borderRadius: 12,
            zIndex: 10,
            // borderRadius: 150,
            // borderWidth: 10,
            // borderColor: 'red',
          },
          {
            url: 'https://pic.juncao.cc/cms/images/minapp.jpg',
            width: 110,
            height: 110,
            y: 570,
            x: 560,
            borderRadius: 100,
            borderWidth: 0,
            zIndex: 10,
          },
        ],
        lines: [
          {
            startY: 540,
            startX: 80,
            endX: 670,
            endY: 541,
            width: 1,
            color: '#eee',
          }
        ]
      },
    }
  }

  // 调用绘画 => canvasStatus 置为true、同时设置config
  canvasDrawFunc = (config = this.state.rssConfig) => {
    this.setState({
      canvasStatus: true,
      config: config,
    })
    Taro.showLoading({
      title: '绘制中...'
    })
  }

  // 绘制成功回调函数 (必须实现)=> 接收绘制结果、重置 TaroCanvasDrawer 状态
  onCreateSuccess = (result) => {
    const { tempFilePath, errMsg } = result;
    Taro.hideLoading();
    if (errMsg === 'canvasToTempFilePath:ok') {
      this.setState({
        shareImage: tempFilePath,
        // 重置 TaroCanvasDrawer 状态,方便下一次调用
        canvasStatus: false,
        config: null
      })
    } else {
      // 重置 TaroCanvasDrawer 状态,方便下一次调用
      this.setState({
        canvasStatus: false,
        config: null
      })
      Taro.showToast({ icon: 'none', title: errMsg || '出现错误' });
      console.log(errMsg);
    }
    // 预览
    // Taro.previewImage({
    //   current: tempFilePath,
    //   urls: [tempFilePath]
    // })
  }

  // 绘制失败回调函数 (必须实现)=> 接收绘制错误信息、重置 TaroCanvasDrawer 状态
  onCreateFail = (error) => {
    Taro.hideLoading();
    // 重置 TaroCanvasDrawer 状态,方便下一次调用
    this.setState({
      canvasStatus: false,
      config: null
    })
    console.log(error);
  }

   // 保存图片至本地
  saveToAlbum = () => {
    const res = Taro.saveImageToPhotosAlbum({
      filePath: this.state.shareImage,
    });
    if (res.errMsg === 'saveImageToPhotosAlbum:ok') {
      Taro.showToast({
        title: '保存图片成功',
        icon: 'success',
        duration: 2000,
      });
    }
  }

  render() {
    return (
      <View className='index'>
        <View>
          <View className='flex-row'>
            <Button onClick={this.canvasDrawFunc.bind(this, this.state.rssConfig)}>绘制</Button>
            <Button onClick={this.saveToAlbum}>保存到相册</Button>
          </View>
        </View>
        <View className='shareImage-cont'>
          <Image
            className='shareImage'
            src={this.state.shareImage}
            mode='widthFix'
            lazy-load
          />
          {
            // 由于部分限制,目前组件通过状态的方式来动态加载
            this.state.canvasStatus &&
            (<TaroCanvasDrawer
              config={this.state.config} // 绘制配置
              onCreateSuccess={this.onCreateSuccess} // 绘制成功回调
              onCreateFail={this.onCreateFail} // 绘制失败回调
            />
            )
          }
        </View>
      </View>
    )
  }
}

问题反馈

有什么问题可以直接提issue

提issue