Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

小程序-生成海报,保存本地 #5

Open
hdm-hdm opened this issue Apr 7, 2023 · 0 comments
Open

小程序-生成海报,保存本地 #5

hdm-hdm opened this issue Apr 7, 2023 · 0 comments

Comments

@hdm-hdm
Copy link

hdm-hdm commented Apr 7, 2023

实现思路

  • 利用 canvas 将海报画出来

  • 将画出来的海报转换成图片

  • 将图片保存至本地相册

实现步骤

  1. 引入Canvas ,设置type='2d' 提升性能
import { Canvas } from '@tarojs/components'
 <Canvas
        id='posterCanvas'
        type='2d'
        style={`width:100vw;height:150vw;position: fixed;top: -999px;`}
      />
  1. 配置绘制基础信息
  const posterBaseConfig = {
        //  此处dx,dy,dw,dh,height 设置的是相对于屏幕宽度的比例
        maxHeight: 1.50,
        //  图片信息
        pintArr: [
          { url: posterBg, dx: 0, dy: 0, dw: 'full', dh: 1.5 }, // 背景
          {
            url: posterUrl,  // 海报大图
            dx: 0.0746,
            dy: 0.072,
            dw: 0.853,
            dh: 0.853 * 4 / 3,
          },
          { url: qrCode, dx: 0.712, dy: 1.2746, dw: 0.1413, dh: 0.1413 }, // 二维码
        ],
        //  文本信息
        textArr: [
          { text: title || '', dx: 0.0933, dy: 1.3333, font: 15px ', fillStyle: '#333333' },
          { text: '长按识别二维码了解详情', dx: 0.0933, dy: 1.4, font: '12px', fillStyle: '#999999' },
        ],
      };
  1. 获取Canvas节点
const getCanvasPoster = () => {
   const query = Taro.createSelectorQuery();
   query.select('#posterCanvas')
   // 获取节点的相关信息。需要获取的字段在fields中指定。返回值是 nodesRef 对应的 selectorQuery
   .fields({ node: true, size: true })
   // 执行所有的请求。请求结果按请求次序构成数组,在callback的第一个参数中返回
   .exec(
     drawPoster,
   );
 };
  1. 绘制
const drawPoster = (res:NodesRef) => {
// 获取屏幕宽度
  const clientWidth = Taro.getSystemInfoSync().windowWidth;
  try {
    // Canvas 实例
    const canvas = res[0].node;
    const ctx = canvas.getContext('2d') as Taro.CanvasContext;
    if (!ctx) return;
    // 初始化画布
    const maxWidth = clientWidth;
    const maxHeight = clientWidth * baseConfig.maxHeight;
    canvas.width = maxWidth;
    canvas.height = maxHeight;
    if (baseConfig.pintArr.length) {
      const pintArr = baseConfig.pintArr;  // 绘制图片
      const promiseAlls: Promise<any>[] = [];
      pintArr.forEach((item) => {
        let promise = new Promise<void>(async (resolve, reject) => {
          let imgDome = canvas.createImage();
          imgDome.src = item.url;
          imgDome.onload = () => {
            resolve(imgDome);
          };
          imgDome.onerror = () => {
            reject();
          };
        });
        promiseAlls.push(promise);
      });
      Promise.all(promiseAlls).then((res) => {
        res.forEach((ele: any, index: number) => {
          const i = pintArr[index];
        // 比例 * 屏幕宽度
          ctx.drawImage(
            ele,
            i.dx * clientWidth,
            i.dy * clientWidth,
            i.dw === 'full' ? clientWidth : i.dw * clientWidth,
            i.dh * clientWidth,
          );
        });
        const texts =baseConfig.textArr; // 绘制文字
        texts.forEach((element: any) => {
          ctx.font = element.font;
          ctx.fillStyle = element.fillStyle;
          ctx.fillText(element?.text, element.dx * clientWidth, element.dy * clientWidth);
        });
      });
    }
  } catch (error) {
    console.log(error);
  }
};
  1. 保存海报
const downLoadToAlnum = () => {
  const query = Taro.createSelectorQuery();
  query.select('#posterCanvas').fields({ node: true, size: true }).exec(
    (res) => {
      if (!res?.length) return;
      Taro.canvasToTempFilePath({
        canvas: res[0]?.node,
        x: 0,
        y: 0,
      }).then((res) => {
        Taro.saveImageToPhotosAlbum({
          filePath: res.tempFilePath,
          success: () => {
           console.log('success')
          },
        });
      }).catch(() => {
        console.log('fail')
      });
    },
  );
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant