HTML5项目中怎么实现及优化分享截图的功能
Admin 2022-06-28 群英技术资讯 790 次浏览
这篇文章主要介绍了HTML5项目中怎么实现及优化分享截图的功能相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇HTML5项目中怎么实现及优化分享截图的功能文章都会有所收获,下面我们一起来看看吧。这篇文章主要是介绍如何使用canvas实现分享截图,
刚开始以为通过canvas绘画分享图片并不难,但实际上在开发的时候还是遇到非常多的坑
例如:
①图片背景为透明
②分享图只有文字没有图片
③图片跨域问题
下面看例子:
分享图片、分享内容描述、标题、二维码都是通过请求接口动态生成

框架我使用的是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>
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)
}
太阳码赋值给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},()=>{
})
}
//最后必须将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%
②分享图加载速度:小程序二维码太阳码,背景图等页面加载阶段可以先请求,点击分享按钮可以直接绘画,减少请求时间长导致生成绘画慢问题,同时也可以避免二维码、背景图未加载完成,绘画就已经开始,导致画出来的分享图没有背景图、二维码的问题。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
background-color设置元素的背景色。background-image属性用于为一个元素设置一个或者多个背景图像。background-repeat定义背景图像的重复方式。
本篇文章主要介绍了css3实现画半圆弧线的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
弹性布局,顾名思义就是具有弹性特点,能够自由的伸缩,也就是自适应网页。所以使用css弹性布局flex可以便捷,完整,响应式地实现多种页面布局。这篇文章就主要给大家介绍一下css弹性布局flex的使用。
用于定义和初始化一个或者多个css计数器。设置计数器的名称和初始值。计数器的初始值不是计数器显示时的第一个数字,如果希望计数器从1开始显示,则需要设置coutter-reset中的初始值设置为0。
这篇文章主要介绍了原生 JS+CSS+HTML 实现时序图的方法,本文通过实例代码图文介绍的非常详细,需要的朋友可以参考下
成为群英会员,开启智能安全云计算之旅
立即注册关注或联系群英网络
7x24小时售前:400-678-4567
7x24小时售后:0668-2555666
24小时QQ客服
群英微信公众号
CNNIC域名投诉举报处理平台
服务电话:010-58813000
服务邮箱:service@cnnic.cn
投诉与建议:0668-2555555
Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008