原 html2canvas解决字体渐变

  • 前言

这两天有个需求,需要保存页面的dom元素为图片到本地,之前没有做过类似的效果,通过github搜索了一下,找到两个github库,

一个为domtoimage:https://github.com/tsayen/dom-to-image; star:3539;

另一个为htmltocanvas:https://github.com/niklasvh/html2canvas/, star12073;

两个都试用后,最后选择了第二个.

使用方法

使用方法很简单:在正常的html中引入html2canvas.js后只需要写如下几行代码;

html2canvas(document.getElementById("container"))
  .then(function (canvas) {
    document.body.appendChild(canvas)
  })

遇到的问题

在使用文本渐变功能的时候,在进行生成图片的时候渐变的文本不能正常的显示渐变内容

明明canvas是支持文本渐变的,这怎么就实现不了了,是官网查了一下and看了github的issues,确实也有很多同学遇到和我同样的问题:https://github.com/niklasvh/html2canvas/issues/1208;作者也在下面回复了,目前暂时不支持:Neither background-clip: text nor box-shadow are currently supported.

在官网上也看到了相关的说明.

需求方这边又要求必须要这样的渐变的效果

解决方案--改源码

首先就得找到渲染文本的函数:

{
  key: 'renderNodeContent',
  value: function renderNodeContent(container) {
    var _this = this;
    var callback = function callback() {
      if (container.childNodes.length) {
        container.childNodes.forEach(function (child) {
          if (child instanceof _TextContainer2.default) {
            var style = child.parent.style;
            var xnwWidth = 0;
            var xnwLeft = child.bounds[0].bounds.left;
            for (var xnwi = 0; xnwi < child.bounds.length; xnwi++) {
              xnwWidth += child.bounds[xnwi].bounds.width;
            }
            xnwWidth = xnwLeft + xnwWidth;
            _this.target.renderTextNode(child.bounds, style.color, style.font, style.textDecoration, style.textShadow, xnwWidth,xnwLeft);
          } else {
            _this.target.drawShape(child, container.style.color);
          }
        });
      }
  }
},

这段函数是渲染内容页面内容的,这个函数调用了renderTextNode 这个函数,我们继续走,一看这个函数名就是渲染文本的.在这个函数里我定义了一些变量都是带我名字的首字母,为了防止冲突.

继续走:

{
  key: 'renderTextNode',
  value: function renderTextNode(textBounds, color, font, textDecoration, textShadows, xnwWidth,xnwLeft) {
    var _this4 = this;
    console.log(xnwWidth);
    this.ctx.font = [font.fontStyle, font.fontVariant, font.fontWeight, font.fontSize, font.fontFamily].join(' ');
    console.log(this.options);
    textBounds.forEach(function (text) {
      // _this4.ctx.fillStyle = '#ff0000';
      if (textShadows && text.text.trim().length) {
        textShadows.slice(0).reverse().forEach(function (textShadow) {
          _this4.ctx.shadowColor = textShadow.color.toString();
          _this4.ctx.shadowOffsetX = textShadow.offsetX * _this4.options.scale;
          _this4.ctx.shadowOffsetY = textShadow.offsetY * _this4.options.scale;
          _this4.ctx.shadowBlur = textShadow.blur;

          _this4.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
        });
      } else {
         // 当fontsize的大小为30.1px的时候,才给它加上渐变的效果
        if (font.fontSize === '30.1px') {
          // xnwLeft为渐变的开始位置,xnwWidth为渐变的长度
          var gradientxnw = _this4.ctx.createLinearGradient(xnwLeft, 0, xnwWidth, 0);
          gradientxnw.addColorStop(0, 'black');
          gradientxnw.addColorStop(0.8, 'red');
          gradientxnw.addColorStop(1, 'blue');
          _this4.ctx.fillStyle = gradientxnw;
        } else {
          _this4.ctx.fillStyle = color;
        }
        _this4.ctx.fillText(text.text, text.bounds.left, text.bounds.top + text.bounds.height);
      }
    });
  }
}

在这里主要定义了渐变的样式,由于不清楚外部的参数是如何传入的,只能通过修改fontsize指定一个特别的数字来确定要使这段文本进行渐变.

OK 大功告成!效果如下:

上面为需要转为图片的dom,下面为转了之后的,因为渐变的颜色是直接写在了html2canvas了,还有很多可以优化的点,目前仅仅是实现了效果.待优化!

具体代码:https://jsfiddle.net/kaykie/2qnoxdoz/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏漫漫前端路

Vue 2.3、2.4 知识点小结

2.3 参考 github.com/vuejs/vue/r… 2.4 参考 github.com/vuejs/vue/r… 实例 demo 地址:github....

912
来自专栏前端新视界

Vue.js 系列教程 5:动画

原文:intro-to-vue-5-animations 译者:nzbin 译者的话:经过两周的努力,终于完成了这个系列的翻译,由于时间因素及个人水平有限,并没...

2167
来自专栏达摩兵的技术空间

h5标签入门

701
来自专栏从零开始学自动化测试

Selenium2+python自动化65-js定位几种方法总结

前言 本篇总结了几种js常用的定位元素方法,并用js点击按钮,对input输入框输入文本 一、以下总结了5种js定位的方法 除了id是定位到的是单个elemen...

2697
来自专栏林德熙的博客

win10 uwp MVVM入门

MVVM 是一个强大的架构,基本从 WPF 开始,wr(我说的就是微软)就提倡使用 MVVM。它可以将界面和后台分离,让开发人员可以不关心界面是怎样,全心投入到...

481
来自专栏Scott_Mr 个人专栏

React Native 系列(二) -- React入门知识

34710
来自专栏知晓程序

开发 | 一个 Android 开发者的小程序开发之旅

我是一名 Android 开发程序员,以前没有接触过前端开发,直到接手了公司的小程序项目,才开始逐渐接触前端领域。

832
来自专栏熊二哥

快速入门系列--MVC--03控制器和IOC应用

    Asp.net MVC也接触好久了,但由于自己一直主要负责后台,尤其是数据库方面的工作对于该框架并没有一个很好的了解,尤其是蒋金楠大师的ASP.NET ...

1716
来自专栏微信小程序开发

小程序的登录逻辑能否放在app.js中实现?

前言:做小程序开发的同学,可能都会考虑一个问题,用户登录这个方法是公用的,我们应该把这个方法放在哪里最合适呢? 看到上面的问题后,很大一部分刚入门同学都会直接...

5967
来自专栏达摩兵的技术空间

css3-not选择器妙用

css3中增加了not选择器,可以用于排除不符合某些规则的元素,下面我从语法,兼容性,可能的实践三个角度更好的学习使用它。

502

扫码关注云+社区