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

@zh-achieve/uni-vue3-canvas

v1.0.0

Published

uniapp-canvas方法

Downloads

7

Readme

uniapp一些操作canvas方法的封装

🛠️ 方法介绍


<script setup lang="ts">
import { useCanvas } from "@zh-achieve/uni-vue3-canvas"

const {
  canvasCtx, // UniApp.CanvasContext对象
  canvasImg, // 生成的图片
  getCanvasTextWidth, // 测量文字渲染的宽度 getCanvasTextWidth(text: string): number
  setCanvasStyle, // 设置canvas颜色供下一次绘制使用setCanvasStyle(color: string): void
  setCanvasWH, // 设置画布宽高大小setCanvasWH(width: number, height: number)
  setCanvasImg, // 在画布上画图片,见下方
  drawRoundRect, // 绘制内容的容器的圆角矩形,见下方
  getImageInfo, // 依据线上地址生成图片本地地址getImageInfo(imgSrc: string): Promise<any>
  rpxToPx, // rpx转为px  rpxToPx(rpx: number): number
  drawRoundImg, // 绘制带有圆角的图片, 可以绘制头像,见下方
  beginDraw, // 开始渲染  beginDraw(): Promise<void>
  createCanvasImg, // 创建图片需要在beginDraw完成之后再执行 createCanvasImg(): Promise<string> | undefined
  setCanvasFontText // 设置canvas填充文字,使用此方法前记得先设置颜色和字体大小,加下方
} = useCanvas("my-canvas")

/**
 * 在画布上画图片
 * @param img
 * @param x
 * @param y
 * @param maxwidth
 */
// setCanvasImg(img: string, x: number, y: number, width: number, height: number)

/**
 * 绘制内容的容器的圆角矩形
 * 带有radius的边框
 * @param x 开始点横坐标
 * @param y 开始点纵坐标
 * @param width 宽度
 * @param height 高度
 * @param radius 圆角
 * @param color 背景颜色
 */
// drawRoundRect(x: number, y: number, width: number, height: number, radius: number, color: string)

/**
   * 绘制带有圆角的图片, 可以绘制头像
   * @param img
   * @param x 起点x坐标
   * @param y 起点y坐标
   * @param width 宽度
   * @param height 高度
   * @param radius 圆角
   */
// drawRoundImg(img: string, x: number, y: number, width: number, height: number, radius = 0)
    

/**
 * 设置canvas填充文字,使用此方法前记得先设置颜色和字体大小
 * @param text	规定在画布上输出的文本。
 * @param x	开始绘制文本的 x 坐标位置(相对于画布)。
 * @param y	开始绘制文本的 y 坐标位置(相对于画布)。
 * @param color	颜色
 * @param font	符合css的font规则,至少需要提供字体大小和字体族名, 默认值"16px sans-serif"
 * @param maxWidth	可选。允许的最大文本宽度,以像素计。
 */
// setCanvasFontText(
//   text: string,
//   x: number,
//   y: number,
//   color = "#000",
//   font = "16px sans-serif",
//   maxwidth?: number
// )
</script>

🛠️ 使用举例

<template>
  <view class="content" v-if="isShow" @click.stop="isShow = false">
    <canvas
      class="my-canvas"
      @click.stop=""
      :style="{ width: canvasW + 'px', height: canvasH + 'px' }"
      canvas-id="my-canvas"
    ></canvas>
    <view class="save-btn" @click.stop="saveImage">保存图片</view>
    <image :style="{ width: canvasW + 'px', height: canvasH + 'px' }" :src="canvasImg" mode="scaleToFill" />
  </view>
</template>

<script setup lang="ts">

import { useCanvas } from "@zh-achieve/uni-vue3-canvas"
const canvasImg = ref("")
const {
  canvasCtx,
  setCanvasStyle,
  setCanvasWH,
  setCanvasFontSize,
  setCanvasText,
  setCanvasImg,
  drawRoundRect,
  getImageInfo,
  rpxToPx,
  drawDashLine,
  drawEmptyRound,
  beginDraw,
  drawRoundImg,
  createCanvasImg
} = useCanvas("my-canvas")
onBeforeUnmount(() => {
  canvasCtx.value = null
})
const isShow = ref(false)
const canvasW = ref(rpxToPx(550))
const canvasH = ref(rpxToPx(900))
const headerImg = ref("https://tva3.sinaimg.cn/large/ceeb653ely1fj7edfnsv7j20i20i2q3k.jpg")
const title = ref("titletitletitletitle")
const content = ref("contentcontentcontentcontentcontent")
const subTitle = ref("subTitlesubTitlesubTitlesubTitlesubTitlesubTitle")
const showCanvas = () => {
  isShow.value = true
  if (!canvasImg.value) {
    init()
  }
}
// 保存图片到相册
const saveImage = () => {
  console.log("saveImage")
}
const init = async () => {
  //初始化画布
  // uni.showLoading({
  //   title: "加载中...",
  //   mask: true
  // })
  //设置画布背景透明
  setCanvasStyle("rgba(255, 255, 255, 0)")
  //设置画布大小
  setCanvasWH(canvasW.value, canvasH.value)
  //绘制圆角背景
  drawRoundRect(0, 0, canvasW.value, canvasH.value, rpxToPx(18), "#FFFFFF")
  //获取标题图片
  let headerImgLocal = await getImageInfo(headerImg.value)
  let hW = rpxToPx(500)
  let hH = rpxToPx(500)
  //绘制标题图
  drawRoundImg(headerImgLocal, (canvasW.value - hW) / 2, (canvasW.value - hW) / 2, hW, hH, rpxToPx(16))

  //绘制标题
  canvasCtx.value?.setFontSize(14) //设置标题字体大小
  setCanvasStyle("#333") //设置标题文本颜色

  setCanvasText(title.value, (canvasW.value - hW) / 2, (canvasW.value - hW) / 2 + hH + rpxToPx(60))
  //绘制副标题
  setCanvasFontSize(14)
  setCanvasStyle("#858585")
  // 计算副标题的长度
  let sWidth = canvasCtx.value?.measureText(subTitle.value).width
  if (sWidth && sWidth > hW) {
    setCanvasText(
      subTitle.value.slice(0, 17) + "...",
      (canvasW.value - hW) / 2,
      (canvasW.value - hW) / 2 + hH + rpxToPx(110)
    )
  } else {
    setCanvasText(subTitle.value, (canvasW.value - hW) / 2, (canvasW.value - hW) / 2 + hH + rpxToPx(110))
  }
  // 绘制价格
  if (content.value) {
    //console.log(this.content)
    // setCanvasFontSize(14)
    setCanvasStyle("#999")
    /* this.ctx.fillText('¥',((canvasW.value-hW) / 2),(((canvasW.value-hW) / 2) + hH + rpxToPx(120))) */
    setCanvasFontSize(12)
    setCanvasText(content.value, (canvasW.value - hW) / 2 + rpxToPx(36), (canvasW.value - hW) / 2 + hH + rpxToPx(120))
  }
  //绘制虚线
  drawDashLine(
    rpxToPx(20),
    (canvasW.value - hW) / 2 + hH + rpxToPx(150),
    canvasW.value - rpxToPx(20),
    (canvasW.value - hW) / 2 + hH + rpxToPx(150),
    5
  )
  //左边实心圆
  drawEmptyRound(0, (canvasW.value - hW) / 2 + hH + rpxToPx(150), rpxToPx(20), "rgba(0, 0, 0, .4)")
  //右边实心圆
  drawEmptyRound(canvasW.value, (canvasW.value - hW) / 2 + hH + rpxToPx(150), rpxToPx(20), "rgba(0, 0, 0, .4)")
  //提示文案
  setCanvasFontSize(12)
  setCanvasStyle("#858585")
  setCanvasText("测试文字", (canvasW.value - hW) / 2 + rpxToPx(20), (canvasW.value - hW) / 2 + hH + rpxToPx(200))
  //底部广告
  let BottomAdImg = await getImageInfo("https://tva3.sinaimg.cn/large/ceeb653ely1fj7edfnsv7j20i20i2q3k.jpg")
  setCanvasImg(BottomAdImg, 50, 380, 50, 50)
  //小程序码
  let qrcodeImg = await getImageInfo("https://hot.online.sh.cn/images/attachement/jpeg/site1/20161229/IMGf48e3894467143297155510.jpeg")
  setCanvasImg(qrcodeImg, rpxToPx(384), (canvasW.value - hW) / 2 + hH + rpxToPx(200), rpxToPx(156), rpxToPx(156))
  //延迟渲染
  beginDraw().then(() => {
    createCanvasImg()?.then((url) => {
      canvasImg.value = url
      uni.hideLoading()
    })
  })
}
onMounted({
  showCanvas
})
</script>

<style scoped lang="scss">
.content {
  position: fixed;
  inset: 0;
  z-index: 9999999;
  background: rgb(0 0 0 / 40%);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;

  .my-canvas {
    position: absolute;
    left: -100%;
  }

  .save-btn {
    margin-top: 35rpx;
    color: #fff;
    background: linear-gradient(to right, #fe726b, #fe956b);
    padding: 15rpx 40rpx;
    border-radius: 50rpx;
  }
}
</style>