前端H5如何实现分享截图

  • 目录
    • 前言
    • 实现:一、body部分
    • 实现:二、JS部分:
    • 实现:三、canvas更换imgs
    • 总结与优化

目录

前言

这篇文章主要是介绍如何使用canvas实现分享截图,
刚开始以为通过canvas绘画分享图片并不难,但实际上在开发的时候还是遇到非常多的坑
例如:
①图片背景为透明
②分享图只有文字没有图片
③图片跨域问题
下面看例子:
分享图片、分享内容描述、标题、二维码都是通过请求接口动态生成

实现:一、body部分

框架我使用的是react。绘画分享采用原生canvas、js实现。所以不用担心vue、小程序、原生H5也是能够适应。

一、构建canvas
下面展示一些 内联代码片

//ref是react获取canvas元素的方法。也可以使用id,再通过getElementById() 方法获取canvas
//宽高需要转化为而二-四倍图来提高清晰度、否则会导致分享截图模糊,清晰度不足<canvas ref='canvas' width={1200} height={1600} className={styles.canvasImg}/>

//点击分享按钮触发this.shareComponent(this.getUrlImg)方法
//非react框架,忽视其余代码。直接触发分享函数<div className={styles.luckDraw_viewPrizeBtn} onClick={()=>{this.setState({shareModal:true},()=>{this.shareComponent(this.getUrlImg)})}}>分享活动</div>

实现:二、JS部分:

shareComponent函数

//函数接受一个回调函数,用于绘画完成后,再将canvas转化为png图片格式。
//canvas移动端无法长按保存,必须传为img才能保存。
shareComponent = (callback)=>{let suncode = this.state.suncode //微信小程序太阳码let activityName = this.state.activityName //活动标题let backgroundImg = this.state.backgroundImg //背景图let postShareDesc= this.state.postShareDesc //分享描述字段let img = new Image()img.crossOrigin="anonymous"; //关键,处理图片跨域问题!!let _t = this//限制活动标题,最多10个字,超过...省略if(activityName.length>10){activityName=activityName.slice(0,10)+'...'}//由于canvas文字不能自动换行,所以我们这里需要做一个文字换行处理,以及字数的限制,防止超出canvas范围let arrDescribe = [] let maxLeng = postShareDesc.length/20 //分享描述每行20字,最多8行if(maxLeng=>8){maxLeng = 8 //最多8行}//postShareDesc为分享描述字段for(let i = 0;i<maxLeng;i++){//将分享描述字段分为若干个20字的行存入arrDescribe数组,且最多8行let str = postShareDesc.slice(i*20,i*20+20) arrDescribe.push(str)}//图片加载完后,将其显示在canvas中,图片必须使用onload方式,否则会导致图片未加载完成就完成绘画//img为整张分享图img.onload = function (){let canvas = _t.refs.canvas //获取canvas元素let ctx = canvas.getContext('2d')//设置背景色,否则背景色会透明ctx.fillStyle='#fff';ctx.fillRect(0,0,1196,1596);ctx.drawImage(img, 0, 0,1200,600);//分享字段描述ctx.font="52px Arial";ctx.fillStyle='#000';//手动换行,80为X坐标,700+index*100为动态计算Y坐标arrDescribe.forEach((item,index)=>{ctx.fillText(item,80,700+index*100);})//分享标题ctx.font="64px Arial";ctx.fillStyle='#000';ctx.fillText(activityName,520,1320);//分享提示ctx.font="48px Arial";ctx.fillStyle='#999';ctx.fillText('长按小程序码查看详情',520,1420);//分享提示ctx.font="48px Arial";ctx.fillStyle='#999';ctx.fillText('分享自[XXXX]',520,1500);//分割线ctx.moveTo(1120,1160);ctx.lineTo(80,1180);ctx.strokeStyle="#E8E8E8"ctx.stroke();//img1为小程序太阳码let img1 = new Image()img1.crossOrigin="anonymous"; //关键,处理太阳码转化为base64格式图片时的跨域问题img1.onload = function(){ctx.drawImage(img1,  80, 1200,340,340)callback(canvas)}太阳码赋值给img1img1.src = suncode//边框ctx.strokeStyle="#f5f5f5";ctx.rect(0,0,1200,1600);ctx.stroke();      }//timeStamp 事件属性可返回一个时间戳。指示发生事件的日期和时间(从 epoch 开始的毫秒数)。//URL时间戳的用法:作用:为了防止浏览器缓存。//URL后面添加随机数或时间戳通常用于防止浏览器(客户端)缓存页面。 浏览器缓存是基于URL进行缓存的,//如果页面允许缓存,则在缓存时效前再次访问相同的URL,浏览器就不会再次发送请求到服务器端,而是直接从缓存中获取指定资源。//而当URL 的末尾追加了随机数或时间戳,就会保证每次都会实际生成新请求且 Web 服务器不会尝试缓存来自服务器的响应。const a = `${backgroundImg}?timeStamp=` + (new Date());img.src = a}
//绘画完成后,必须转化为img,否则移动端将会无法长按保存
//必须等绘画完成后,才能够回调。如果直接使用canvas.toDataURL('image/png')转化,会导致出现分享图只有写死的文字,没有请求的图片和文字。会存在异步问题getUrlImg=(canvas)=>{   let dataImg = new Image()    try {dataImg.src = canvas.toDataURL('image/png')} catch (e) {console.log(e);}let urlImg = dataImg.src //urlImg为img路径this.setState({urlImg},()=>{ })}

实现:三、canvas更换imgs


//最后必须将canvas隐藏,再替换为imgs,这样移动端才能长按保存
//css中.canvasImg添加display:none隐藏画布
//再使用canvas转化的img,并且将img的宽高设置为25%
//因为为了提高清晰度,我是采用四倍图再压缩的方式来提高清晰度,所以img需要缩回25%<canvas ref='canvas' width={1200} height={1600} className={styles.canvasImg}/>//display:none//crossOrigin="Anonymous" 处理图片跨域问题<img src={this.state.urlImg} crossOrigin="Anonymous"/>//width:25%。height:25%div className={styles.shareTips}>长按保存,可分享至朋友圈</div>

总结与优化

难点在于:
①将canvas转化为base64格式图片,会导致图片跨域问题
②异步问题(图片还未加载,绘画就已经完成)
③背景透明的问题等等

优化:
①清晰度:可以将canvas画成2-4倍图,转化为图片再压缩回50%-25%
②分享图加载速度:小程序二维码太阳码,背景图等页面加载阶段可以先请求,点击分享按钮可以直接绘画,减少请求时间长导致生成绘画慢问题,同时也可以避免二维码、背景图未加载完成,绘画就已经开始,导致画出来的分享图没有背景图、二维码的问题。

有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。

前端H5如何实现分享截图相关推荐

  1. 前端H5各种qq,微博,fb,whatsapp等网页分享的链接

    ####前端H5各种qq,微博,fb,whatsapp等网页分享的链接(我用到过的,一点点汇总) 代码链接如下: <a href = "https://sns.qzone.qq.com ...

  2. h5页面生成图片分享到微信js_微信端h5页面如何调用分享页面的接口

    这次给大家带来微信端h5页面如何调用分享页面的接口,微信端h5页面调用分享页面接口的注意事项有哪些,下面就是实战案例,一起来看一下. 最近公司做了一个给学生投票的H5页面,主要是在微信端使用,需要添加 ...

  3. h5 默认为移动端页面_20条移动前端H5页面开发规范,h5开发必看文档

    这是根据腾讯最新公布的<移动页面用户行为报告>来给大家分享的关于移动端H5页面开发一些20条规范和准则.里面大概包含了16种用户操作习惯和注意点. 下面25学堂跟大家先分享一张关于2016 ...

  4. 前端H5—jQuery精通-张晓飞-专题视频课程

    前端H5-jQuery精通-1388人已学习 课程介绍         jQuery是优秀, 使用广的JS函数库, 它能帮我们程序员简化DOM查询及DOM操作, 轻松实现动画效果.在世界前10000个 ...

  5. thinkphp后台管理系统+vue前端H5 app

    thinkphp后台管理系统+vue前端H5 app 众包接单型App 全部源码已发布,欢迎star, 移步码云 前言 1.帮朋友做的一个接单类型的后台管理系统(朋友的需求是淘宝好评刷管理) 2.目前 ...

  6. H5实现微信分享自定义地图

    这几天紧急开发一个拼团+砍价的H5微信小商城.技术用的是:前端Vue+Vant快速开发组件框架.后端java. 使用微信js-sdk流程图: 微信公众平台测试帐号申请地址:https://mp.wei ...

  7. 黑马前端h5团队开发代码规范

    黑马前端h5团队开发代码规范 1. 概述 欢迎使用品优购代码规范, 这个是我借鉴京东前端代码规范,组织的品优购内部规范.旨在增强团队开发协作.提高代码质量和打造开发基石的编码规范, 以下规范是团队基本 ...

  8. 前端自学经验总结分享,顺便谈谈前端该如何自学

    前端自学经验总结分享,顺便谈谈前端该如何自学 写在前面 作者非科班出身,本科学的是自动化专业,平时也能接触一些计算机编程方面的知识,因而对编程比较感兴趣.工作后正好赶上团队调整,采用主流的前后端分离的 ...

  9. 前端H5实现微信授权

    背景: 前段时间做了一个H5项目,H5项目需要放在微信公众号里面,并且需要通过微信授权拿到openId,所以就需要实现h5授权微信这个功能了. 原理: 其实原理就是前端在本项目首页去请求微信端提供的一 ...

  10. H5手机QQ分享到手Q、QQ空间、微信好友、朋友圈础通用接口

    H5手Q分享通用接口代码片段 <meta itemprop="name" content="网页标题"> <meta itemprop=&qu ...

最新文章

  1. 三端可调稳压集成电路LM317的多种应用电路
  2. 记录一下两个相机相同处理如何简便进行
  3. 用apksigner进行批量签名的脚本
  4. Linux中打包和解压到的方法
  5. 【华为云技术分享】AI 开发路漫漫,什么才是真正的极客精神?
  6. Sublime Text 3安装与使用
  7. 远程桌面中转,基于 UltraVNC Repeater(中继器)的远程桌面服务搭建,用于复杂网络环境
  8. 孙玄:年薪75万的真实技术面试实践攻略(篇章一)
  9. 使用ImageJ软件计算信噪比(SNR)的小工具
  10. 一文彻底搞懂方差、协方差、协方差矩阵
  11. 华为C语言的编程规范
  12. Android 设备管理器 理解和使用
  13. Android字符设备驱动开发基于高通msm8916【原创 】
  14. 关于UI设计学习,推荐6个高质量的学习网站!
  15. java基础(个人笔记)
  16. python微信api_用Python实现微信公众号API素材库图文消息抓取
  17. instancetype 与 id for Objective-C
  18. 量子信息matlab,matlab在量子力学中的应用.PDF
  19. 卡塔兰(Catalan)数
  20. 优酷端侧弹幕穿人技术实战之:PixelAI移动端实时人像分割

热门文章

  1. AI人工智能在自动写歌词软件的最新应用,AI机器人小芝
  2. 三次hermite插值多项式例题_数值分析实验六(分段三次Hermite插值)
  3. 数字冰雹智慧城市大数据可视化分析决策系统
  4. 浏览器Cookie详解
  5. 菜鸟学习之Java入门基础知识
  6. 【电子元件】稳压(齐纳)管 Zener Diode
  7. 华为 C/C++ 编程规范(精华总结)
  8. opencv学习笔记三十二:Haar特征与积分图像
  9. 数据仓库分层设计,零基础一看就会
  10. 0到50带圆圈的数字序号有需要的吗:)