当前位置: 代码网 > it编程>网页制作>html5 > 前端Html5如何实现分享截图的示例代码

前端Html5如何实现分享截图的示例代码

2021年03月18日 html5 我要评论
前端Html5如何实现分享截图的示例代码这篇文章主要介绍了前端Html5如何实现分享截图的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 21-03-18

前言

这篇文章主要是介绍如何使用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)

      }
   太阳码赋值给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

//最后必须将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%
②分享图加载速度:小程序二维码太阳码,背景图等页面加载阶段可以先请求,点击分享按钮可以直接绘画,减少请求时间长导致生成绘画慢问题,同时也可以避免二维码、背景图未加载完成,绘画就已经开始,导致画出来的分享图没有背景图、二维码的问题。

到此这篇关于前端html5如何实现分享截图的示例代码的文章就介绍到这了,更多相关html5分享截图内容请搜索代码网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持代码网!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com