uniapp小程序分享使用canvas自定义绘制 vue3

news2024/11/13 19:07:16

使用混入结合canvas做小程序的分享
在混入里面定义一个全局共享的分享样式,在遇到特殊页面需要单独处理

utils/share.js

import { ref } from 'vue';
export default {
  onShow() {
    // 创建时设置统一页面的默认值
    uni.$mpShare = {
      title: '分享的标题',
      path: '/pages/home/home',
      imageUrl: 'https:xxx',
      success: function (res) {
        // 转发成功之后的回调
        console.log('转发成功之后的回调', res);
        if (res.errMsg == 'shareAppMessage:ok') {}
      },
      fail: function () {
        // 转发失败之后的回调
        console.log('转发失败之后的回调', res);
        if (res.errMsg == 'shareAppMessage:fail cancel') {
          // 用户取消转发
        } else if (res.errMsg == 'shareAppMessage:fail') {
          // 转发失败,其中 detail message 为详细失败信息
        }
      },
    };
  },
  //发送给朋友
  onShareAppMessage(res) {
    console.log(' uni.$mpShare-----------', uni.$mpShare);
    return uni.$mpShare;
  },
  //分享到朋友圈
  onShareTimeline(res) {
    return uni.$mpShare;
  },
};

main.js混入

import share from '/utils/share.js';
export function createApp() {
  const app = createSSRApp(App);
  app.use(Pinia.createPinia());
  app.mixin(share); // 这里
  app.use(uviewPlus);
  return {
    app,
    Pinia,
  };
}

Canvas绘制海报
commonShare.js

/**
 * canvas
 * context
 * currentObj 绘制需要用到的对象
 * bgImg 背景图
 * dpr 设备分辨率
 * type 类型
 */

export async function createPoster(canvas, context, currentObj, bgImg, dpr, type) {
  const bgImage = await renderImg(canvas, bgImg);

  //绘制矩形
  context.drawImage(bgImage, 0, 0, canvas.width / dpr, canvas.height / dpr);
  context.fillStyle = '#FFF';
  context.strokeStyle = '#303030';
  context.lineWidth = 2;
  context.strokeRect(16, 100, 343, 180);
  context.fillRect(16, 100, 343, 180);
    switch (type) {
    //周边商品
    case 'periphery':
      //绘制商品图片
      const productPath = showPicture(currentObj.goodsPictures[0].picture);
      const productImg = await renderImg(canvas, productPath);
      context.drawImage(productImg, 28, 112, 150, 157);
      //绘制商品名称
      context.font = 'normal normal bold 19px SourceHanSansCN-Bold';
      context.fillStyle = '#0D1932';
      context.fillText(currentObj.goodsName, 189, 136);

      //绘制¥
      context.font = 'normal normal bold 25px SourceHanSansCN-Bold';
      context.fillStyle = '#FE2A12';
      context.fillText(`${currentObj.giftPrice}.${currentObj.giftPricePrefix}`, 189, 256);
    break;
}
  let path = await generatePath(context);
  console.log('分享图片', path);
  return path;
}

//图片显示
function showPicture(srcPath) {
  if (srcPath.includes('http')) {
    return srcPath;
  } else {
    return 'https://xxxxxx' + srcPath; // 注意路径
  }
}

//创建图片对象
function renderImg(canvas, url) {
  // url传临时路径
  return new Promise((resolve) => {
    const img = canvas.createImage();
    img.src = `${url}?timestamp=${new Date().getTime()}`;
    img.onload = () => {
      resolve(img);
    };
  });
}

function base64src(base64data, fun) {
  const base64 = base64data; //base64格式图片
  const time = new Date().getTime();
  const imgPath = uni.env.USER_DATA_PATH + '/poster' + time + 'share' + '.png';
  //如果图片字符串不含要清空的前缀,可以不执行下行代码.
  const imageData = base64.replace(/^data:image\/\w+;base64,/, '');
  const file = uni.getFileSystemManager();
  file.writeFileSync(imgPath, imageData, 'base64');
  fun(imgPath);
}

async function generatePath(context) {
  let base64IMG = context.canvas.toDataURL();
  let pathImg = '';
  await base64src(base64IMG, (res) => {
    pathImg = res;
  });
  return pathImg;
}

Canvas.createImage() 创建Image对象onload事件在安卓真机下只会触发一次,
确保每次加载的 URL 是唯一的:通过在 URL 后面添加一个时间戳或随机数来避免缓存问题。

img = `${url}?timestamp=${new Date().getTime()}`;

单独页面的处理xxxx.vue

<view id="canvas" v-show="false">
   <canvas id="myCanvas" type="2d" canvas-id="myCanvas" style="width: 375px; height: 300px"></canvas>
</view>

<script setup>
//引入分享绘制canvas
import { createPoster } from '/utils/commonShare.js';
onShow(() => {
   generatorCanvasUrl();
});

function generatorCanvasUrl() {
   uni
     .createSelectorQuery()
     .select('#myCanvas')
     .node((res) => {
       let canvas = res.node;
       let context = res.node.getContext('2d');
       uni.getSystemInfo({
         success: async function (sysRes) {
           const dpr = sysRes.devicePixelRatio;
           canvas.width = 375 * dpr;
           canvas.height = 300 * dpr;
           context.clearRect(0, 0, canvas.width, canvas.height);
           context.scale(dpr, dpr);
           let path = await createPoster(canvas, context, currentObj.value, canvasBgImg.value, dpr, canvasType.value);
           uni.$mpShare = {
             title: canvasTitle.value,
             path: '/pagesDiscover/group/group-product-dedails?from=sharePage&data=' + encodeURIComponent(JSON.stringify(currentObj.value)),
             imageUrl: path,
           };
           console.log('重绘成功');
         },
       });
     })
     .exec();
 }
</script>

注意几个问题

  1. canvas的绘制时间,需要在拿到数据之后,dom生成之前绘制完成,onShow不可以就试试onReady,否则就会绘制失败(图片找不到,数据undefined)
  2. 图片路径后面一定要加时间戳保证图片路径是唯一的,否则就会一直走缓存
  3. 如果页面想要重置分享但是不用canvas绘制,直接用下面这个
const shareData = computed(() => {
  // 分享的数据
  return {
    title: '重置',
    desc: '重置',
    path: '/xxxx/xxxx/xxxx',
    imageUrl: 'xxxxx',
  };
});
onShow(() => {
  uni.$mpShare = shareData.value; // 修改uni.$mpShare的值
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2239592.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VMware Workstation Pro 最新版下载路径图示

从 2024 年 5 月开始&#xff0c;VMware Workstation Pro 宣布免费供个人使用。这意味着我们可以在无需许可证密钥或任何持续费用的前提下&#xff0c;在 Windows 或 Linux 上下载并使用这款强大的虚拟机软件的全部功能。 1、进入官网 你会发现找不到VMware workstation Pro 的…

【软件测试】设计测试用例的万能公式

文章目录 概念设计测试用例的万能公式常规思考逆向思维发散性思维万能公式水杯测试弱网测试如何进行弱网测试 安装卸载测试 概念 什么是测试用例&#xff1f; 测试⽤例&#xff08;Test Case&#xff09;是为了实施测试⽽向被测试的系统提供的⼀组集合&#xff0c;这组集合包…

linux命令详解,ssh服务+远程拷贝

ssh服务 ssh&#xff08;Secure Shell&#xff09;命令用于安全地远程登录到另一台计算机&#xff0c;并执行命令和传输文件。ssh 提供了加密的通信通道&#xff0c;确保数据传输的安全性。 ssh [选项] [用户]主机 [命令]常用选项 -V&#xff1a;显示 ssh 版本信息。-v&…

“高级Java编程复习指南:深入理解并发编程、JVM优化与分布式系统架构“

我的个人主页 接下来我将方享四道由易到难的编程题&#xff0c;进入我们的JavaSE复习之旅。 1&#xff1a;大小写转换------题目链接 解题思路&#xff1a; 在ASCII码表中&#xff0c;⼤写字⺟A-Z的Ascii码值为65- 90&#xff0c;⼩写字⺟a-z的Ascii码值为97-122。每个字 ⺟…

SQL面试题——飞猪SQL面试 重点用户

飞猪SQL面试题—重点用户 在一些场景中我们经常听到这样的一些描述&#xff0c;例如20%的用户贡献了80%的销售额&#xff0c;或者是20%的人拥有着80%的财富&#xff0c;你知道这样的数据是怎么算出来的吗 数据如下,uid 是用户的id ,amount是用户的消费金额 |uid|amount| ---…

操作系统OS--进程

目录 操作系统是什么 进程 进程的状态 1.并行和并发 2.时间片 进程优先级 进程切换 task_struct内容分类&#xff1a; 操作系统是什么 操作系统本质上是一款纯正的“搞管理”的软件 你的程序不能直接写入硬件&#xff0c;都必须通过操作系统 对软硬件之间进行交互&…

Spring——容器:IoC

容器&#xff1a;IoC IoC 是 Inversion of Control 的简写&#xff0c;译为“控制反转”&#xff0c;它不是一门技术&#xff0c;而是一种设计思想&#xff0c;是一个重要的面向对象编程法则&#xff0c;能够指导我们如何设计出松耦合、更优良的程序。 Spring 通过 IoC 容器来…

全自动火腿肉馅斩拌机:

全自动火腿肉馅斩拌机通过斩切作用提高产品的细密度和弹性&#xff0c;广泛应用于肉制品的深加工制作&#xff0c;如制作肉丸、香肠等。其工作原理是利用斩刀高速旋转的斩切作用&#xff0c;将原料进行斩切和乳化处理&#xff0c;从而提高产品的细腻度和弹性。斩拌机具有以下特…

音视频入门基础:MPEG2-TS专题(3)——TS Header简介

注&#xff1a;本文有部分内容引用了维基百科&#xff1a;https://zh.wikipedia.org/wiki/MPEG2-TS 一、引言 本文对MPEG2-TS格式的TS Header进行简介。 进行简介之前&#xff0c;请各位先下载MPEG2-TS的官方文档。ITU-T和ISO/IEC都分别提供MPEG2-TS的官方文档。但是ITU提供的…

NCC前端调用查询弹框

系统自带的查询模板 弹框 调启使用默认的 查询模板 是在 单据模板的 列表模板中&#xff0c;有个查询区域 &#xff0c;查询区域就是查询模板内容如果在列表页做客开 新增按钮 调启查询模板 无问题&#xff0c;但是目前需求是需要再卡片页面下调启系统标准的调启模板代码 //调…

第8章 利用CSS制作导航菜单

8.1 水平顶部导航栏 水平菜单导航栏是网站设计中应用范围最广的导航设计&#xff0c;一般放置在页面的顶部。水平导航适用性强&#xff0c;几乎所有类型的网站都可以使用&#xff0c;设计难度较低。 8.1.1 简单水平导航栏的设计与实现 8.1.1.1导航栏的创建 <nav>标签…

labview拆解日期字符串

今天在写测试时&#xff0c;发现有些时候需要把日期和时间拆分开来&#xff0c;由于项目采集到的日期是一个数字字符串&#xff0c;需要把他们转换成带日期格式的字符串分别显示&#xff0c;这里还是用到了数组到电子表格字符串转换的函数。 下面示例如下&#xff0c;首先我们…

Kafka - 启用安全通信和认证机制_SSL + SASL

文章目录 官方资料概述制作kakfa证书1.1 openssl 生成CA1.2 生成server端秘钥对以及证书仓库1.3 CA 签名证书1.4 服务端秘钥库导入签名证书以及CA根证书1.5 生成服务端信任库并导入CA根数据1.6 生成客户端信任库并导入CA根证书 2 配置zookeeper SASL认证2.1 编写zk_server_jass…

Ubuntu22.04安装DataEase

看到DataEase的驾驶舱&#xff0c;感觉比PowerBI要好用一点&#xff0c;于是搭建起来玩玩。Dataease推荐的操作系统是Ubuntu22.04/Centos 7。 下载了Ubuntu22.04和DataEase 最新版本的离线安装包 一.安装ubuntu22.04 在安装的时候&#xff0c;没有顺手设置IP地址信息&#xff…

使用iviewui组件库的坑

背景 使用view-design组件库的Input组件的时候&#xff0c;按照产品的要求&#xff0c;输入框中只能键入正整数。 使用效果 如果直接使用组件的type属性&#xff0c;设置类型为number时&#xff0c;乍一看没啥问题&#xff0c;但是当我们键入 小数点(.) 或者 e/E 后面没有跟任…

AI绘图最强软件stable diffusion,一文带你迅速了解!

有需要stable diffusion整合包可以扫描下方&#xff0c;免费获取 01 — 什么是 SD ​ Stable Difusion(简称 SD) 其三种概念。 1.用来指代稳定扩散(Stable Diffusion) 技术,如 Midjourney是基于Stable Difusion技术实现的就是指它运用了 Stable Diffusion 的技术原理。 …

Unity3D实现视频和模型融合效果

系列文章目录 unity工具 文章目录 系列文章目录👉前言👉一、效果展示如下👉二、VideoPlayer播放视频(一)👉2-1、Hieraechy面板右键创建videoPlayer👉2-2、Assets面板右键创建RenderTexture👉2-3、把设置好的RenderTexture拖到videoPlayer里面还有本地视频视频�…

stm32 ADC实例解析(3)-多通道采集互相干扰的问题

文章目录 一、问题现象&#xff1a;二、原因分析&#xff1a;1、测量值不准问题分析&#xff1a;2、采样干扰问题分析 三、解决办法&#xff1a;1、硬件&#xff1a;&#xff08;1&#xff09;、电源供电&#xff08;2&#xff09;、引脚电容&#xff08;3&#xff09;、减少采…

springboot 医院住院管理系统,计算机毕业设计项目源码035,计算机毕设程序(LW+开题报告、中期报告、任务书等全套方案)

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;医院当然也不例外。医院住院管理系统是以实际运用为开发背景&#xff0c;运用软件工程原理和开发方法&#xff0c;采用J…

Redis集群模式之Redis Sentinel vs. Redis Cluster

在分布式系统环境中&#xff0c;Redis以其高性能、低延迟和丰富的数据结构而广受青睐。随着数据量的增长和访问需求的增加&#xff0c;单一Redis实例往往难以满足高可用性和扩展性的要求。为此&#xff0c;Redis提供了两种主要的集群模式&#xff1a;Redis Sentinel和Redis Clu…