[h5]自定义海报生成

功能需求:获取海报参数自定义生成一张带二维码海报。

效果如下:
image

元素:主要分成背景图,用户信息和带用户信息的二维码(由前端生成);

步骤:先根据设计完成布局设计->将这张海报的html元素生成为canvas->将该canvas转化成图片;

  • 步骤1:请求数据,成功后主要是二维码的生成(使用qrcodejs2)
// 生成二维码
    qrcodeCreate() {
      const _this = this;
      if (_this.poster_params.code_url) {
        let qrcodeDom = document.getElementById("qrcode");
        qrcode = new QRCode("qrcode", {
          width: parseInt(qrcodeDom.clientWidth), // 设置宽度,单位像素
          height: parseInt(qrcodeDom.clientHeight), // 设置高度,单位像素
          text: _this.poster_params.code_url // 设置二维码内容或跳转地址
        });
      } else {
        _this.isLoading = false;
        _this.isFailed = true;
        return _this.$toast.center("海报跑走了~");
      }
    }
  • 步骤2:设计海报canvas

注意是内部图片必须有效加载才能生成成功,所以需要先判断图片链接的有效性,之后等图片完全加载完成之后再转为canvas;还有在图片为不同域的情况也可能会产生生成失败的现象,所以需要先将跨域图片转换为base64格式。

// 创建海报canvas
let box = document.getElementById("poster-box"); // 海报盒子
      let c_width = box.offsetWidth;
      let c_height = box.offsetHeight;
      let canvas = document.createElement("canvas");
      let context = canvas.getContext("2d");
      // 获取根据屏幕分辨率,来设置canvas的宽高以获得高清图片
      let devicePixelRatio = window.devicePixelRatio || 2;
      let backingStoreRatio =
        context.webkitBackingStorePixelRatio ||
        context.mozBackingStorePixelRatio ||
        context.msBackingStorePixelRatio ||
        context.oBackingStorePixelRatio ||
        context.backingStorePixelRatio ||
        1;
      let ratio = devicePixelRatio / backingStoreRatio;
      canvas.width = c_width * ratio;
      canvas.height = c_height * ratio;
      canvas.style.width = c_width + "px";
      canvas.style.height = c_height + "px";
      canvas.style.position = "absolute";
      canvas.style.left = "50%";
      canvas.style.top = "50%";
      canvas.style.transform = "translate(-50%, -50%)";
      canvas.style.zIndex = "10";
      canvas.style.opacity = "0";
      // canvas的页面位置自行调整
      let scrollTop =
        document.documentElement.scrollTop ||
        window.pageYOffset ||
        document.body.scrollTop;
      let scrollLeft =
        document.documentElement.scrollLeft ||
        window.pageXOffset ||
        document.body.scrollLeft;
      let transTop =
        screenTop -
        (document.getElementsByClassName("poster-view-content")[0].offsetTop -
          c_height / 2);
      let transLeft = (c_width - window.innerWidth) / 2;
      context.scale(ratio, ratio);
      // canvas的位置要保证与div位置相同。
      context.translate(transLeft, transTop);
// 背景图片
      let img = new Image();
      let canvas2 = document.createElement("canvas");
      let ctx = canvas2.getContext("2d");
      img.crossOrigin = "Anonymous";
      img.src = _this.poster_params.share;
      img.onload = function() {
        if (img.width > 0) {
          canvas2.height = img.height;
          canvas2.width = img.width;
          ctx.drawImage(img, 0, 0);
          let dataURL = canvas2.toDataURL("image/png");
          document.getElementById("poster-bg").setAttribute("src", dataURL);
          canvas2 = null;
          _this.getCard(box, canvas, c_width, c_height); // 生成海报canvas
        } else {
          _this.isLoading = false;
          _this.isFailed = true;
          return _this.$toast.center("海报跑走了~");
        }
      };
      img.onerror = function() {
        _this.isLoading = false;
        _this.isFailed = true;
        return _this.$toast.center("海报跑走了~");
      };
  • 步骤3:在所有图片都加载以及转换成功后,可以生成海报canvas并转换生成图片(使用html2canvas)
        // 每次图片加载成功后都会请求执行该函数(但是要在所有图片都加载成功后才能真正生成canvas)
    getCard(box, canvas, c_width, c_height) {
      const _this = this;
      _this.cnt++; // 对已加载成功的图片数进行判断
      if (_this.cnt < 3) return; // 所有图片都成功可以生成
      html2canvas(box, {
        allowTaint: true,
        useCORS: true,
        canvas: canvas,
        width: c_width,
        height: c_height
      }).then(function(canvas) {
        canvas.setAttribute("id", "my-canvas"); //添加属性
        box.appendChild(canvas);
        // 转换图片得到base64格式
        let dataURL = canvas.toDataURL("image/png");
        let img = new Image();
        img.src = dataURL;
        img.className = "cardImg";
        img.style.position = "absolute";
        img.style.left = "50%";
        img.style.top = "50%";
        img.style.transform = "translate(-50%, -50%)";
        img.style.zIndex = "150";
        img.style.width = c_width + "px";
        img.style.height = c_height + "px";
        box.appendChild(img);
        // 生成成功
        _this.$emit('createPosterSuccess', dataURL);
        _this.isLoading = false;
        _this.isSuccess = true;
      });
    }

大致就完成了,主要在于异步的问题,在图片base64格式转换的时候也要判断二维码是否生成成功。
还有生成到成为一张图片还是需要一定时间,所以最好有一个生成中的加载状态。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,123评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,031评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,723评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,357评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,412评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,760评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,904评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,672评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,118评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,456评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,599评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,264评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,857评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,731评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,956评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,286评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,465评论 2 348

推荐阅读更多精彩内容

  • 在项目中,需要生成海报。有动态信息(微信头像、微信昵称、上传图片(oss链接)、二维码)+ 海报背景图生成一张海报...
    奔跑吧笨笨阅读 7,673评论 0 0
  • 本文适用人群 需要在微信wap页开发分享海报功能的前端程序员们 想要了解html2canvas库的吃瓜群众 挣扎在...
    朝颜vivian阅读 10,151评论 4 17
  • 第一章 HTML5 (2014年10月29日发布)新特性: 10个 (1)新的语义标签 (2)增强型表单 (3)视...
    fastwe阅读 948评论 0 1
  • $HTML, HTTP,web综合问题 1、前端需要注意哪些SEO 2、 的title和alt有什么区别 3、HT...
    Hebborn_hb阅读 4,584评论 0 20
  • 时值寒冬,我坐在异国的列车上,前往北方,想要去一座知名的小镇收集些有助于写作的素材。因早已听闻过该地的寒冷,所以...
    林文l阅读 870评论 4 16