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

canvas2posterjs

v0.0.5

Published

canvas to poster

Downloads

5

Readme

canvas2posterjs

draw with canvas,is faster then html2Canvas

usage

install

npm i canvas2posterjs -S

base

import CanvasToPoster from 'canvas2posterjs'
const paint = new CanvasToPoster({
  painting: {
    width: '550px',
    height: '876px',
    background: '#f4f5f7',
    views: []
  },
  immediate: true,
  imageType: 'jpeg',
  onSuccess(canvas) {
    document.body.append(canvas)
  },
  onError(err) {
    console.log(err)
  }
})

toImage

new CanvasToPoster({
  painting: {
    width: '550px',
    height: '876px',
    background: '#f4f5f7',
    views: []
  },
  immediate: true,
  imageType: 'jpeg'
}).toImage().then((image) => {
  document.body.append(image)
})

toBase64

new CanvasToPoster({
  painting: {
    width: '550px',
    height: '876px',
    background: '#f4f5f7',
    views: []
  },
  immediate: true,
  imageType: 'jpeg'
}).toBase64().then((base64) => {
  const image = new Image()
  image.src = base64
  document.body.append(image)
})

toCanvas

new CanvasToPoster({
  painting: {
    width: '550px',
    height: '876px',
    background: '#f4f5f7',
    views: []
  },
  immediate: true,
  imageType: 'jpeg'
}).toCanvas().then((canvas) => {
  document.body.append(canvas)
})

demo

import Canvas2Poster, { Painting } from 'canvas2posterjs'
const painting: Painting = {
  width: '750px',
  height: '1334px',
  background:
    'https://si.geilicdn.com/img-40d300000187ad60ace70a207569-unadjust_1125_2001.png?w=750',
  views: [
    {
      type: 'image',
      url: 'https://si.geilicdn.com/passport-0b67c6d7f6f35806c2107f1d030a93cf.jpg',
      css: {
        top: '95px',
        left: '327px',
        width: '102px',
        height: '102px',
        overflow: 'hidden',
        borderRadius: '50%'
      }
    },
    {
      type: 'text',
      text: '灶门家门口的小树苗灶门家门口的小灶门家门口的小树苗灶门家门口的小',
      css: {
        top: '218px',
        left: '103px',
        width: '544px',
        fontFamily: 'PingFangSC-Heavy',
        fontSize: '32px',
        color: '#FFFFFF',
        maxLines: 1,
        textAlign: 'center',
        fontWeight: '400'
      }
    },
    {
      type: 'image',
      url: 'https://si.geilicdn.com/img-589400000187ad66c7ca0a210349-unadjust_1125_1500.png',
      css: {
        top: '294px',
        left: '75px',
        width: '600px',
        height: '800px'
      }
    },
    {
      type: 'text',
      text: '2022年12月5日',
      css: {
        top: '430px',
        left: '160px',
        width: '430px',
        height: '38px',
        fontFamily: 'PingFangSC-Heavy',
        fontSize: '32px',
        color: 'rgba(0,0,0,0.40)',
        textAlign: 'center',
        fontWeight: '400'
      }
    },
    {
      type: 'text',
      text: '天生万物,',
      css: {
        top: '542px',
        left: '160px',
        width: '430px',
        lineHeight: '32px',
        fontFamily: 'PingFangSC-Heavy',
        fontSize: '32px',
        color: 'rgba(0,0,0,0.70)',
        textAlign: 'center',
        fontWeight: '600'
      }
    },
    {
      type: 'text',
      text: '谋望皆通,',
      css: {
        top: '622px',
        left: '160px',
        width: '430px',
        lineHeight: '32px',
        fontFamily: 'PingFangSC-Heavy',
        fontSize: '32px',
        color: 'rgba(0,0,0,0.70)',
        textAlign: 'center',
        fontWeight: '600'
      }
    },
    {
      type: 'text',
      text: '福德相助,',
      css: {
        top: '702px',
        left: '160px',
        width: '430px',
        lineHeight: '32px',
        fontFamily: 'PingFangSC-Heavy',
        fontSize: '32px',
        color: 'rgba(0,0,0,0.70)',
        textAlign: 'center',
        fontWeight: '600'
      }
    },
    {
      type: 'text',
      text: '瑞气匆匆,',
      css: {
        top: '782px',
        left: '160px',
        width: '430px',
        lineHeight: '32px',
        fontFamily: 'PingFangSC-Heavy',
        fontSize: '32px',
        color: 'rgba(0,0,0,0.70)',
        textAlign: 'center',
        fontWeight: '600'
      }
    },
    {
      type: 'text',
      text: '戳一戳👉',
      css: {
        bottom: '154px',
        left: '105px',
        lineHeight: '40px',
        fontFamily: 'PingFangSC-Heavy',
        fontSize: '28px',
        color: '#fff',
        fontWeight: '500'
      }
    },

    {
      type: 'text',
      text: '抽签今日幸运签🎐',
      css: {
        bottom: '102px',
        left: '105px',
        lineHeight: '37px',
        fontFamily: 'PingFangSC-Heavy',
        fontSize: '28px',
        color: '#fff',
        fontWeight: '400'
      }
    },
    {
      type: 'rect',
      css: {
        right: '92px',
        bottom: '92px',
        width: '116px',
        height: '116px',
        color: '#fff'
      }
    },
    {
      type: 'qrcode',
      content: 'https://github.com/coderlyu/canvas2Poster',
      css: {
        right: '96px',
        bottom: '96px',
        width: '108px',
        height: '108px'
      }
    }
  ]
}

new CanvasToPoster({
  painting,
  immediate: true,
  imageType: 'jpeg'
})
  .toCanvas()
  .then((canvas) => {
    document.body.append(canvas)
  })

效果

typescript helper

如果不了解每个 type 下的 css 都可以设置什么值,你可以借助 typescript 类型来帮助你(对外暴露了 Options, Painting )

import Canvas2Poster, { Options, Painting } from 'canvas2posterjs'
const painting: Painting = {
    width: '750px',
    height: '1414px',
    background:
      'https://si.geilicdn.com/img-111b0000018774e577790a2102d0-unadjust_1125_2121.png?w=750',
    views: [
      {
        type: 'image',
        url: 'https://si.geilicdn.com/passport-0b67c6d7f6f35806c2107f1d030a93cf.jpg',
        css: {
          top: '280px',
          left: '150px',
          width: '80px',
          height: '80px',
          borderRadius: '50%'
        }
      }
    ]
}
const options: Options = {
    painting: painting,
    immediate: true,
    imageType: 'jpeg'
}
const paint = new Canvas2Poster(options)

API

CanvasToPoster options

| 属性名 | 类型 | 说明 | 默认值 | | --------- | -------------- | ------------------------------ | ----- | | painting | object | canvas上绘制内容的json描述,见下方 | | | immediate | boolean | 是否在new CanvasToPoster的时候立即生成海报 | false | | imageType | 生成base64的图片类型, | 默认jpeg,若支持webp,将会使用webp格式 | '' | | onSuccess | 海报成功的回调 | | | | onError | 海报失败的回调 | | |

methods

| 方法名 | 入参 | 说明 | | ---------- | ---------------------- | --------------------------------------------------------------- | | startPaint | CanvasToPoster options | 在new CanvasToPoster 时,未设置immediate: true,可手动调用该方法同时传入最新的options |

painting 对象

具体信息见下方

painting(画布props)

| 属性名称 | 类型 | 说明 | 默认值 | | ------------ | ------ | ------------------------ | --- | | background | string | 画布背景,可以是颜色值或者图片的链接,支持渐变色 | 白色 | | width | string | 画布的宽度,单位px | | | height | string | 画布的高度,单位px | | | borderRadius | string | 边框的圆角 | 0px | | views | array | 数组,包含一系列对象,见下一节元素vies | |

view props

| 属性名 | 类型 | 说明 | 默认值 | 是否必须 | | ------- | ------ | ---------------------------------- | --- | ------------------ | | type | string | view的类型(text, image, rect, qrcode) | 无 | 是 | | text | string | 文本内容(type===text) | 无 | type=== text下必须 | | url | string | 图片(type===image) | 无 | type === image下必须 | | content | string | 用改链接生成二维码(type === qrcode) | 无 | type === qrcode下必须 |

text css

| 属性名称 | 类型 | 说明 | 默认值 | | -------------- | ------ | ------------------------------------------------------------------------------------------------------ | ----------- | | fontSize | string | 字体大小 | 20px | | color | string | 字体颜色 | black | | width | string | 换行宽度,当文字长度大于width,换行 | | | maxLines | number | 最大行数 | 不限,根据width来 | | lineHeight | string | 行高(上下两行文字baseline的距离) | fontSize大小 | | fontWeight | string | 字体粗细,'normal','blod','bolder','lighter', '100', '200', '300', '400', '500', '600', '700', '800', '900' | normal | | textDecoration | string | 文本修饰,支持underline, overline,line-through, 也可组合使用 | | | textStyle | string | fill:填充样式,stroke:镂空样式 | fill | | fontFamily | string | 字体,需引入字体 | sans-serif | | background | string | 文字背景颜色 | | | padding | string | 文字背景颜色边际与文字间距 | 0px | | textAlign | string | 文字的对齐方式,分为left, center, right, view的对齐方法请看align属性 | left | | textIndent | string | 文字首行缩进 | 0px |

image css

| 属性名 | 类型 | 说明 | 默认值 | | ------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------- | ---------- | | width | string | image的宽度 | auto | | height | string | image的高度 | auto | | mode | string | 图片裁剪、缩放的模式(scaleToFill:不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素; aspectFill:保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。) | aspectFill |

qrcode css

| 属性名 | 类型 | 说明 | 默认值 | | ------ | ------ | ----- | ----- | | color | string | 二维码颜色 | black | | width | string | 二维码宽度 | | | height | string | 二维码高度 | |

rect css

| 属性名 | 类型 | 说明 | 默认值 | | ------ | ------ | ---- | ----- | | color | string | 矩形颜色 | black | | width | string | 矩形宽度 | | | height | string | 矩形高度 | |

Questions

ts类型不兼容

如果遇到ts类型不兼容的问题,一般是传入 options 的 painting 报错,你可以从 canvas2posterjs 引入 Painting 或者 Options,如下示例

import Canvas2Poster, { Options, Painting } from 'canvas2posterjs'
const painting: Painting = {
    width: '750px',
    height: '1414px',
    background:
      'https://si.geilicdn.com/img-111b0000018774e577790a2102d0-unadjust_1125_2121.png?w=750',
    views: [
      {
        type: 'image',
        url: 'https://si.geilicdn.com/passport-0b67c6d7f6f35806c2107f1d030a93cf.jpg',
        css: {
          top: '280px',
          left: '150px',
          width: '80px',
          height: '80px',
          borderRadius: '50%'
        }
      }
    ]
}
const options: Options = {
    painting: painting,
    immediate: true,
    imageType: 'jpeg'
}
const paint = new Canvas2Poster(options)

or

import Canvas2Poster, { Painting } from 'canvas2posterjs'
const painting: Painting = {
    width: '750px',
    height: '1414px',
    background:
      'https://si.geilicdn.com/img-111b0000018774e577790a2102d0-unadjust_1125_2121.png?w=750',
    views: [
      {
        type: 'image',
        url: 'https://si.geilicdn.com/passport-0b67c6d7f6f35806c2107f1d030a93cf.jpg',
        css: {
          top: '280px',
          left: '150px',
          width: '80px',
          height: '80px',
          borderRadius: '50%'
        }
      }
    ]
}
new Canvas2Poster({
  painting: painting,
  immediate: true,
  imageType: 'jpeg'
})

or

import Canvas2Poster, { Painting } from 'canvas2posterjs'
const painting = {
    width: '750px',
    height: '1414px',
    background:
      'https://si.geilicdn.com/img-111b0000018774e577790a2102d0-unadjust_1125_2121.png?w=750',
    views: [
      {
        type: 'image',
        url: 'https://si.geilicdn.com/passport-0b67c6d7f6f35806c2107f1d030a93cf.jpg',
        css: {
          top: '280px',
          left: '150px',
          width: '80px',
          height: '80px',
          borderRadius: '50%'
        }
      }
    ]
}
new Canvas2Poster({
  painting: painting as Painting,
  immediate: true,
  imageType: 'jpeg'
})