uniapp 使用cavans 生成海报

uniapp 使用cavans 生成海报

javascript 复制代码
npm install qs-canvas

1.创建 useCanvas.js

javascript 复制代码
/**
 * Shopro + qs-canvas 绘制海报
 * @version 1.0.0
 * @author lidongtony
 * @param {Object} options - 海报参数
 * @param {Object} vm - 自定义组件实例
 */
import QSCanvas from 'qs-canvas';
import { getPosterData } from './poster';

export default async function useCanvas(options, vm) {
  const width = options.width;
  const qsc = new QSCanvas(
    {
      canvasId: options.canvasId,
      width: options.width,
      height: options.height,
      setCanvasWH: (canvas) => {
        options.height = canvas.height;
      },
    },
    vm,
  );

  let drawer = getPosterData(options);

  // 绘制背景图
  const background = await qsc.drawImg({
    type: 'image',
    val: drawer.background,
    x: 0,
    y: 0,
    width,
    mode: 'widthFix',
    zIndex: 0,
  });
  await qsc.updateCanvasWH({
    width: background.width,
    height: background.bottom,
  });

  let list = drawer.list;

  for (let i = 0; i < list.length; i++) {
    let item = list[i];
    // 绘制文字
    if (item.type === 'text') {
      await qsc.drawText(item);
    }
    // 绘制图片
    if (item.type === 'image') {
      if (item.d) {
        qsc.setCircle({
          x: item.x,
          y: item.y,
          d: item.d,
          clip: true,
        });
      }

      if (item.r) {
        qsc.setRect({
          x: item.x,
          y: item.y,
          height: item.height,
          width: item.width,
          r: item.r,
          clip: true,
        });
      }
      await qsc.drawImg(item);
      qsc.restore();
    }

    // 绘制二维码
    if (item.type === 'qrcode') {
      await qsc.drawQrCode(item);
    }
  }

  await qsc.draw();
  // 延迟执行, 防止不稳定
  setTimeout(async () => {
    options.src = await qsc.toImage();
  }, 100);
  return options;
}

index.vue

javascript 复制代码
<template>
 <canvas
        class="hideCanvas"
        :canvas-id="poster.canvasId"
        :id="poster.canvasId"
        :style="{
          height: poster.height + 'px',
          width: poster.width + 'px',
        }"
      />
 </template>
 <script setup>
 import useCanvas from './useCanvas';
  const props = defineProps({
    shareInfo: {
      type: Object,
      default() {},
    },
  });
 const Sys = uni.getSystemInfoSync();
 const poster = reactive({
    canvasId: 'canvasId',
    width: Sys.device.windowWidth * 0.9,
    height: 600,
    src: '',
  });
  
 async function getPoster() {
    poster.src = '';
    poster.shareInfo = props.shareInfo;
    // #ifdef APP-PLUS
    poster.canvasId = 'canvasId-' + new Date().getTime();
    // #endif
    const canvas = await useCanvas(poster, vm);
    return canvas;
  }
</script>

poster/index.js

javascript 复制代码
import user from './user';
export function getPosterData(options) {
  switch (options.shareInfo.poster.type) {
    case 'user':
      return user(options);
  }
}

export function formatImageUrlProtocol(url) {
  // #ifdef H5
  // H5平台 https协议下需要转换
  if (window.location.protocol === 'https:' && url.indexOf('http:') === 0) {
    url = url.replace('http:', 'https:');
  }
  // #endif

  // #ifdef MP-WEIXIN
  // 小程序平台 需要强制转换为https协议
  if (url.indexOf('http:') === 0) {
    url = url.replace('http:', 'https:');
  }
  // #endif

  return url;
}

需要不同的海报 就创建不同 js 文件 存放你需要画的那些元素

poster/user.js

javascript 复制代码
import { formatImageUrlProtocol } from './index';

const user = (poster) => {
  const width = poster.width;
  //你需要拼接的参数
  const userInfo = {};
  return {
    background: formatImageUrlProtocol('httpxxxxxxxx'),
    list: [
      {
        name: 'nickname',
        type: 'text',
        val: userInfo.nickname,
        x: width / 2,
        y: width * 0.4,
        paintbrushProps: {
          textAlign: 'center',
          fillStyle: '#333',
          font: {
            fontSize: 14,
            fontFamily: 'sans-serif',
          },
        },
      },
      {
        name: 'avatar',
        type: 'image',
        val: formatImageUrlProtocol('httpxxxxxx'),
        x: width * 0.4,
        y: width * 0.16,
        width: width * 0.2,
        height: width * 0.2,
        d: width * 0.2,
      },
      // #ifndef MP-WEIXIN
      {
        name: 'qrcode',
        type: 'qrcode',
        val: poster.shareInfo.link,
        x: width * 0.35,
        y: width * 0.84,
        size: width * 0.3,
      },
      // #endif
      // #ifdef MP-WEIXIN
      {
        name: 'wxacode',
        type: 'image',
        val: 'httpxxxxxxxxxxx',
        x: width * 0.35,
        y: width * 0.84,
        width: width * 0.3,
        height: width * 0.3,
      },
      // #endif
    ],
  };
};

export default user;
相关推荐
2501_915921433 小时前
iOS 是开源的吗?苹果系统的封闭与开放边界全解析(含开发与开心上架(Appuploader)实战)
android·ios·小程序·uni-app·开源·iphone·webview
2501_915909067 小时前
原生 iOS 开发全流程实战,Swift 技术栈、工程结构、自动化上传与上架发布指南
android·ios·小程序·uni-app·自动化·iphone·swift
2501_915106327 小时前
Comodo HTTPS 在工程中的部署与排查实战(证书链、兼容性与真机抓包策略)
网络协议·http·ios·小程序·https·uni-app·iphone
2501_915909067 小时前
苹果软件混淆与 iOS 代码加固趋势,IPA 加密、应用防反编译与无源码保护的工程化演进
android·ios·小程序·https·uni-app·iphone·webview
2501_916007477 小时前
苹果软件混淆与 iOS 应用加固实录,从被逆向到 IPA 文件防反编译与无源码混淆解决方案
android·ios·小程序·https·uni-app·iphone·webview
2501_9160088913 小时前
iOS 26 性能分析深度指南 包含帧率、渲染、资源瓶颈与 KeyMob 协助策略
android·macos·ios·小程序·uni-app·cocoa·iphone
iOS阿玮15 小时前
喜欢做马甲包的有福了~现在多了一招续费方式!
uni-app·app·apple
_AaronWong18 小时前
一键搞定UniApp WiFi连接!这个Vue 3 Hook让你少走弯路
前端·微信小程序·uni-app
2501_915909061 天前
tcpdump 抓包数据分析实战,命令、过滤、常见故障定位与真机补充流程
网络·测试工具·ios·小程序·uni-app·iphone·tcpdump