京东6.18大促主会场领京享红包更优惠

 找回密码
 立即注册

QQ登录

只需一步,快速开始

前端Html5怎样实现分享截图的示例代码

2024-11-2 22:26| 发布者: 2ae29| 查看: 94| 评论: 0

摘要: 前言 这篇文章主要是先容怎样使用canvas实现分享截图, 刚开始以为通过canvas绘画分享图片并不难,但实际上在开发的时候还是遇到非常多的坑 例如: ①图片配景为透明 ②分享图只有笔墨没有图片 ③图片跨域问题 下面

前言

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

实现:一、body部分

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

一、构建canvas

下面展示一些 内联代码片。

[code] //ref是react获取canvas元素的方法。也可以使用id,再通过getElementById() 方法获取canvas //宽高需要转化为而二-四倍图来进步清晰度、否则会导致分享截图含糊,清晰度不足 <canvas ref='canvas' width={1200} height={1600} className={styles.canvasImg}/>[/code] [code] //点击分享按钮触发this.shareComponent(this.getUrlImg)方法 //非react框架,忽视别的代码。直接触发分享函数 <div className={styles.luckDraw_viewPrizeBtn} onClick={()=>{ this.setState({ shareModal:true },()=>{ this.shareComponent(this.getUrlImg) })} }>分享运动</div>[/code]

实现:二、JS部分:

shareComponent函数

[code] //函数接受一个回调函数,用于绘画完成后,再将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) } 太阳码赋值给img1 img1.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},()=>{ }) }[/code]

实现:三、canvas更换imgs

[code] //最后必须将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> [/code]

总结与优化

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

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

到此这篇关于前端Html5怎样实现分享截图的示例代码的文章就先容到这了,更多相关Html5分享截图内容请搜刮脚本之家以前的文章或继承浏览下面的相关文章,渴望大家以后多多支持脚本之家!


来源:https://www.jb51.net/html5/768100.html
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
关闭

站长推荐上一条 /6 下一条

QQ|手机版|小黑屋|梦想之都-俊月星空 ( 粤ICP备18056059号 )|网站地图

GMT+8, 2025-7-2 08:32 , Processed in 0.033612 second(s), 18 queries .

Powered by Mxzdjyxk! X3.5

© 2001-2025 Discuz! Team.

返回顶部