1.0.0 • Published 5 months ago

@zh-achieve/uni-vue3-canvas v1.0.0

Weekly downloads
-
License
MIT
Repository
-
Last release
5 months ago

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>
1.0.0

5 months ago

0.0.3

6 months ago

0.0.2

6 months ago

0.0.1

7 months ago