这两天有个需求,需要保存页面的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/